summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorYuri Pankov <yuri.pankov@nexenta.com>2018-08-07 16:46:21 -0700
committerJoshua M. Clulow <josh@sysmgr.org>2018-08-07 16:46:22 -0700
commitcb41b9c565d4eec9e1f06e24d429696f59f2f07d (patch)
treeee8675f196c2ea84b5ac5c6f0dff8c9e5305f0ee /usr/src
parent0e986b9d87352cd82909c748e7f684afe0ed579f (diff)
downloadillumos-joyent-cb41b9c565d4eec9e1f06e24d429696f59f2f07d.tar.gz
9674 Let's scrap AVS/sdbc
Reviewed by: Dan McDonald <danmcd@joyent.com> Reviewed by: Peter Tribble <peter.tribble@gmail.com> Approved by: Joshua M. Clulow <josh@sysmgr.org>
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/Makefile.lint7
-rw-r--r--usr/src/cmd/Makefile4
-rw-r--r--usr/src/cmd/avs/Makefile74
-rw-r--r--usr/src/cmd/avs/Makefile.com33
-rw-r--r--usr/src/cmd/avs/dsbitmap/Makefile76
-rw-r--r--usr/src/cmd/avs/dsbitmap/dsbitmap.c436
-rw-r--r--usr/src/cmd/avs/dscfg/Makefile81
-rw-r--r--usr/src/cmd/avs/dscfg/dscfg.c894
-rw-r--r--usr/src/cmd/avs/dscfg/dscfgadm.sh1547
-rw-r--r--usr/src/cmd/avs/dscfg/etc/Makefile44
-rw-r--r--usr/src/cmd/avs/dscfg/etc/dscfg_format72
-rw-r--r--usr/src/cmd/avs/dscfglockd/Makefile84
-rw-r--r--usr/src/cmd/avs/dscfglockd/dscfgcli.c149
-rw-r--r--usr/src/cmd/avs/dscfglockd/dscfglockd.c1371
-rw-r--r--usr/src/cmd/avs/dsstat/Makefile91
-rw-r--r--usr/src/cmd/avs/dsstat/common.c187
-rw-r--r--usr/src/cmd/avs/dsstat/common.h43
-rw-r--r--usr/src/cmd/avs/dsstat/dsstat.c546
-rw-r--r--usr/src/cmd/avs/dsstat/dsstat.h111
-rw-r--r--usr/src/cmd/avs/dsstat/ii_stats.c811
-rw-r--r--usr/src/cmd/avs/dsstat/ii_stats.h82
-rw-r--r--usr/src/cmd/avs/dsstat/multi_stats.c206
-rw-r--r--usr/src/cmd/avs/dsstat/multi_stats.h43
-rw-r--r--usr/src/cmd/avs/dsstat/report.c439
-rw-r--r--usr/src/cmd/avs/dsstat/report.h122
-rw-r--r--usr/src/cmd/avs/dsstat/sdbc_stats.c788
-rw-r--r--usr/src/cmd/avs/dsstat/sdbc_stats.h92
-rw-r--r--usr/src/cmd/avs/dsstat/sndr_stats.c852
-rw-r--r--usr/src/cmd/avs/dsstat/sndr_stats.h70
-rw-r--r--usr/src/cmd/avs/dsw/Makefile102
-rw-r--r--usr/src/cmd/avs/dsw/etc/Makefile63
-rw-r--r--usr/src/cmd/avs/dsw/etc/ii.cluster.sh63
-rw-r--r--usr/src/cmd/avs/dsw/etc/ii.sh144
-rw-r--r--usr/src/cmd/avs/dsw/iiadm.c4377
-rw-r--r--usr/src/cmd/avs/dsw/iiboot.c684
-rw-r--r--usr/src/cmd/avs/dsw/iicpbmp.c260
-rw-r--r--usr/src/cmd/avs/dsw/iicpshd.c358
-rw-r--r--usr/src/cmd/avs/errgen/Makefile55
-rw-r--r--usr/src/cmd/avs/errgen/errgen.c379
-rw-r--r--usr/src/cmd/avs/errgen/errgen.help.txt118
-rw-r--r--usr/src/cmd/avs/ncall/Makefile84
-rw-r--r--usr/src/cmd/avs/ncall/ncalladm.c558
-rw-r--r--usr/src/cmd/avs/nsctl/Makefile87
-rw-r--r--usr/src/cmd/avs/nsctl/nscadm.c275
-rw-r--r--usr/src/cmd/avs/nsctl/nskernd.c1000
-rw-r--r--usr/src/cmd/avs/rdc/Makefile118
-rw-r--r--usr/src/cmd/avs/rdc/etc/Makefile71
-rw-r--r--usr/src/cmd/avs/rdc/etc/rdc.cluster.sh74
-rw-r--r--usr/src/cmd/avs/rdc/etc/rdc.sh186
-rw-r--r--usr/src/cmd/avs/rdc/etc/rdcfinish.sh90
-rw-r--r--usr/src/cmd/avs/rdc/rdc_ioctl.c87
-rw-r--r--usr/src/cmd/avs/rdc/rdcadm.h67
-rw-r--r--usr/src/cmd/avs/rdc/sndradm.c5715
-rw-r--r--usr/src/cmd/avs/rdc/sndrboot.c881
-rw-r--r--usr/src/cmd/avs/rdc/sndrd.c2013
-rw-r--r--usr/src/cmd/avs/rdc/sndrsubr.c463
-rw-r--r--usr/src/cmd/avs/rdc/sndrsyncd.c1695
-rw-r--r--usr/src/cmd/avs/sdbc/Makefile108
-rw-r--r--usr/src/cmd/avs/sdbc/etc/Makefile62
-rw-r--r--usr/src/cmd/avs/sdbc/etc/dscfg_reconfigure.cluster.sh425
-rw-r--r--usr/src/cmd/avs/sdbc/etc/scm.sh348
-rw-r--r--usr/src/cmd/avs/sdbc/scmadm.c2156
-rw-r--r--usr/src/cmd/avs/sdbc/sd_diag.c1169
-rw-r--r--usr/src/cmd/avs/sdbc/sd_stats.c594
-rw-r--r--usr/src/cmd/avs/sdbc/sd_trace.c961
-rw-r--r--usr/src/cmd/avs/sdbc/sdbc_dynmem.c388
-rw-r--r--usr/src/cmd/avs/sdbc/sdbc_ioctl.c156
-rw-r--r--usr/src/cmd/avs/sv/Makefile94
-rw-r--r--usr/src/cmd/avs/sv/etc/Makefile69
-rw-r--r--usr/src/cmd/avs/sv/etc/sv.cluster.sh77
-rw-r--r--usr/src/cmd/avs/sv/etc/sv.sh122
-rw-r--r--usr/src/cmd/avs/sv/svadm.c1515
-rw-r--r--usr/src/cmd/avs/sv/svadm.h50
-rw-r--r--usr/src/cmd/avs/sv/svboot.c533
-rw-r--r--usr/src/cmd/avs/svc/Makefile54
-rw-r--r--usr/src/cmd/avs/svc/manifest/nws_ii.xml100
-rw-r--r--usr/src/cmd/avs/svc/manifest/nws_rdc.xml108
-rw-r--r--usr/src/cmd/avs/svc/manifest/nws_rdcsyncd.xml101
-rw-r--r--usr/src/cmd/avs/svc/manifest/nws_scm.xml123
-rw-r--r--usr/src/cmd/avs/svc/manifest/nws_sv.xml100
-rw-r--r--usr/src/cmd/mdb/Makefile.common5
-rw-r--r--usr/src/cmd/mdb/common/modules/ii/Makefile.com24
-rw-r--r--usr/src/cmd/mdb/common/modules/ii/ii.c427
-rw-r--r--usr/src/cmd/mdb/common/modules/nsctl/Makefile.com24
-rw-r--r--usr/src/cmd/mdb/common/modules/nsctl/nsctl.c2159
-rw-r--r--usr/src/cmd/mdb/common/modules/rdc/Makefile.com24
-rw-r--r--usr/src/cmd/mdb/common/modules/rdc/rdc.c1563
-rw-r--r--usr/src/cmd/mdb/common/modules/sdbc/Makefile.com24
-rw-r--r--usr/src/cmd/mdb/common/modules/sdbc/sdbc.c3158
-rw-r--r--usr/src/cmd/mdb/common/modules/sv/Makefile.com24
-rw-r--r--usr/src/cmd/mdb/common/modules/sv/sv.c624
-rw-r--r--usr/src/cmd/mdb/intel/amd64/ii/Makefile35
-rw-r--r--usr/src/cmd/mdb/intel/amd64/nsctl/Makefile35
-rw-r--r--usr/src/cmd/mdb/intel/amd64/rdc/Makefile38
-rw-r--r--usr/src/cmd/mdb/intel/amd64/sdbc/Makefile38
-rw-r--r--usr/src/cmd/mdb/intel/amd64/sv/Makefile35
-rw-r--r--usr/src/cmd/mdb/intel/ia32/ii/Makefile34
-rw-r--r--usr/src/cmd/mdb/intel/ia32/nsctl/Makefile34
-rw-r--r--usr/src/cmd/mdb/intel/ia32/rdc/Makefile37
-rw-r--r--usr/src/cmd/mdb/intel/ia32/sdbc/Makefile37
-rw-r--r--usr/src/cmd/mdb/intel/ia32/sv/Makefile34
-rw-r--r--usr/src/cmd/mdb/sparc/v9/ii/Makefile35
-rw-r--r--usr/src/cmd/mdb/sparc/v9/nsctl/Makefile35
-rw-r--r--usr/src/cmd/mdb/sparc/v9/rdc/Makefile38
-rw-r--r--usr/src/cmd/mdb/sparc/v9/sdbc/Makefile38
-rw-r--r--usr/src/cmd/mdb/sparc/v9/sv/Makefile35
-rw-r--r--usr/src/head/Makefile1
-rw-r--r--usr/src/head/nsctl.h88
-rw-r--r--usr/src/lib/Makefile10
-rw-r--r--usr/src/lib/libdscfg/Makefile64
-rw-r--r--usr/src/lib/libdscfg/Makefile.com74
-rw-r--r--usr/src/lib/libdscfg/common/cfg.c3585
-rw-r--r--usr/src/lib/libdscfg/common/cfg.h180
-rw-r--r--usr/src/lib/libdscfg/common/cfg_cluster.c582
-rw-r--r--usr/src/lib/libdscfg/common/cfg_cluster.h344
-rw-r--r--usr/src/lib/libdscfg/common/cfg_impl.h247
-rw-r--r--usr/src/lib/libdscfg/common/cfg_local.c653
-rw-r--r--usr/src/lib/libdscfg/common/cfg_local.h42
-rw-r--r--usr/src/lib/libdscfg/common/cfg_lockd.h72
-rw-r--r--usr/src/lib/libdscfg/common/cfg_lockdlck.c135
-rw-r--r--usr/src/lib/libdscfg/common/cfg_lockdmsg.c324
-rw-r--r--usr/src/lib/libdscfg/common/cfg_vols.c1286
-rw-r--r--usr/src/lib/libdscfg/common/mapfile-vers100
-rw-r--r--usr/src/lib/libdscfg/i386/Makefile34
-rw-r--r--usr/src/lib/libdscfg/sparc/Makefile34
-rw-r--r--usr/src/lib/libnsctl/Makefile60
-rw-r--r--usr/src/lib/libnsctl/Makefile.com56
-rw-r--r--usr/src/lib/libnsctl/common/cache.c425
-rw-r--r--usr/src/lib/libnsctl/common/hash.c166
-rw-r--r--usr/src/lib/libnsctl/common/libnsctl.h62
-rw-r--r--usr/src/lib/libnsctl/common/llib-lnsctl52
-rw-r--r--usr/src/lib/libnsctl/common/machdep.c314
-rw-r--r--usr/src/lib/libnsctl/common/mapfile-vers70
-rw-r--r--usr/src/lib/libnsctl/common/nsc_hash.h49
-rw-r--r--usr/src/lib/libnsctl/i386/Makefile36
-rw-r--r--usr/src/lib/libnsctl/sparc/Makefile30
-rw-r--r--usr/src/lib/librdc/Makefile60
-rw-r--r--usr/src/lib/librdc/Makefile.com92
-rw-r--r--usr/src/lib/librdc/common/librdc.h113
-rw-r--r--usr/src/lib/librdc/common/llib-lrdc46
-rw-r--r--usr/src/lib/librdc/common/mapfile-vers84
-rw-r--r--usr/src/lib/librdc/common/netaddrs.c670
-rw-r--r--usr/src/lib/librdc/common/rdcconfig.c1318
-rw-r--r--usr/src/lib/librdc/common/rdcerr.c98
-rw-r--r--usr/src/lib/librdc/common/rdcerr.h74
-rw-r--r--usr/src/lib/librdc/common/rdcpersist.c716
-rw-r--r--usr/src/lib/librdc/common/rdcrules.c545
-rw-r--r--usr/src/lib/librdc/common/rdcrules.h46
-rw-r--r--usr/src/lib/librdc/i386/Makefile33
-rw-r--r--usr/src/lib/librdc/sparc/Makefile31
-rw-r--r--usr/src/lib/libunistat/Makefile96
-rw-r--r--usr/src/lib/libunistat/Makefile.com189
-rw-r--r--usr/src/lib/libunistat/common/README33
-rw-r--r--usr/src/lib/libunistat/common/dsw/dsw.err54
-rw-r--r--usr/src/lib/libunistat/common/llib-lunistat42
-rw-r--r--usr/src/lib/libunistat/common/mapfile-vers55
-rw-r--r--usr/src/lib/libunistat/common/rdc/rdc.err93
-rw-r--r--usr/src/lib/libunistat/common/sdbc/sdbc.err60
-rw-r--r--usr/src/lib/libunistat/common/solaris/solaris.err173
-rw-r--r--usr/src/lib/libunistat/common/spcs/spcs.err39
-rw-r--r--usr/src/lib/libunistat/common/spcs_errors.stub36
-rw-r--r--usr/src/lib/libunistat/common/spcs_etext.stub40
-rw-r--r--usr/src/lib/libunistat/common/spcs_etrinkets.stub49
-rw-r--r--usr/src/lib/libunistat/common/spcs_log.c115
-rw-r--r--usr/src/lib/libunistat/common/spcs_s_u.c246
-rw-r--r--usr/src/lib/libunistat/common/sv/sv.err45
-rw-r--r--usr/src/lib/libunistat/i386/Makefile35
-rw-r--r--usr/src/lib/libunistat/sparc/Makefile35
-rw-r--r--usr/src/man/man1m/Makefile14
-rw-r--r--usr/src/man/man1m/dsbitmap.1m178
-rw-r--r--usr/src/man/man1m/dscfg.1m310
-rw-r--r--usr/src/man/man1m/dscfgadm.1m159
-rw-r--r--usr/src/man/man1m/dscfglockd.1m100
-rw-r--r--usr/src/man/man1m/dsstat.1m1127
-rw-r--r--usr/src/man/man1m/iiadm.1m1016
-rw-r--r--usr/src/man/man1m/iicpbmp.1m77
-rw-r--r--usr/src/man/man1m/iicpshd.1m85
-rw-r--r--usr/src/man/man1m/nscadm.1m143
-rw-r--r--usr/src/man/man1m/scmadm.1m203
-rw-r--r--usr/src/man/man1m/sndradm.1m1043
-rw-r--r--usr/src/man/man1m/sndrd.1m150
-rw-r--r--usr/src/man/man1m/sndrsyncd.1m132
-rw-r--r--usr/src/man/man1m/svadm.1m181
-rw-r--r--usr/src/man/man4/Makefile5
-rw-r--r--usr/src/man/man4/ds.log.4112
-rw-r--r--usr/src/man/man4/rdc.cf.4166
-rw-r--r--usr/src/man/man4/sndr.489
-rw-r--r--usr/src/man/man7d/Makefile4
-rw-r--r--usr/src/man/man7d/ii.7d104
-rw-r--r--usr/src/man/man7d/sv.7d47
-rw-r--r--usr/src/pkg/manifests/driver-storage-sv.mf66
-rw-r--r--usr/src/pkg/manifests/service-storage-avs-cache-management.mf108
-rw-r--r--usr/src/pkg/manifests/storage-avs-point-in-time-copy.mf73
-rw-r--r--usr/src/pkg/manifests/storage-avs-remote-mirror.mf88
-rw-r--r--usr/src/pkg/manifests/storage-avs.mf11
-rw-r--r--usr/src/uts/Makefile13
-rw-r--r--usr/src/uts/common/Makefile.files68
-rw-r--r--usr/src/uts/common/Makefile.rules58
-rw-r--r--usr/src/uts/common/avs/Makefile51
-rw-r--r--usr/src/uts/common/avs/Makefile.com28
-rw-r--r--usr/src/uts/common/avs/ncall/Makefile51
-rw-r--r--usr/src/uts/common/avs/ncall/ncall.c769
-rw-r--r--usr/src/uts/common/avs/ncall/ncall.conf26
-rw-r--r--usr/src/uts/common/avs/ncall/ncall.h121
-rw-r--r--usr/src/uts/common/avs/ncall/ncall_module.h85
-rw-r--r--usr/src/uts/common/avs/ncall/ncall_stub.c265
-rw-r--r--usr/src/uts/common/avs/ns/Makefile57
-rw-r--r--usr/src/uts/common/avs/ns/contract.h535
-rw-r--r--usr/src/uts/common/avs/ns/dsw/Makefile48
-rw-r--r--usr/src/uts/common/avs/ns/dsw/dsw.c655
-rw-r--r--usr/src/uts/common/avs/ns/dsw/dsw.h485
-rw-r--r--usr/src/uts/common/avs/ns/dsw/dsw_dev.c10386
-rw-r--r--usr/src/uts/common/avs/ns/dsw/dsw_dev.h633
-rw-r--r--usr/src/uts/common/avs/ns/dsw/ii.conf38
-rw-r--r--usr/src/uts/common/avs/ns/dsw/ii_tree.c599
-rw-r--r--usr/src/uts/common/avs/ns/model.h235
-rw-r--r--usr/src/uts/common/avs/ns/ncall_inter.h91
-rw-r--r--usr/src/uts/common/avs/ns/nsctl.h526
-rw-r--r--usr/src/uts/common/avs/ns/nsctl/Makefile55
-rw-r--r--usr/src/uts/common/avs/ns/nsctl/nsc_cache.c499
-rw-r--r--usr/src/uts/common/avs/ns/nsctl/nsc_dev.c2215
-rw-r--r--usr/src/uts/common/avs/ns/nsctl/nsc_dev.h218
-rw-r--r--usr/src/uts/common/avs/ns/nsctl/nsc_disk.c554
-rw-r--r--usr/src/uts/common/avs/ns/nsctl/nsc_disk.h83
-rw-r--r--usr/src/uts/common/avs/ns/nsctl/nsc_freeze.c310
-rw-r--r--usr/src/uts/common/avs/ns/nsctl/nsc_gen.c1106
-rw-r--r--usr/src/uts/common/avs/ns/nsctl/nsc_gen.h116
-rw-r--r--usr/src/uts/common/avs/ns/nsctl/nsc_ioctl.h106
-rw-r--r--usr/src/uts/common/avs/ns/nsctl/nsc_mem.c939
-rw-r--r--usr/src/uts/common/avs/ns/nsctl/nsc_mem.h97
-rw-r--r--usr/src/uts/common/avs/ns/nsctl/nsc_ncallio.c757
-rw-r--r--usr/src/uts/common/avs/ns/nsctl/nsc_ncallio.h105
-rw-r--r--usr/src/uts/common/avs/ns/nsctl/nsc_power.c249
-rw-r--r--usr/src/uts/common/avs/ns/nsctl/nsc_power.h53
-rw-r--r--usr/src/uts/common/avs/ns/nsctl/nsc_resv.c1014
-rw-r--r--usr/src/uts/common/avs/ns/nsctl/nsc_rmspin.c270
-rw-r--r--usr/src/uts/common/avs/ns/nsctl/nsc_rmspin.h53
-rw-r--r--usr/src/uts/common/avs/ns/nsctl/nsc_trap.c81
-rw-r--r--usr/src/uts/common/avs/ns/nsctl/nsctl.c923
-rw-r--r--usr/src/uts/common/avs/ns/nsctl/nsctl.conf41
-rw-r--r--usr/src/uts/common/avs/ns/nsctl/nsvers.h77
-rw-r--r--usr/src/uts/common/avs/ns/nsctl_inter.h223
-rw-r--r--usr/src/uts/common/avs/ns/rdc/Makefile62
-rw-r--r--usr/src/uts/common/avs/ns/rdc/rdc.c1108
-rw-r--r--usr/src/uts/common/avs/ns/rdc/rdc.conf55
-rw-r--r--usr/src/uts/common/avs/ns/rdc/rdc.h44
-rw-r--r--usr/src/uts/common/avs/ns/rdc/rdc_bitmap.c2659
-rw-r--r--usr/src/uts/common/avs/ns/rdc/rdc_bitmap.h191
-rw-r--r--usr/src/uts/common/avs/ns/rdc/rdc_clnt.c3381
-rw-r--r--usr/src/uts/common/avs/ns/rdc/rdc_clnt.h66
-rw-r--r--usr/src/uts/common/avs/ns/rdc/rdc_dev.c3019
-rw-r--r--usr/src/uts/common/avs/ns/rdc/rdc_diskq.c3252
-rw-r--r--usr/src/uts/common/avs/ns/rdc/rdc_diskq.h332
-rw-r--r--usr/src/uts/common/avs/ns/rdc/rdc_health.c800
-rw-r--r--usr/src/uts/common/avs/ns/rdc/rdc_io.c6718
-rw-r--r--usr/src/uts/common/avs/ns/rdc/rdc_io.h1009
-rw-r--r--usr/src/uts/common/avs/ns/rdc/rdc_ioctl.h498
-rw-r--r--usr/src/uts/common/avs/ns/rdc/rdc_prot.x390
-rw-r--r--usr/src/uts/common/avs/ns/rdc/rdc_stub.c110
-rw-r--r--usr/src/uts/common/avs/ns/rdc/rdc_stub.h45
-rw-r--r--usr/src/uts/common/avs/ns/rdc/rdc_subr.c241
-rw-r--r--usr/src/uts/common/avs/ns/rdc/rdc_svc.c3079
-rw-r--r--usr/src/uts/common/avs/ns/rdc/rdc_update.h50
-rw-r--r--usr/src/uts/common/avs/ns/rdc/rdcsrv.c447
-rw-r--r--usr/src/uts/common/avs/ns/rdc/rdcsrv.h56
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/CACHE_SPEC.txt389
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/Makefile55
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/cache_kstats_readme.txt319
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/dynmem_readme.txt352
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/safestore.c394
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/safestore.h655
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/safestore_impl.h142
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/safestore_ram.c614
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/safestore_ram.h90
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/sd_bcache.c7484
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/sd_bcache.h1161
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/sd_bio.c1305
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/sd_bio.h47
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/sd_cache.h182
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/sd_conf.c839
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/sd_conf.h87
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/sd_ft.c1266
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/sd_ft.h111
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/sd_hash.c499
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/sd_hash.h93
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/sd_io.c2009
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/sd_io.h68
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/sd_iob.h105
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/sd_misc.c1437
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/sd_misc.h65
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/sd_mkiob.sh77
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/sd_pcu.c874
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/sd_pcu.h103
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/sd_tdaemon.c1157
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/sd_tdaemon.h49
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/sd_trace.c620
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/sd_trace.h320
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/sdbc.conf35
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/sdbc_ioctl.h296
-rw-r--r--usr/src/uts/common/avs/ns/solaris/Makefile50
-rw-r--r--usr/src/uts/common/avs/ns/solaris/nsc_ddi.c389
-rw-r--r--usr/src/uts/common/avs/ns/solaris/nsc_ddi.h70
-rw-r--r--usr/src/uts/common/avs/ns/solaris/nsc_list.c85
-rw-r--r--usr/src/uts/common/avs/ns/solaris/nsc_list.h119
-rw-r--r--usr/src/uts/common/avs/ns/solaris/nsc_proc.c382
-rw-r--r--usr/src/uts/common/avs/ns/solaris/nsc_raw.c853
-rw-r--r--usr/src/uts/common/avs/ns/solaris/nsc_solaris.c141
-rw-r--r--usr/src/uts/common/avs/ns/solaris/nsc_thread.c1026
-rw-r--r--usr/src/uts/common/avs/ns/solaris/nsc_thread.h157
-rw-r--r--usr/src/uts/common/avs/ns/solaris/nskern.conf24
-rw-r--r--usr/src/uts/common/avs/ns/solaris/nskernd.c298
-rw-r--r--usr/src/uts/common/avs/ns/solaris/nskernd.h71
-rw-r--r--usr/src/uts/common/avs/ns/sv/Makefile50
-rw-r--r--usr/src/uts/common/avs/ns/sv/sv.c2816
-rw-r--r--usr/src/uts/common/avs/ns/sv/sv.conf36
-rw-r--r--usr/src/uts/common/avs/ns/sv/sv.h175
-rw-r--r--usr/src/uts/common/avs/ns/sv/sv_efi.h65
-rw-r--r--usr/src/uts/common/avs/ns/sv/sv_impl.h152
-rw-r--r--usr/src/uts/common/avs/ns/unistat/Makefile52
-rw-r--r--usr/src/uts/common/avs/ns/unistat/spcs_s.h89
-rw-r--r--usr/src/uts/common/avs/ns/unistat/spcs_s_impl.h310
-rw-r--r--usr/src/uts/common/avs/ns/unistat/spcs_s_k.c888
-rw-r--r--usr/src/uts/common/avs/ns/unistat/spcs_s_k.h252
-rw-r--r--usr/src/uts/common/avs/ns/unistat/spcs_s_u.h117
-rw-r--r--usr/src/uts/common/avs/ns/unistat/spuni.c81
-rw-r--r--usr/src/uts/intel/Makefile.intel5
-rw-r--r--usr/src/uts/intel/ii/Makefile95
-rw-r--r--usr/src/uts/intel/ncall/Makefile89
-rw-r--r--usr/src/uts/intel/nsctl/Makefile95
-rw-r--r--usr/src/uts/intel/nskern/Makefile97
-rw-r--r--usr/src/uts/intel/nskern/nsc_asm.s189
-rw-r--r--usr/src/uts/intel/rdc/Makefile108
-rw-r--r--usr/src/uts/intel/rdcsrv/Makefile96
-rw-r--r--usr/src/uts/intel/rdcstub/Makefile93
-rw-r--r--usr/src/uts/intel/sdbc/Makefile172
-rw-r--r--usr/src/uts/intel/spuni/Makefile88
-rw-r--r--usr/src/uts/intel/sv/Makefile91
-rw-r--r--usr/src/uts/sparc/Makefile.sparc3
-rw-r--r--usr/src/uts/sparc/ii/Makefile95
-rw-r--r--usr/src/uts/sparc/ncall/Makefile89
-rw-r--r--usr/src/uts/sparc/nsctl/Makefile95
-rw-r--r--usr/src/uts/sparc/nskern/Makefile89
-rw-r--r--usr/src/uts/sparc/nskern/nsc_asm.s150
-rw-r--r--usr/src/uts/sparc/rdc/Makefile106
-rw-r--r--usr/src/uts/sparc/rdcsrv/Makefile96
-rw-r--r--usr/src/uts/sparc/rdcstub/Makefile93
-rw-r--r--usr/src/uts/sparc/sdbc/Makefile172
-rw-r--r--usr/src/uts/sparc/spuni/Makefile88
-rw-r--r--usr/src/uts/sparc/sv/Makefile91
349 files changed, 19 insertions, 155748 deletions
diff --git a/usr/src/Makefile.lint b/usr/src/Makefile.lint
index b9c46fb093..295d86054f 100644
--- a/usr/src/Makefile.lint
+++ b/usr/src/Makefile.lint
@@ -23,7 +23,7 @@
# Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2012 by Delphix. All rights reserved.
# Copyright 2015 Garrett D'Amore <garrett@damore.org>
-# Copyright 2016 Nexenta Systems, Inc.
+# Copyright 2018 Nexenta Systems, Inc.
#
# include global definitions
@@ -47,7 +47,6 @@ COMMON_SUBDIRS = \
cmd/auths \
cmd/autopush \
cmd/availdevs \
- cmd/avs \
cmd/awk \
cmd/banner \
cmd/bart \
@@ -362,7 +361,6 @@ COMMON_SUBDIRS = \
lib/libdladm \
lib/libdlpi \
lib/libdoor \
- lib/libdscfg \
lib/libdtrace \
lib/libefi \
lib/libelfsign \
@@ -397,7 +395,6 @@ COMMON_SUBDIRS = \
lib/libmp \
lib/libmtmalloc \
lib/libndmp \
- lib/libnsctl \
lib/libnsl \
lib/libnvpair \
lib/libnwam \
@@ -411,7 +408,6 @@ COMMON_SUBDIRS = \
lib/libpthread \
lib/libraidcfg \
lib/librcm \
- lib/librdc \
lib/libreparse \
lib/librestart \
lib/librstp \
@@ -435,7 +431,6 @@ COMMON_SUBDIRS = \
lib/libtsnet \
lib/libtsol \
lib/libumem \
- lib/libunistat \
lib/libuuid \
lib/libuutil \
lib/libvrrpadm \
diff --git a/usr/src/cmd/Makefile b/usr/src/cmd/Makefile
index 996cd553a7..57644f077b 100644
--- a/usr/src/cmd/Makefile
+++ b/usr/src/cmd/Makefile
@@ -26,7 +26,7 @@
# Copyright (c) 2013 DEY Storage Systems, Inc. All rights reserved.
# Copyright 2014 Garrett D'Amore <garrett@damore.org>
# Copyright 2016 Toomas Soome <tsoome@me.com>
-# Copyright 2016 Nexenta Systems, Inc.
+# Copyright 2018 Nexenta Systems, Inc.
# Copyright 2018 Gary Mills
#
@@ -68,7 +68,6 @@ COMMON_SUBDIRS= \
audio \
auths \
autopush \
- avs \
awk \
awk_xpg4 \
backup \
@@ -519,7 +518,6 @@ MSGSUBDIRS= \
auditset \
auths \
autopush \
- avs \
awk \
awk_xpg4 \
backup \
diff --git a/usr/src/cmd/avs/Makefile b/usr/src/cmd/avs/Makefile
deleted file mode 100644
index 18c07e24d6..0000000000
--- a/usr/src/cmd/avs/Makefile
+++ /dev/null
@@ -1,74 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#
-include ../Makefile.cmd
-include Makefile.com
-
-# general subdirectories
-
-MSGSUBDIRS= dsbitmap \
- dscfg \
- dscfglockd \
- dsstat \
- dsw \
- errgen \
- ncall \
- nsctl \
- rdc \
- sdbc \
- sv
-
-SUBDIRS = $(MSGSUBDIRS) svc
-
-all:= TARGET= all
-install:= TARGET= install
-clean:= TARGET= clean
-clobber:= TARGET= clobber
-lint:= TARGET= lint
-_msg:= TARGET= _msg
-
-.KEEP_STATE:
-
-all clean clobber: $(SUBDIRS)
-
-_msg: $(MSGSUBDIRS)
-
-install: $(CLUSTERDIR) \
- $(CLUSTERLIBDIR) \
- $(CLUSTERSBINDIR) \
- $(CLUSTERLIBDSCFGDIR) \
- $(CLUSTERLIBDSCFGSTOPDIR) \
- $(CLUSTERLIBDSCFGSTARTDIR) \
- .WAIT \
- $(SUBDIRS)
-
-lint: $(SUBDIRS)
-
-$(CLUSTERDIR) $(CLUSTERLIBDIR) $(CLUSTERSBINDIR) $(CLUSTERLIBDSCFGDIR) $(CLUSTERLIBDSCFGSTOPDIR) $(CLUSTERLIBDSCFGSTARTDIR):
- $(INS.dir)
-
-$(SUBDIRS): FRC
- @cd $@; pwd; $(MAKE) $(TARGET)
-
-FRC:
diff --git a/usr/src/cmd/avs/Makefile.com b/usr/src/cmd/avs/Makefile.com
deleted file mode 100644
index b6ea49214b..0000000000
--- a/usr/src/cmd/avs/Makefile.com
+++ /dev/null
@@ -1,33 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# cmd/avs/Makefile.com
-#
-CLUSTERDIR = $(ROOT)/usr/cluster
-CLUSTERSBINDIR = $(CLUSTERDIR)/sbin
-CLUSTERLIBDIR = $(CLUSTERDIR)/lib
-CLUSTERLIBDSCFGDIR = $(CLUSTERLIBDIR)/dscfg
-CLUSTERLIBSTOPDIR = $(CLUSTERLIBDIR)/stop
-CLUSTERLIBSTARTDIR = $(CLUSTERLIBDIR)/start
-CLUSTERLIBDSCFGSTOPDIR = $(CLUSTERLIBDSCFGDIR)/stop
-CLUSTERLIBDSCFGSTARTDIR = $(CLUSTERLIBDSCFGDIR)/start
diff --git a/usr/src/cmd/avs/dsbitmap/Makefile b/usr/src/cmd/avs/dsbitmap/Makefile
deleted file mode 100644
index 2b9380995e..0000000000
--- a/usr/src/cmd/avs/dsbitmap/Makefile
+++ /dev/null
@@ -1,76 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-DYNPROG= dsbitmap
-
-include ../../Makefile.cmd
-include ../Makefile.com
-
-PROG = $(DYNPROG)
-
-dsbitmap := POBJS = dsbitmap.o
-
-OBJS= dsbitmap.o
-SRCS= $(OBJS:%.o=%.c)
-POFILE= $(OBJS:%.o=%.po)
-
-CFLAGS += $(CCVERBOSE)
-CERRWARN += -_gcc=-Wno-uninitialized
-LDLIBS += -lunistat -ladm
-LINTFLAGS += -Xa -n -s -x -m -u -Dlint -errhdr=%user
-LINTFLAGS += -erroff=E_SEC_PRINTF_VAR_FMT
-ROOTLINK = $(ROOTUSRSBIN)/$(PROG)
-
-all := TARGET= all
-install := TARGET= install
-clean := TARGET= clean
-clobber := TARGET= clobber
-lint := TARGET= lint
-
-.KEEP_STATE:
-
-.PARALLEL: $(OBJS)
-
-all: $(PROG)
-
-install: all $(ROOTPROG) $(ROOTLINK)
-
-lint: lint_SRCS
-
-clean:
- $(RM) *.o $(POFILE)
-
-$(PROG): $$(POBJS)
- $(LINK.c) $(POBJS) -o $@ $(LDLIBS)
- $(POST_PROCESS)
-
-check: $(PROG).c
- $(CSTYLE) -pP $(SRCS:%=%)
-
-$(ROOTLINK): $(ROOTBIN)/$(PROG) $(ROOTUSRSBIN)
- -$(RM) $@; $(LN) $(ROOTBIN)/$(PROG) $@
-
-FRC:
-
-include ../../Makefile.targ
diff --git a/usr/src/cmd/avs/dsbitmap/dsbitmap.c b/usr/src/cmd/avs/dsbitmap/dsbitmap.c
deleted file mode 100644
index 77c5be7c1f..0000000000
--- a/usr/src/cmd/avs/dsbitmap/dsbitmap.c
+++ /dev/null
@@ -1,436 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/dkio.h>
-#include <sys/vtoc.h>
-#include <sys/mkdev.h>
-#ifdef DKIOCPARTITION
-#include <sys/efi_partition.h>
-#endif
-#include <strings.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <stdio.h>
-#include <locale.h>
-#include <unistd.h>
-#include <libgen.h>
-#include <kstat.h>
-
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_u.h>
-#include <sys/unistat/spcs_errors.h>
-
-#include <sys/nsctl/dsw.h>
-#include <sys/nsctl/dsw_dev.h>
-#include <sys/nsctl/rdc_io.h>
-#include <sys/nsctl/rdc_bitmap.h>
-
-enum { UNKNOWN = 0, SNDR, II };
-
-static char *program;
-
-void
-usage(void)
-{
- (void) printf(gettext("usage: %s -h\n"), program);
- (void) printf(gettext(" %s { -p | -r } data_volume "
- "[bitmap_volume]\n"), program);
- (void) printf(gettext(" -h : This usage message\n"));
- (void) printf(gettext(" -p : Calculate size of Point in Time "
- "bitmap\n"));
- (void) printf(gettext(" -r : Calculate size of Remote Mirror "
- "bitmap\n"));
-}
-
-
-static void
-message(char *prefix, spcs_s_info_t *status, caddr_t string, va_list ap)
-{
- (void) fprintf(stderr, "%s: %s: ", program, prefix);
- (void) vfprintf(stderr, string, ap);
- (void) fprintf(stderr, "\n");
-
- if (status) {
- spcs_s_report(*status, stderr);
- spcs_s_ufree(status);
- }
-}
-
-
-static void
-error(spcs_s_info_t *status, char *string, ...)
-{
- va_list ap;
- va_start(ap, string);
-
- message(gettext("error"), status, string, ap);
- va_end(ap);
- exit(1);
-}
-
-
-static void
-warn(spcs_s_info_t *status, char *string, ...)
-{
- va_list ap;
- va_start(ap, string);
-
- message(gettext("warning"), status, string, ap);
- va_end(ap);
-}
-
-#if defined(_LP64)
- /* max value of a "long int" */
-#define ULONG_MAX 18446744073709551615UL
-#else /* _ILP32 */
-#define ULONG_MAX 4294967295UL /* max of "unsigned long int" */
-#endif
-
-static uint64_t
-get_partsize(char *partition)
-{
-#ifdef DKIOCPARTITION
- struct dk_cinfo dki_info;
- struct partition64 p64;
-#endif
- struct vtoc vtoc;
- uint64_t size;
- int fd;
- int rc;
-
- if ((fd = open(partition, O_RDONLY)) < 0) {
- error(NULL, gettext("unable to open partition, %s: %s"),
- partition, strerror(errno));
- /* NOTREACHED */
- }
-
- rc = read_vtoc(fd, &vtoc);
- if (rc >= 0) {
- size = (uint64_t)(ULONG_MAX & vtoc.v_part[rc].p_size);
- return (size);
- }
-#ifdef DKIOCPARTITION
- else if (rc != VT_ENOTSUP) {
-#endif
- error(NULL,
- gettext("unable to read the vtoc from partition, %s: %s"),
- partition, strerror(errno));
- /* NOTREACHED */
-#ifdef DKIOCPARTITION
- }
-
- /* See if there is an EFI label */
- rc = ioctl(fd, DKIOCINFO, &dki_info);
- if (rc < 0) {
- error(NULL, gettext("unable to get controller info "
- "from partition, %s: %s"),
- partition, strerror(errno));
- /* NOTREACHED */
- }
-
- bzero(&p64, sizeof (p64));
- p64.p_partno = (uint_t)dki_info.dki_partition;
- rc = ioctl(fd, DKIOCPARTITION, &p64);
- if (rc >= 0) {
- size = (uint64_t)p64.p_size;
- return (size);
- } else {
- struct stat64 stb1, stb2;
- struct dk_minfo dkm;
-
- /*
- * See if the stat64 for ZFS's zvol matches
- * this file descriptor's fstat64 data.
- */
- if (stat64("/devices/pseudo/zfs@0:zfs", &stb1) != 0 ||
- fstat64(fd, &stb2) != 0 ||
- !S_ISCHR(stb1.st_mode) ||
- !S_ISCHR(stb2.st_mode) ||
- major(stb1.st_rdev) != major(stb2.st_rdev)) {
- error(NULL,
- gettext("unable to read disk partition, %s: %s"),
- partition, strerror(errno));
- /* NOTREACHED */
- }
-
- rc = ioctl(fd, DKIOCGMEDIAINFO, (void *)&dkm);
- if (rc >= 0) {
- size = LE_64(dkm.dki_capacity) *
- dkm.dki_lbsize / 512;
- return (size);
- } else {
- error(NULL, gettext("unable to read EFI label "
- "from partition, %s: %s"),
- partition, strerror(errno));
- /* NOTREACHED */
- }
- }
- return (size);
-
-#endif /* DKIOCPARTITION */
-}
-
-
-int
-do_sndr(char *volume, char *bitmap)
-{
- uint64_t vblocks;
- uint64_t bblocks;
- uint64_t bsize_bits; /* size of the bits alone */
- uint64_t bsize_simple; /* size of the simple bitmap */
- uint64_t bsize_diskq; /* size of the diskq bitmap, 8 bit refcnt */
- uint64_t bsize_diskq32; /* size of the diskq bitmap, 32 bit refcnt */
- int rc = 0;
-
- vblocks = get_partsize(volume);
- if (bitmap) {
- bblocks = get_partsize(bitmap);
- }
-
- bsize_bits = BMAP_LOG_BYTES(vblocks);
- bsize_bits = (bsize_bits + 511) / 512;
-
- bsize_simple = RDC_BITMAP_FBA + bsize_bits;
- bsize_diskq = RDC_BITMAP_FBA + bsize_bits + (BITS_IN_BYTE * bsize_bits);
- bsize_diskq32 = RDC_BITMAP_FBA + bsize_bits + (BITS_IN_BYTE *
- bsize_bits * sizeof (unsigned int));
-
- (void) printf(gettext("Remote Mirror bitmap sizing\n\n"));
- (void) printf(gettext("Data volume (%s) size: %llu blocks\n"),
- volume, vblocks);
-
- (void) printf(gettext("Required bitmap volume size:\n"));
- (void) printf(gettext(" Sync replication: %llu blocks\n"),
- bsize_simple);
- (void) printf(gettext(" Async replication with memory queue: "
- "%llu blocks\n"), bsize_simple);
- (void) printf(gettext(" Async replication with disk queue: "
- "%llu blocks\n"), bsize_diskq);
- (void) printf(gettext(" Async replication with disk queue and 32 bit "
- "refcount: %llu blocks\n"), bsize_diskq32);
-
- if (bitmap) {
- (void) printf("\n");
- (void) printf(gettext("Supplied bitmap volume %s "
- "(%llu blocks)\n"),
- bitmap, bblocks);
- if (bblocks >= bsize_diskq32) {
- (void) printf(gettext("is large enough for all "
- "replication modes\n"));
- } else if (bblocks >= bsize_diskq) {
- (void) printf(gettext("is large enough for all "
- "replication modes, but with restricted diskq "
- "reference counts\n"));
- } else if (bblocks >= bsize_simple) {
- (void) printf(gettext(
- "is large enough for: Sync and Async(memory) "
- "replication modes only\n"));
- rc = 3;
- } else {
- (void) printf(gettext(
- "is not large enough for any replication modes\n"));
- rc = 4;
- }
- }
-
- return (rc);
-}
-
-
-/* sizes in bytes */
-#define KILO (1024)
-#define MEGA (KILO * KILO)
-#define GIGA (MEGA * KILO)
-#define TERA ((uint64_t)((uint64_t)GIGA * (uint64_t)KILO))
-
-/* rounding function */
-#define roundup_2n(x, y) (((x) + ((y) - 1)) & (~y))
-
-int
-do_ii(char *volume, char *bitmap)
-{
- const uint64_t int64_bits = sizeof (uint64_t) * BITS_IN_BYTE;
- const uint64_t int32_bits = sizeof (uint32_t) * BITS_IN_BYTE;
- const uint64_t terablocks = TERA / ((uint64_t)FBA_SIZE(1));
- uint64_t vblocks_phys, vblocks;
- uint64_t bblocks;
- uint64_t bsize_ind; /* indep and dep not compact */
- uint64_t bsize_cdep; /* compact dep */
- int rc = 0;
-
- vblocks_phys = get_partsize(volume);
- if (bitmap) {
- bblocks = get_partsize(bitmap);
- }
-
- /* round up to multiple of DSW_SIZE blocks */
- vblocks = roundup_2n(vblocks_phys, DSW_SIZE);
- bsize_ind = DSW_SHD_BM_OFFSET + (2 * DSW_BM_FBA_LEN(vblocks));
- bsize_cdep = bsize_ind;
- bsize_cdep += DSW_BM_FBA_LEN(vblocks) *
- ((vblocks < (uint64_t)(terablocks * DSW_SIZE)) ?
- int32_bits : int64_bits);
-
- (void) printf(gettext("Point in Time bitmap sizing\n\n"));
- (void) printf(gettext("Data volume (%s) size: %llu blocks\n"),
- volume, vblocks_phys);
-
- (void) printf(gettext("Required bitmap volume size:\n"));
- (void) printf(gettext(" Independent shadow: %llu blocks\n"),
- bsize_ind);
- (void) printf(gettext(" Full size dependent shadow: %llu blocks\n"),
- bsize_ind);
- (void) printf(gettext(" Compact dependent shadow: %llu blocks\n"),
- bsize_cdep);
-
- if (bitmap) {
- (void) printf("\n");
- (void) printf(gettext("Supplied bitmap volume %s "
- "(%llu blocks)\n"), bitmap, bblocks);
-
- if (bblocks >= bsize_cdep) {
- (void) printf(gettext("is large enough for all types "
- "of shadow volume\n"));
- } else if (bblocks >= bsize_ind) {
- (void) printf(gettext("is large enough for: "
- "Independent and full size dependent shadow "
- "volumes only\n"));
- rc = 6;
- } else {
- (void) printf(gettext("is not large enough for"
- "any type of shadow volume\n"));
- rc = 5;
- }
- }
-
- return (rc);
-}
-
-
-/*
- * Return codes:
- * 0 success (if bitmap was supplied it is large enough for all uses)
- * 1 usage, programing, or access errors
- * 2 unknown option supplied on command line
- * 3 SNDR bitmap is not large enough for diskq usage
- * 4 SNDR bitmap is not large enough for any usage
- * 5 II bitmap is not large enough for any usage
- * 6 II bitmap is not large enough for compact dependent usage
- */
-int
-main(int argc, char *argv[])
-{
- extern int optind;
- char *volume, *bitmap;
- int type = UNKNOWN;
- int opt;
- int rc = 0;
-
- (void) setlocale(LC_ALL, "");
- (void) textdomain("dsbitmap");
-
- program = strdup(basename(argv[0]));
-
- while ((opt = getopt(argc, argv, "hpr")) != EOF) {
- switch (opt) {
- case 'p':
- if (type != UNKNOWN) {
- warn(NULL, gettext(
- "cannot specify -p with other options"));
- usage();
- return (1);
- }
- type = II;
- break;
-
- case 'r':
- if (type != UNKNOWN) {
- warn(NULL, gettext(
- "cannot specify -r with other options"));
- usage();
- return (1);
- }
- type = SNDR;
- break;
-
- case 'h':
- if (argc != 2) {
- warn(NULL, gettext(
- "cannot specify -h with other options"));
- rc = 1;
- }
- usage();
- return (rc);
- /* NOTREACHED */
-
- default:
- usage();
- return (2);
- /* NOTREACHED */
- }
- }
-
- if (type == UNKNOWN) {
- warn(NULL, gettext("one of -p and -r must be specified"));
- usage();
- return (1);
- }
-
- if ((argc - optind) != 1 && (argc - optind) != 2) {
- warn(NULL, gettext("incorrect number of arguments to %s"),
- (type == SNDR) ? "-r" : "-p");
- usage();
- return (1);
- }
-
- volume = argv[optind];
- if ((argc - optind) == 2) {
- bitmap = argv[optind+1];
- } else {
- bitmap = NULL;
- }
-
- switch (type) {
- case SNDR:
- rc = do_sndr(volume, bitmap);
- break;
-
- case II:
- rc = do_ii(volume, bitmap);
- break;
-
- default:
- /* cannot happen */
- warn(NULL, gettext("one of -p and -r must be specified"));
- rc = 1;
- break;
- }
-
- return (rc);
-}
diff --git a/usr/src/cmd/avs/dscfg/Makefile b/usr/src/cmd/avs/dscfg/Makefile
deleted file mode 100644
index 9b4a1eff03..0000000000
--- a/usr/src/cmd/avs/dscfg/Makefile
+++ /dev/null
@@ -1,81 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-.KEEP_STATE:
-
-PROG = dscfg
-SHFILES = dscfgadm
-CLOBBERFILES = $(SHFILES)
-
-include ../../Makefile.cmd
-include ../Makefile.com
-
-
-LPROG = $(PROG:%=%.li)
-
-SUBDIRS= etc
-
-OBJS= dscfg.o
-
-CFLAGS += $(CCVERBOSE) -D_SYSCALL32
-CERRWARN += -_gcc=-Wno-unused-variable
-CERRWARN += -_gcc=-Wno-address
-LDLIBS += -ldscfg -lunistat
-LINTFLAGS += -Xa -n -s -x -m -u -Dlint -errhdr=%user -D_SYSCALL32
-LINTFLAGS += -erroff=E_NOP_ELSE_STMT -erroff=E_FUNC_SET_NOT_USED
-LINTFLAGS += -erroff=E_BAD_FORMAT_ARG_TYPE2
-LINTFLAGS += -erroff=E_FUNC_RET_MAYBE_IGNORED2
-LINTFLAGS += -erroff=E_FUNC_RET_ALWAYS_IGNOR2
-LINTDIR = $(KBASE)/lintdir
-LFILE = $(LINTDIR)/dscfg.ln
-ROOTLINK = $(ROOTUSRSBIN)/$(PROG)
-ROOTSHLINK = $(ROOTUSRSBIN)/$(SHFILES)
-
-all := TARGET= all
-install := TARGET= install
-clean := TARGET= clean
-clobber := TARGET= clobber
-lint := TARGET= lint
-
-all: $(SUBDIRS) $(PROG) $(SHFILES)
-
-install: $(SUBDIRS) all $(ROOTSHFILES) $(ROOTPROG) $(ROOTLINK) $(ROOTSHLINK)
-
-lint: $(SUBDIRS) lint_PROG
-
-clean: $(SUBDIRS)
- $(RM) *.o
-
-$(SUBDIRS): FRC
- @cd $@; pwd; $(MAKE) $(TARGET)
-
-$(ROOTLINK): $(ROOTUSRSBIN) $(ROOTPROG)
- -$(RM) $@; $(LN) $(ROOTPROG) $@
-
-$(ROOTSHLINK): $(ROOTUSRSBIN) $(ROOTSHFILES)
- -$(RM) $@; $(LN) $(ROOTSHFILES) $@
-
-FRC:
-
-include ../../Makefile.targ
diff --git a/usr/src/cmd/avs/dscfg/dscfg.c b/usr/src/cmd/avs/dscfg/dscfg.c
deleted file mode 100644
index 6e1d583cc0..0000000000
--- a/usr/src/cmd/avs/dscfg/dscfg.c
+++ /dev/null
@@ -1,894 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/vtoc.h>
-#include <sys/stat.h>
-#include <stdio.h>
-#include <sys/mnttab.h>
-#include <errno.h>
-#include <limits.h>
-#include <fcntl.h>
-#include <string.h>
-#include <strings.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <time.h>
-
-#include <locale.h>
-#include <langinfo.h>
-#include <libintl.h>
-#include <stdarg.h>
-#include <netdb.h>
-#include <ctype.h>
-#include <assert.h>
-
-#include <sys/nsctl/cfg_impl.h>
-#include <sys/nsctl/cfg.h>
-
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_u.h>
-#include <sys/unistat/spcs_errors.h>
-
-#ifdef DEBUG
-#include <sys/nsctl/dsw.h>
-#endif
-
-#define DEFAULT_PARSER_LOC "/etc/dscfg_format"
-
-int Cflg;
-int Dflg;
-int Lflg;
-int aflg;
-int iflg;
-int lflg;
-int nflg;
-int pflg;
-int rflg;
-int sflg;
-int uflg;
-
-int verbose;
-int noflags;
-int errflg;
-int mustcommit;
-char *locname; /* config location from cfg_location */
-char *cmdname;
-
-#define MAX_FILENAME 80
-
-char output_file[MAX_FILENAME]; /* specified output file */
-char altroot[MAX_FILENAME]; /* specifed root location */
-char config_file[MAX_FILENAME]; /* specified configuration file */
-char input_file[MAX_FILENAME]; /* specified input file */
-char logical_host[MAX_FILENAME]; /* specified cluster node */
-char device_group[MAX_FILENAME]; /* specified device group name */
-
-#define IS_NOT_CLUSTER 1
-#define IS_CLUSTER 2
-
-void cfg_invalidate_hsizes(int, const char *);
-static int check_cluster();
-
-void
-usage(char *errmsg)
-{
- if (errmsg)
- (void) fprintf(stderr, "%s: %s\n", cmdname, errmsg);
- (void) fprintf(stderr,
- gettext("dscfg \t\t\t\tDisplay location of "
- "local configuration database\n"));
- (void) fprintf(stderr, gettext("dscfg -l -s path\t\t"
- "List contents of configuration database\n"));
- (void) fprintf(stderr, gettext(
- "\t\t\t\tlocated at path specified\n"));
- (void) fprintf(stderr, gettext("dscfg -i\t\t\t"
- "Initialize configuration database\n"));
- (void) fprintf(stderr,
- gettext("dscfg -i -p "
-#ifdef DEBUG
-"[-n] "
-#endif
- "/etc/dscfg_format\tFormat configuration database\n"));
- (void) fprintf(stderr,
- gettext("dscfg -a file\t\t\tRestore configuration "
- "database from file\n"));
- (void) fprintf(stderr, gettext("\t\t\t\tspecified\n"));
- (void) fprintf(stderr,
- gettext("dscfg -l\t\t\tList contents of configuration database"
- "\n"));
- (void) fprintf(stderr,
- gettext("dscfg -L\t\t\tDisplay configuration database's\n"));
- (void) fprintf(stderr, gettext("\t\t\t\tlock status\n"));
- (void) fprintf(stderr, gettext("dscfg -h\t\t\tUsage message\n"));
- if (check_cluster() != IS_NOT_CLUSTER) {
- (void) fprintf(stderr, gettext("\nSun Cluster Usage\n"));
- (void) fprintf(stderr, gettext("******************\n"));
- (void) fprintf(stderr,
- gettext("dscfg -s path\t\t\tSet cluster "
- "configuration database at DID\n"));
- (void) fprintf(stderr, gettext("\t\t\t\tpath specified\n"));
- (void) fprintf(stderr, gettext("dscfg -D device_group\t\t"
- "Check status of cluster device group\n"));
- (void) fprintf(stderr, gettext("dscfg -C -\t\t\t"
- "Display location of cluster configuration\n"));
- (void) fprintf(stderr, gettext("\t\t\t\tdatabase\n"));
- (void) fprintf(stderr, gettext("dscfg -l -s DID_device\t\tList "
- "the contents of cluster configuration\n"));
- (void) fprintf(stderr, gettext("\t\t\t\tdatabase\n"));
- (void) fprintf(stderr, gettext("dscfg -C - -i\t\t\tInitialize "
- "cluster configuration database\n"));
- (void) fprintf(stderr, gettext("dscfg -C - -i -p "
- "/etc/dscfg_format Format cluster configuration database\n"));
- (void) fprintf(stderr, gettext("dscfg -C - -a file\t\t"
- "Restore cluster configuration database from\n"));
- (void) fprintf(stderr, gettext("\t\t\t\tfile specified\n"));
- (void) fprintf(stderr, gettext("dscfg -C - -l\t\t\t"
- "List contents of local configuration database\n"));
- (void) fprintf(stderr, gettext("dscfg -C device_group -l\t"
- "List configuration database by device group\n"));
- (void) fprintf(stderr, gettext("dscfg -C \"-\" -l\t\t\t"
- "List configuration database excluding\n"));
- (void) fprintf(stderr, gettext("\t\t\t\tdevice groups\n"));
- }
-}
-
-int
-parse_parse_config(CFGFILE *cfg)
-{
- FILE *fp;
- char inbuf[CFG_MAX_BUF];
- char *buff;
- int rc;
-
- /*
- * Open parser config file, use default if none specified
- */
- buff = (input_file[0]) ? input_file : DEFAULT_PARSER_LOC;
- if ((fp = fopen(buff, "r")) == NULL) {
- (void) fprintf(stderr,
- gettext("parser config file (%s) not found\n"), buff);
- return (-1);
- }
-
- /*
- * start at begining of configration database
- */
- cfg_rewind(cfg, CFG_SEC_ALL);
-
- while (((buff = fgets(inbuf, (sizeof (inbuf) - 1), fp)) != NULL)) {
- if (*buff == '#' || *buff == '%')
- continue;
- /* overwrite newline */
- buff[strlen(buff) - 1] = '\0';
- rc = cfg_update_parser_config(cfg, buff, CFG_PARSE_CONF);
- if (rc < 0) {
- (void) fprintf(stderr,
- gettext("update parser config rc %d key %s\n"),
- rc, buff);
- (void) fclose(fp);
- return (-1);
- }
- }
- (void) fclose(fp);
- return (1);
-}
-
-void
-parse_text_config(CFGFILE *cfg)
-{
- FILE *fp;
- char inbuf[CFG_MAX_BUF];
- char *buff;
- char *key;
- char *p;
- int rc;
-
- if ((fp = fopen(input_file, "r")) == NULL) {
- (void) fprintf(stderr,
- gettext("Unable to open text config %s\n"),
- input_file);
- exit(2);
- }
- bzero(inbuf, sizeof (inbuf));
- cfg_rewind(cfg, CFG_SEC_CONF);
- while (((buff = fgets(inbuf, (sizeof (inbuf) - 1), fp)) != NULL)) {
- if (*buff == '#')
- continue;
- /* overwrite newline */
- buff[strlen(buff) - 1] = '\0';
- key = strtok(buff, ":");
- if (!key) {
- continue;
- }
- p = &buff[strlen(key)+2];
- while (*p && isspace(*p)) {
- ++p;
- }
- if (!*p) {
- continue;
- }
- rc = cfg_put_cstring(cfg, key, p, strlen(p));
- if (rc < 0) {
- (void) fprintf(stderr,
- gettext("update text config failed rc %d key %s"),
- rc, buff);
- return;
- }
- bzero(inbuf, sizeof (inbuf));
- }
- (void) fclose(fp);
-}
-void
-dump_status(CFGFILE *cfg)
-{
- cfp_t *cfp = FP_SUN_CLUSTER(cfg);
-
- /*
- * WARNING will robinson
- * The following is using a non-exported internal interface
- * to libcfg
- * You may not use any of the following fields in MS software
- */
- if (!locname)
- exit(2);
- if (!verbose)
- (void) printf("%s\n", locname);
- else {
-#ifdef DEBUG
- (void) printf(gettext("Configuration location: %s\n"), locname);
- (void) printf(
- gettext("Header info:\n\t\t\tmagic: %x\tstate: %x\n"),
- cfp->cf_head->h_magic, cfp->cf_head->h_state);
- (void) printf(
- gettext("Parser section:\t\t"
- "Start: %x\tsize: %d offset: %d\n"),
- cfp->cf_mapped, cfp->cf_head->h_parsesize,
- cfp->cf_head->h_parseoff);
- (void) printf(
- gettext("Config section:\t\t"
- "Start: %x\tsize:%d\tacsize: %d\n"),
- cfp->cf_head->h_cparse, cfp->cf_head->h_csize,
- cfp->cf_head->h_acsize);
- (void) printf("\t\t\tccopy1: %s\tccopy2: %s\n",
- cfp->cf_head->h_ccopy1,
- cfp->cf_head->h_ccopy2);
- (void) printf(
- gettext("Sequence:\t\tseq1: %d\t\tseq2: %d\n"),
- cfp->cf_head->h_seq1, cfp->cf_head->h_seq2);
-#endif
- }
-}
-
-void
-dump_lockstat(CFGFILE *cfg)
-{
- pid_t pid;
- CFGLOCK lock;
- char ps_str[1024];
-
- if (cfg_get_lock(cfg, &lock, &pid) == TRUE) {
- (void) printf("%s %ld\n",
- lock == CFG_RDLOCK ?
- gettext("Read locked by process id") :
- gettext("Write locked by process id"),
- pid);
- (void) sprintf(ps_str, "ps -p %ld", pid);
- system(ps_str);
- } else
- (void) printf("%s\n", gettext("Not locked."));
-}
-
-
-/*
- * dump current configuration section to stdout
- */
-
-void
-print_config(CFGFILE *cfg)
-{
- time_t tloc = 0;
- int set = 0;
- char pconfig[CFG_MAX_BUF];
- char key[CFG_MAX_KEY];
- char buf[CFG_MAX_BUF];
- char *cp, pbuf[CFG_MAX_BUF];
- FILE *fp;
- int rc;
- int end;
-
- (void) snprintf(pconfig, sizeof (pconfig),
- "%s%s", altroot, DEFAULT_PARSER_LOC);
- if ((fp = fopen(pconfig, "r")) == NULL) {
- (void) fprintf(stderr,
- gettext("dscfg: unable to open "
- "parser configuration (%s): %s\n"),
- pconfig, strerror(errno));
- exit(1);
- }
-
- (void) time(&tloc);
- (void) printf(gettext("# Consolidated Dataservice Configuration\n"));
- (void) printf(gettext("# Do not edit out whitespace or dashes\n"));
- (void) printf(gettext("# File created on: %s"), ctime(&tloc));
-
- while (fgets(pbuf, (sizeof (pbuf) - 1), fp) != NULL) {
- if (pbuf[0] == '#') {
- /* comment */
- continue;
- }
- /* force a NULL terminator */
- pbuf[sizeof (pbuf) - 1] = '\0';
-
- if (pbuf[0] == '%') {
- /*
- * descriptive text
- * - print it (with comment leader) and move on
- */
- (void) printf("#%s", &pbuf[1]);
- continue;
- }
-
- /*
- * truncate the parser config in pbuf[] to just the tag
- */
- cp = strchr(pbuf, '.');
- if (cp != NULL) {
- *cp = '\0';
- }
-
- set = 1;
- /*CONSTCOND*/
- while (1) {
- bzero(buf, CFG_MAX_BUF);
- (void) snprintf(key,
- sizeof (key), "%s.set%d", pbuf, set);
- rc = cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF);
- if (rc < 0) {
- break;
- }
- /* trim trailing space if necessary */
- end = strlen(buf) - 1;
- if (buf[end] == ' ')
- buf[end] = '\0';
-
- (void) printf("%s:%s\n", pbuf, buf);
- set++;
- }
- }
-
- (void) fclose(fp);
-}
-
-int
-make_new_config(const char *fileloc)
-{
- int fd;
- int rc;
- int skip;
-
- char buf[CFG_MAX_BUF];
- /*CONSTCOND*/
- assert((sizeof (buf) % 512) == 0);
-
- bzero(buf, CFG_MAX_BUF);
-
- if ((fd = open(fileloc, O_RDWR | O_CREAT, 0640)) == -1) {
- return (-1);
- }
-
- /* if this is a device, we may have to skip the vtoc */
- if ((skip = cfg_shldskip_vtoc(fd, fileloc)) == -1) {
- (void) fprintf(stderr,
- gettext("dscfg: unable to read vtoc on (%s)\n"),
- fileloc);
- return (-1);
- } else if (skip) {
- do {
- rc = lseek(fd, CFG_VTOC_SKIP, SEEK_SET);
- } while (rc == -1 && errno == EINTR);
-
- if (rc == -1) {
- (void) fprintf(stderr, gettext("dscfg: seek error"));
- return (-1);
- }
- }
-
- do {
- rc = write(fd, buf, sizeof (buf));
- } while (rc == -1 && errno == EINTR);
-
- close(fd);
-
- return ((rc < 0) ? 0 : 1);
-}
-
-/*
- * dscfg
- * configure or return dataservice persistent configuration
- *
- * options
- * -i initialize file for first time
- * -l dump current configuration to stdout in ascii
- * -a add
- * -C node Set resource filter
- * -p parser config specified input file
- * -s set partition location or filename in default location
- * -L print configuration lock status
- * -u upgrade
- * -r prepend bootdir to beginning of path for cfg_open
- * no options status
- *
- *
- */
-#ifdef lint
-int
-dscfg_lintmain(int argc, char *argv[])
-#else
-int
-main(int argc, char *argv[])
-#endif
-{
- CFGFILE *cfg;
- extern char *optarg;
- char *loc;
- int offset = 0;
- int rc;
- char c;
- int local;
- int action_counts = 0;
-
- bzero(input_file, sizeof (input_file));
- (void) setlocale(LC_ALL, "");
- (void) textdomain("dscfg");
- logical_host[0] = '\0';
- cmdname = argv[0];
-#ifdef DEBUG
- while ((c = getopt(argc, argv, "a:C:dD:ilLp:r:s:hvn")) != EOF) {
-#else
- while ((c = getopt(argc, argv, "a:C:dD:ilLp:r:s:h")) != EOF) {
-#endif
- switch (c) {
- case 'a':
- aflg++;
- strcpy(input_file, optarg);
- mustcommit++;
- action_counts++;
- break;
- case 'C':
- Cflg++;
- strcpy(logical_host, optarg);
- if (logical_host && *logical_host == '-')
- if (argc == 3)
- action_counts++;
- break;
- case 'D':
- Dflg++;
- strcpy(device_group, optarg);
- action_counts++;
- break;
- case 'i':
- iflg++;
- mustcommit++;
- action_counts++;
- break;
- case 'l':
- lflg++;
- action_counts++;
- break;
- case 'L':
- Lflg++;
- action_counts++;
- break;
- case 'p':
- pflg++;
- strcpy(input_file, optarg);
- mustcommit++;
- break;
- case 's':
- sflg++;
- strcpy(config_file, optarg);
- action_counts++;
- break;
- case 'h':
- usage(NULL);
- exit(0);
- /*NOTREACHED*/
-#ifdef DEBUG
- case 'v':
- verbose++;
- action_counts++;
- break;
-#endif
-#ifdef UPGRADE
- case 'u':
- uflg++;
- action_counts++;
- break;
-#endif
-
- case 'r':
- rflg++;
- strcpy(altroot, optarg);
- break;
-
- case 'n':
- nflg++;
- break;
-
- default:
- usage(NULL);
- exit(1);
- break;
- };
- }
-
- switch (action_counts) {
- case 0:
- if (argc > 1) {
- if (pflg)
- usage(gettext(
- "-p option must be used in conjunction with -i"));
- else
- usage(gettext("must specify an action flag"));
- exit(1);
- }
- break;
- case 1:
- break;
- case 2:
- if (lflg && sflg)
- break;
- else {
- usage(gettext("too many action flags"));
- exit(1);
- break;
- }
- default:
- usage(gettext("too many action flags"));
- exit(1);
- break;
- }
-
- if (argc == 1 || (argc == 2 && verbose) || (argc == 3 && (rflg|Cflg)))
- noflags++;
-
- if (Dflg) {
- /*
- * Determine if the value specified is a device group
- * that is active on this node
- */
- char *other_node;
- if ((cfg_issuncluster() > 0) && (strlen(device_group) > 0)) {
- local = cfg_dgname_islocal(device_group, &other_node);
- if (local == 0)
- (void) fprintf(stderr, gettext(
- "Device group %s active on %s\n"),
- device_group, other_node);
- else if (local == 1)
- (void) fprintf(stderr, gettext(
- "Device group %s active on this node\n"),
- device_group);
- else
- (void) fprintf(stderr, gettext(
- "Device group %s not found\n"), device_group);
- return (local);
- } else {
- (void) fprintf(stderr, gettext(
- "dscfg -D is only allowed in "
- "Sun Cluster OE\n"));
- return (0);
- }
- }
-
- if (sflg && !lflg) {
- /*
- * Only allow setting location on a non-sun cluster system
- * if the cluster reference file is already present.
- */
- struct stat dscfg_stat = {0};
- if (cfg_issuncluster() <= 0) {
- if (stat(CFG_CLUSTER_LOCATION, &dscfg_stat) != 0) {
- if (dscfg_stat.st_blocks == 0) {
- (void) fprintf(stderr, gettext(
- "dscfg -s is only allowed in "
- "Sun Cluster OE\n"));
- exit(1);
- }
- }
- }
-
- spcs_log("dscfg", NULL, gettext("dscfg -s %s"), config_file);
- locname = cfg_location(config_file, CFG_LOC_SET_CLUSTER,
- rflg ? altroot : NULL);
- if (locname == NULL) {
- (void) fprintf(stderr, gettext("dscfg: %s\n"),
- cfg_error(NULL));
- exit(1);
- } else
- exit(0);
-
- } else if (sflg && lflg) {
- /* s used with l for temporarily peeking at a dscfg database */
- loc = config_file;
- } else {
- locname = cfg_location(NULL,
- Cflg ? CFG_LOC_GET_CLUSTER : CFG_LOC_GET_LOCAL,
- rflg ? altroot : NULL);
- if (Cflg && (locname == NULL)) {
- (void) fprintf(stderr, gettext(
- "dscfg: cluster config not set: %s\n"),
- cfg_error(NULL));
- return (1);
- }
- loc = rflg ? locname : NULL;
- }
-
- /*
- * the following hack forces the configuration file to initialize
- */
- if (iflg && !pflg) {
- int fild;
- int c;
- char buf[CFG_MAX_BUF] = {0};
- cfp_t *cfp;
-
- if (!nflg) {
- (void) printf(
- gettext("WARNING: This option will erase your "
- "Availability Suite configuration\n"));
- (void) printf(
- gettext("Do you want to continue? (Y/N) [N] "));
-
- c = getchar();
- switch (c) {
- case 'y':
- case 'Y': break;
- case 'n':
- case 'N':
- case '\n':
- (void) fprintf(stderr, gettext(
- "dscfg: configuration not initialized\n"));
- exit(1);
- default:
- (void) fprintf(stderr, gettext(
- "dscfg: %d is not a valid response\n"), c);
- exit(1);
- }
- }
-
- spcs_log("dscfg", NULL, gettext("dscfg -i"));
-
- if ((cfg = cfg_open(loc)) == NULL) {
- /* this is not a good config, or non-existent so.. */
- if (!make_new_config(locname)) {
- (void) fprintf(stderr, gettext("dscfg: %s\n"),
- cfg_error(NULL));
- exit(1);
- }
- if ((cfg = cfg_open(loc)) == NULL) {
- (void) fprintf(stderr, gettext("dscfg: %s\n"),
- cfg_error(NULL));
- exit(1);
- }
- }
-
- /*
- * Set cluster node if specified
- */
- if (Cflg)
- cfg_resource(cfg, logical_host);
-
- if (cfg_is_cfg(cfg) != 1) {
- if (!make_new_config(locname)) {
- (void) fprintf(stderr, gettext("dscfg: unable "
- " to create new config \n"));
- exit(1);
- }
- }
-
- if (!cfg_lock(cfg, CFG_WRLOCK)) {
- (void) fprintf(stderr, gettext("dscfg: %s\n"),
- cfg_error(NULL));
- exit(1);
- }
-
- cfp = FP_SUN_CLUSTER(cfg);
- if ((fild = cfp->cf_fd) == 0) {
- (void) fprintf(stderr,
- gettext("dscfg: failure to access %s "
- "configuration database: %s\n"),
- (Cflg) ? gettext("cluster") : gettext("local"),
- cfg_error(NULL));
- exit(1);
- }
-
- if (cfg_shldskip_vtoc(fild, locname) > 0)
- offset += CFG_VTOC_SKIP;
-
- lseek(fild, offset, SEEK_SET);
- write(fild, buf, sizeof (buf));
- cfg_invalidate_hsizes(fild, locname);
-
- cfg_close(cfg);
- exit(0);
- }
-
- if (pflg && !iflg) {
- usage(gettext("-p option must be used in conjunction with -i"));
- exit(1);
-
- }
-
- if (uflg) {
- char cmd[CFG_MAX_BUF];
- if (rflg)
- (void) snprintf(cmd, sizeof (cmd),
- "%s/usr/sbin/dscfg -r %s -l >"
- " %s/var/tmp/.dscfg.bak", altroot,
- altroot, altroot);
- else
- (void) snprintf(cmd, sizeof (cmd),
- "/usr/sbin/dscfg -l >"
- " /var/tmp/.dscfg.bak");
-
- if (system(cmd) != 0) {
- (void) fprintf(stderr,
- "dscfg: unable to create backup\n");
- exit(1);
- }
-
- if ((cfg = cfg_open(loc)) == NULL) {
- (void) fprintf(stderr, gettext("dscfg: %s\n"),
- cfg_error(NULL));
- exit(2);
- }
-
- if (!cfg_lock(cfg, CFG_UPGRADE)) {
- (void) fprintf(stderr,
- gettext("dscfg: upgrade failed\n"));
- cfg_close(cfg);
- exit(1);
- }
-
- cfg_close(cfg);
- exit(0);
- }
-
- if ((cfg = cfg_open(loc)) == NULL) {
- (void) fprintf(stderr, gettext("dscfg: %s\n"), cfg_error(NULL));
- exit(2);
- }
-
- /*
- * Set cluster node if specified
- */
- if (Cflg)
- cfg_resource(cfg, logical_host);
-
- if ((!pflg) && (!noflags)) {
- if (cfg_is_cfg(cfg) != 1) {
- (void) fprintf(stderr,
- gettext("dscfg: %s\n"), cfg_error(NULL));
- cfg_close(cfg);
- exit(1);
- }
- }
-
- if (Lflg) {
- dump_lockstat(cfg);
- cfg_close(cfg);
- exit(0);
- }
-
- if (noflags) {
- dump_status(cfg);
- cfg_close(cfg);
- exit(0);
- }
-
- if (!cfg_lock(cfg, mustcommit? CFG_WRLOCK : CFG_RDLOCK)) {
- (void) fprintf(stderr, gettext("cfg_lock: lock failed\n"));
- cfg_close(cfg);
- exit(1);
- }
-
- if (lflg) {
- print_config(cfg);
- cfg_close(cfg);
- exit(0);
- }
-
- /*
- * initialize configuration
- */
- if (iflg) {
- spcs_log("dscfg", NULL, gettext("dscfg -i -p %s"), input_file);
-
- if (!pflg) {
- (void) fprintf(stderr,
- gettext("dscfg: cannot init without "
- "parser configuration file\n"));
- cfg_close(cfg);
- exit(1);
- } else if (parse_parse_config(cfg) < 0) {
- (void) fprintf(stderr, gettext("dscfg: cannot load "
- "parser configuration file\n"));
- cfg_close(cfg);
- exit(1);
- }
- }
-
- /*
- * read asci config file and write
- */
- if (aflg) {
- spcs_log("dscfg", NULL, gettext("dscfg -a %s"), input_file);
- parse_text_config(cfg);
- }
-
- if (mustcommit) {
- rc = cfg_commit(cfg);
- if (rc < 0) {
- int sev = 0;
- (void) fprintf(stderr, gettext("dscfg: %s\n"),
- cfg_error(&sev));
- if (sev == CFG_EFATAL) {
- cfg_close(cfg);
- exit(2);
- }
- }
- }
-
- cfg_close(cfg);
- return (0);
-}
-
-static int
-check_cluster()
-{
- static int is_cluster = -1;
- int rc;
-
- if (is_cluster != -1)
- return (is_cluster);
- rc = cfg_iscluster();
- if (rc > 0) {
- is_cluster = IS_CLUSTER;
- return (is_cluster);
- } else if (rc == 0) {
- is_cluster = IS_NOT_CLUSTER;
- return (is_cluster);
- } else {
- (void) fprintf(stderr,
- gettext("dscfg: unable to determin environment\n"));
- /*NOTREACHED*/
- }
-
- /* gcc */
- return (is_cluster);
-}
diff --git a/usr/src/cmd/avs/dscfg/dscfgadm.sh b/usr/src/cmd/avs/dscfg/dscfgadm.sh
deleted file mode 100644
index 736a89b2a2..0000000000
--- a/usr/src/cmd/avs/dscfg/dscfgadm.sh
+++ /dev/null
@@ -1,1547 +0,0 @@
-#!/usr/bin/ksh
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2010 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-typeset -r PROG=$(basename $0)
-typeset -r CTAG_NULL="-"
-
-#
-# help message
-#
-help()
-{
- $xopt
-
- cluster_configured
- CLUSTER_CONFIGURED=$?
-
- echo "\
-usage:
- $PROG
- $PROG -i
- $PROG -e [-r][-p]
- $PROG -d [-r]" >&2
- if [ $CLUSTER_CONFIGURED -eq 1 ]; then
- echo "\
- $PROG -s" >&2
- fi
-
- echo "\
- -i : display information on the Availability Suite services
- -e : enable Availability Suite services (all, by default)
- -d : disable Availability Suite services (all, by default)
- -r : enable/disable Remote Mirror
- -p : enable Point in Time Copy" >&2
- if [ $CLUSTER_CONFIGURED -eq 1 ]; then
- echo "\
- -s : set the location of the cluster configuration database" >&2
- fi
- echo "\
- -x : turn on script debugging (may be used with any valid option)
-
- When executed with no options or with nothing but -x, $PROG runs in
- interactive fashion, allowing the user to initialize the local (and
- if applicable, the cluster) configuration database, and to start the
- Availability Suite services." >&2
-
- exit 2
-}
-
-########################## SET GLOBAL VARIABLES ######################
-
-# root directory
-PKG_INSTALL_ROOT=""
-export PKG_INSTALL_ROOT
-
-# set lib path
-LD_LIBRARY_PATH=/usr/lib:/usr/lib
-export LD_LIBRARY_PATH
-
-# set dscfg
-DSCFG="/usr/sbin/dscfg"
-export DSCFG
-
-# set parser config location
-PCONFIG="/etc/dscfg_format"
-export PCONFIG
-
-# set local dscfg location
-export LOCAL_DSCFG="/etc/dscfg_local"
-
-# set cluster dscfg reference file
-export CLUSTER_REF="/etc/dscfg_cluster"
-
-# a service that has a dependency on us
-FS_LOCAL_SVC="svc:/system/filesystem/local"
-
-NODELIST="/tmp/nodelist"
-DSCFGLOCKDCF="/etc/dscfg_lockdb"
-DSCFG_DEPEND_NOCHK="/tmp/.dscfgadm_pid"
-
-# SMF defines
-MANIFEST_PATH=/lib/svc/manifest/system
-
-# SMF services (enable and disable)
-SMF_ENABLE="nws_scm nws_sv nws_ii nws_rdc nws_rdcsyncd"
-SMF_DISABLE="nws_rdcsyncd nws_rdc nws_ii nws_sv nws_scm"
-
-# state of each service
-nws_scm_enabled=0
-nws_sv_enabled=0
-nws_ii_enabled=0
-nws_rdc_enabled=0
-nws_rdcsyncd_enabled=0
-
-# set path
-PATH=/usr/bin:/usr/sbin:/sbin/sh
-export PATH
-
-# set architecture
-ARCH=`uname -p`
-export ARCH
-OS_MINOR=`uname -r | cut -d '.' -f2`
-
-# number of sectors required for database
-# 1024*1024*5.5/512
-REQUIRED=11264
-
-# must set here, else seen as null in MAIN
-VALID_DB_ENTERED=0
-
-NO_ARGS=0
-
-# for debugging
-xopt=
-
-# set lengthy message here
-CLUST_LOC_MESS="The current location is invalid for a Sun StorageTek \
-Data Services configuration database. Once a valid location is \
-entered (raw slice on \"did\" device), you may upgrade the existing \
-database to this new location - following the procedure outlined \
-in the Installation and Configuration Guide."
-
-########################## SET GLOBAL VARIABLES ######################
-
-
-########################## ERROR ####################################
-
-# called with optional error msg $1
-# prints basic guidelines for configuration of the database location
-error()
-{
- $xopt
-
- echo >&2
- echo "INSTALLATION ERROR" >&2
- echo "Error: $1" >&2
- echo >&2
- in_cluster
-
- if [ $? -eq 1 ]; then
- echo "GENERAL INSTALLATION RULES:" >&2
- echo "\tBecause you are installing on a cluster," >&2
- echo "\tthe database must be located on a raw slice of a did device.">&2
- echo "\t e.g. /dev/did/rdsk/d17s1" >&2
- fi
- # let?
- MB=`expr $REQUIRED / 2 / 1024`
- echo "\t$REQUIRED sectors ($MB MBs) are required for the database." >&2
-}
-
-########################## ERROR ####################################
-
-########################## ALL LOCATION TESTS ########################
-
-# sets numerous environment variables describing the state of the system
-get_system_state()
-{
- $xopt
-
- valid_local_dscfg_exists
- VALID_LOCAL_DB=$?
- OLD_VALID_LOCAL_DB=$VALID_LOCAL_DB
-
- in_cluster
- IN_CLUSTER=$?
-
- cluster_configured
- CLUSTER_CONFIGURED=$?
-
- if [ $IN_CLUSTER = 1 ]; then
- valid_cluster_dscfg_exists
- VALID_CLUSTER_DB=$?
- OLD_VALID_CLUSTER_DB=$VALID_CLUSTER_DB
- else
- VALID_CLUSTER_DB=0
- fi
-}
-
-# Checks if in cluster
-# returns 1 if in cluster, else 0
-#
-in_cluster()
-{
- $xopt
-
- if [ -x /usr/sbin/clinfo ]; then
- clinfo
- if [ $? -eq 0 ]; then
- return 1
- else
- return 0
- fi
- else
- return 0
- fi
-}
-
-# checks if a system is configured as a cluster
-# returns 1 if configured as a cluster, 0 if not
-#
-cluster_configured()
-{
- $xopt
-
- if [ -f /etc/cluster/nodeid ]; then
- return 1
- else
- return 0
- fi
-}
-
-# Check the list of Sun Cluster device groups known in the dscfg, determing
-# if they are currently enabled on this Sun Cluster node. If so, fail allowing
-# the system administator to scswitch them elsewhere.
-#
-check_device_groups()
-{
- $xopt
-
- if [ $VALID_CLUSTER_DB == 1 ]; then
- DEVICE_GROUPS=`$DSCFG -s $FILE_LOC -l 2>/dev/null | \
- grep "^dsvol:" | cut -d' ' -f3 | sort | uniq | xargs`
- for x in $DEVICE_GROUPS
- do
- $DSCFG -D $x 2>/dev/null
- if [ $? -eq 1 ]
- then
- IN_USE="$IN_USE $x"
- fi
- done
-
- if [ -n "$IN_USE" ]
- then
- print "The following Sun Cluster device groups are in use "
- print "by Availability Suite on this node."
- print ""
- print "$IN_USE"
- print ""
- print "'scswitch' them to another Sun Cluster node before "
- print "attempting to disable any data services."
- return 1
- else
- return 0
- fi
- fi
-
- return 0
-}
-
-# checks to see if this is a char device in the
-# /dev/did/rdsk directory returns 1 if so.
-#
-is_did_device()
-{
- $xopt
-
- DID=`echo $1 | awk -F/ '{print $3}'`
- RDSK=`echo $1 | awk -F/ '{print $4}'`
-
- if [ "did" = $DID -a "rdsk" = $RDSK -a -c $1 ]; then
- return 1
- else
- return 0
- fi
-}
-
-#
-# checks size of area for db location
-#
-check_size()
-{
- $xopt
-
- # if in cluster look for d*s*
- SLICE=`echo $1 | sed -n 's/.*d.*s\(.*\)/\1/p'`
-
- SECTORS=`prtvtoc $1 | tr -s ' '| grep "^ $SLICE " | awk '{print $5}'`
-
- if [ -z "$SECTORS" ]; then
- echo "SLICE at $1 not found on this device"
- return 0
- fi
-
- # if required size is greater than space available, then fail
- if [ $REQUIRED -gt $SECTORS ]; then
- return 0
- else
- return 1
- fi
-}
-
-# looks in dscfg_cluster reference file. if a location is configured,
-# tests to see if it is a valid database. if so, returns 1
-#
-valid_cluster_dscfg_exists()
-{
- $xopt
-
- if [ -s $CLUSTER_REF ]; then
- FILE_LOC=`head -1 $CLUSTER_REF`
- contains_data $FILE_LOC
- return $?
- else
- return 0
- fi
-}
-
-
-# checks for the existence of dscfg_local database, and if it exists,
-# tests to see if it is a valid database. if so, returns 1
-#
-valid_local_dscfg_exists()
-{
- $xopt
-
- if [ -s $LOCAL_DSCFG ]; then
- contains_data $LOCAL_DSCFG
- return $?
- else
- return 0
- fi
-}
-
-# used to test if a valid DS config database exists on machine already
-# MAGIC_STRING is the top line in the config used in v3.1 & v3.2
-#
-contains_data()
-{
- $xopt
-
- # dscfg distinct strings, varies on the architecture
- if [ $ARCH = "sparc" ]
- then
- MAGIC_STRING="MAGI"
- elif [ $ARCH = "i386" ]
- then
- MAGIC_STRING="IGAM"
- fi
-
- # Create a PID unique temporary file
- TMP_FILE=/tmp/$$
-
- # Write the first or 16th block (skipping over VTOC) to
- # the TMP_FILE, then scan for the presence of the "MAGI"
- #
- for offset in 0 16
- do
- if [ ! -z "$1" ]; then
- dd if=$1 of=$TMP_FILE count=1 iseek=$offset 2>/dev/null
- FILECONTENTS=`strings $TMP_FILE | head -1 2>/dev/null`
- if [ `echo $FILECONTENTS | grep -c "$MAGIC_STRING"` -gt 0 ]; then
- rm $TMP_FILE
- return 1
- fi
- fi
- done
-
- rm $TMP_FILE
- return 0
-}
-
-########################## ALL LOCATION TESTS ########################
-
-
-########################## MAIN FUNCTIONS ############################
-
-# since location already has been set, asks what to do now? keeping
-# it still checks the size (since an upgrade from 3.0 may still be
-# occuring) and also checks if was an old cluster config on disallowed
-# /dev/did/dsk directory
-#
-# returns:
-# 0 if cluster location is invalid or the user does not want to keep it
-# 1 if the location is valid and the user wants to keep it.
-#
-keep_it()
-{
- $xopt
-
- NOTE="\nThe Sun StorageTek Data Services database configuration"
- NOTE="$NOTE location has already been set."
- echo $NOTE
-
- echo "\nCurrent location: $PKG_INSTALL_ROOT$FILE_LOC"
-
- QUEST="Would you like to preserve the existing configuration"
- QUEST="$QUEST information at its current location? "
-
- ANS=`ckyorn -Qd n -p "$QUEST"`
-
- case $ANS in
- y|Y|yes|YES|Yes)
- #Since the user has said "yes I want to keep this current one"
- #it may actually be a 3.x database, which only required 4.5mb
- #space, so now will check that there is room to grow another 1mb"
- check_location $FILE_LOC
- if [ $? = 0 ]; then
- error "$CLUST_LOC_MESS"
- return 0
- else
- OLD_FILE_LOC=$FILE_LOC
- FILE_LOC=$NULL
- return 1
- fi
- ;;
- *)
- return 0
- ;;
- esac
-}
-
-#
-# asks if user wants to keep existing db information, overwrite with
-# a new db, or view the contents, and be asked again...
-# returns:
-# 0 if old location is bad
-# 1 if old location is good
-#
-preserve_overwrite_maybe()
-{
- $xopt
-
- echo "\nIt appears a valid database configuration exists here already."
-
- while true
- do
- SAFE_LOC=$FILE_LOC
-
- echo "\nWould you like to preserve this information and continue?"
- echo "\ty - preserve current configuration"
- echo "\tn - overwrite with new configuration"
- echo "\tmaybe - view contents of current configuration"
-
- ANS=`ckkeywd -Q y n maybe`
- case $ANS in
- y)
- check_location $FILE_LOC
- if [ $? = 0 ]; then
- error "$CLUST_LOC_MESS"
- return 0
- else
- $DSCFG -s "$FILE_LOC" -C $CTAG_NULL >/dev/null 2>&1
- OLD_FILE_LOC=$FILE_LOC
- FILE_LOC=$NULL
- return 1
- fi
- ;;
- n)
- check_location $FILE_LOC
- if [ $? = 0 ]; then
- error "$CLUST_LOC_MESS"
- return 0
- else
- return 1
- fi
- ;;
-
- maybe)
- # print contents of this db config.
- echo "\nContents of database configuration found at $SAFE_LOC are:"
- $DSCFG -l -s "$FILE_LOC" | more
- FILE_LOC=$SAFE_LOC
- continue
- ;;
- esac
- done
-}
-
-# gets location from user
-#
-get_location()
-{
- $xopt
-
- #Checks for absolute path name, and if file name and file doesn't
- #exist, creates it.
- echo "\n\n----------ENTER DATABASE CONFIGURATION LOCATION-----------------"
- echo "Note: Please ensure this location meets all requirements specified"
- echo "in the Availability Suite Installation Guide."
-
- FILE_LOC=`ckpath -artwQ -p "Enter location:"`
- if [ $? = 1 ]
- then
- exit 1
- fi
-
- # allow non-root user to access for least privileges
- chmod 666 $FILE_LOC
-}
-
-
-#
-# tests for proper config
-#
-# returns:
-# 0 if bad location
-# 1 if good location
-#
-check_location()
-{
- $xopt
-
- # set to FILE_LOC
- LOCATION=$1
-
- did_clust_msg="You are in cluster and $LOCATION is not valid DID device"
-
- # Set "actual file location" variable here to equal file location
- # entered by user because getting here means contains_data was already
- # successfully called before and now the two can equal each other for
- # future testing.
-
- SAFE_LOC=$FILE_LOC
-
- if [ $IN_CLUSTER = 1 -o $CLUSTER_CONFIGURED = 1 ]; then
- if [ -b "$LOCATION" ] || [ -c "$LOCATION" ]; then
- is_did_device $LOCATION
- if [ $? = 0 ]; then
- error "$did_clust_msg"
- return 0
- fi
- else
- error "$did_clust_msg"
- return 0
- fi
- else
- echo "Location may not be changed in a non Sun Cluster OE." 2>&1
- return 0
- fi
-
- check_size $LOCATION
-
- if [ $? != 1 ]; then
- error "$LOCATION does not meet minimum space requirement."
- return 0
- else
- return 1
- fi
-}
-
-#
-# Notifies the user that the SMF services are online,
-# and gives him the option to disable the services before proceeding. If
-# the services are not disabled, the program cannot proceed with setting
-# a new dscfg location.
-#
-ask_to_disable()
-{
- $xopt
-
- echo "\
-\nYour services must be disabled before a new configuration location is set.\n"
-
- QUEST="Would you like to disable the services now and continue with the"
- QUEST="$QUEST Availability Suite setup? "
-
- ANS=`ckyorn -Qd n -p "$QUEST"`
-
- case $ANS
- in y|Y|yes|YES|Yes)
- return 1
- ;;
- *)
- return 0
- ;;
- esac
-}
-
-#
-# Asks the user if he would like to enable the services now. If so,
-# import them (if necessary) and enable them.
-#
-ask_to_enable()
-{
- $xopt
-
- echo "\
-\nIf you would like to start using the Availability Suite immediately, you may
-start the SMF services now. You may also choose to start the services later
-using the $PROG -e command."
-
- QUEST="Would you like to start the services now? "
-
- ANS=`ckyorn -Qd n -p "$QUEST"`
-
- case $ANS
- in y|Y|yes|YES|Yes)
- return 1
- ;;
- *)
- return 0
- ;;
- esac
-}
-
-#
-# display information about the system
-#
-display_info()
-{
- $xopt
-
- typeset grp_error_flg=0
- typeset -L15 svc state en SVC="SERVICE" STATE="STATE" EN="ENABLED"
- echo "$SVC\t$STATE\t$EN"
-
- for i in $SMF_ENABLE
- do
- is_imported $i
- if [ $? = 1 ]
- then
- state=`svcprop -c -p restarter/state \
- svc:/system/${i}:default`
- en=`svcprop -c -p general/enabled \
- svc:/system/${i}:default`
- check_fs_local_grouping $i
- if [ $? -ne 0 ]
- then
- svc="${i}***"
- grp_error_flg=$((grp_error_flg + 1))
- else
- svc=$i
- fi
-
- echo "$svc\t$state\t$en"
- fi
- done
-
- print "\nAvailability Suite Configuration:"
- printf "Local configuration database: "
- if [ $VALID_LOCAL_DB = 1 ]
- then
- print "valid"
- else
- print "invalid"
- fi
-
- if [ $CLUSTER_CONFIGURED = 1 ]
- then
- printf "cluster configuration database: "
- if [ $VALID_CLUSTER_DB = 1 ]
- then
- print "valid"
- print "cluster configuration location: ${FILE_LOC}"
- else
- print "invalid"
- fi
- fi
-
- if [ $grp_error_flg -gt 0 ]
- then
- typeset p
- typeset p_has
- if [ $grp_error_flg -gt 1 ]
- then
- p="s"
- p_has="have"
- else
- p=""
- p_has="has"
- fi
-
- printf "\n*** Warning: The service$p above $p_has an incorrect "
- printf "dependency. To repair the\n"
- printf "problem, run \"dscfgadm\".\n"
- fi
-}
-
-#
-# initialize the local configuration database (only called if none exists)
-# returns 0 if successful, 1 if failed
-#
-initialize_local_db()
-{
- $xopt
-
- echo "Could not find a valid local configuration database."
- echo "Initializing local configuration database..."
- echo y | ${DSCFG} -i > /dev/null 2>&1
- ${DSCFG} -i -p ${PCONFIG} > /dev/null 2>&1
-
- # Make sure the new location is initialized properly
- valid_local_dscfg_exists
- VALID_LOCAL_DB=$?
- if [ $VALID_LOCAL_DB != 1 ]
- then
- echo "Unable to initialize local configuration database" >&2
- return 1
- else
- echo "Successfully initialized local configuration database"
- fi
-
- return 0
-}
-
-#
-# initialize the cluster configuration database, if necessary
-# returns 0 if successful, 1 if failed
-#
-initialize_cluster_db()
-{
- $xopt
-
- if [ ! -n "$FILE_LOC" ]
- then
- return 0
- fi
-
- echo "Initializing cluster configuration database..."
- ${DSCFG} -s ${FILE_LOC} -C $CTAG_NULL > /dev/null 2>&1
- echo y | ${DSCFG} -i -C $CTAG_NULL > /dev/null 2>&1
- ${DSCFG} -i -p ${PCONFIG} -C $CTAG_NULL > /dev/null 2>&1
-
- # make sure the cluster db is valid now
- valid_cluster_dscfg_exists
- VALID_CLUSTER_DB=$?
- if [ $VALID_CLUSTER_DB != 1 ]
- then
- echo "Unable to initialize cluster configuration database" >&2
- return 1
- else
- echo "Successfully initialized cluster configuration database"
- fi
-
- return 0
-
-}
-
-#
-# prompt the user for a config location and set AVS to use that location
-#
-set_cluster_config()
-{
-
-$xopt
-
-REPEAT=0
-while [ $REPEAT -eq 0 ]; do
- # See if user has entered location already, and it was an existing
- # db. Retruns FILE_LOC value
- if [ $VALID_DB_ENTERED = 1 ]; then
-
- # reset
- VALID_DB_ENTERED=0
- preserve_overwrite_maybe
-
- # if 1, location passes, and FILE_LOC being passed to end, else
- # set VALID_CLUSTER_DB to 0 since the "valid one" isn't valid anymore
- # (bad size, etc) thereby when looping go straight to get_location
- if [ $? = 1 ]; then
- REPEAT=1
- continue
- else
- VALID_CLUSTER_DB=0
- continue
- fi
- fi
-
- # if 1, then valid db exists, now see what user wants to do
- if [ $VALID_CLUSTER_DB = 1 ]; then
- SAFE_LOC=$FILE_LOC
- keep_it
-
- # if 0, then user can't or won't keep location. set PROMPT
- # so we will get new location from user.
- if [ $? = 0 ]; then
- PROMPT=0
- else
- PROMPT=1
- fi
- fi
-
- # if either are 0, then user wants or needs new db as outlined in
- # earlier comments
- if [ $VALID_CLUSTER_DB = 0 ] || [ $PROMPT = 0 ]; then
- #
- # We cannot proceed if the services are running. Give the user
- # a chance to stop the services. If he chooses not to, bail.
- #
- check_enabled
- if [ $? = 1 ]
- then
- show_enabled
- ask_to_disable
- if [ $? = 0 ]
- then
- echo "A new configuration location was not set."
- exit 1
- else
- disable_services
- if [ $? != 0 ]
- then
- exit 1
- fi
- fi
-
- fi
-
- get_location
- contains_data $FILE_LOC
-
- # if 1, then user entered an existsing db location, loop
- # back to ask what to do with it
- if [ $? = 1 ]; then
- VALID_DB_ENTERED=1
- continue
- else
- check_location $FILE_LOC
-
- # if 0, that means location has failed, loop and
- # get_location again
- if [ $? = 0 ]; then
- VALID_CLUSTER_DB=0
- continue
- fi
- # entered location passes tests
- REPEAT=1
- continue
- fi
- else
- # user wants to leave location where and how it is
- # FILE_LOC being passed all the way to end
- REPEAT=1
- continue
- fi
-done
-
-}
-
-########################## MAIN FUNCTIONS ############################
-
-######################## SMF HELPER FUNCTIONS ########################
-#
-# check if any SMF service is online (enabled)
-#
-check_enabled()
-{
- $xopt
- typeset ret=0
- typeset svc
-
- for svc in $SMF_ENABLE
- do
- is_enabled $svc
- eval ${svc}_enabled=$?
- ret=$((ret | ${svc}_enabled))
- done
-
- return $ret
-}
-
-#
-# Display which services are enabled. (Must be called after check_enabled)
-#
-show_enabled()
-{
- $xopt
- typeset svc
-
- echo "\nThe following Availability Suite services are enabled:"
-
- for svc in $SMF_ENABLE
- do
- if (( ${svc}_enabled == 1 ))
- then
- printf "$svc "
- fi
- done
-
- echo ""
-}
-
-
-#
-# check if the given SMF service is online (enabled)
-#
-# $1: service name to check for
-#
-is_enabled()
-{
- $xopt
- typeset en
-
- is_imported $1
- if [ $? = 1 ]
- then
- en=`svcprop -c -p general/enabled svc:/system/${1}:default`
- if [ $en = "true" ]
- then
- return 1
- fi
- fi
-
- return 0
-
-}
-
-#
-# If necessary, flag no dependency check
-#
-no_depend_check()
-{
- $xopt
- typeset pid
- typeset msg=0
-
- if [ $OS_MINOR -lt 11 ]
- then
- if [ -f $DSCFG_DEPEND_NOCHK ]
- then
- pid=`cat $DSCFG_DEPEND_NOCHK`
- echo "Another dscfgadm disable is in progress."
- echo "Waiting for pid: $pid to terminate..."
-
- while [ -f $DSCFG_DEPEND_NOCHK ]
- do
- if (( msg && (msg % 6 == 0)))
- then
- printf "\nAnother dscfgadm disable "
- printf "(pid: $pid) still appears to "
- printf " be in progress.\n"
- printf "If this is not the case, you "
- printf "may remove "
- printf "$DSCFG_DEPEND_NOCHK.\n"
- fi
- sleep 5
- msg=$((msg + 1))
- done
- fi
-
- touch $DSCFG_DEPEND_NOCHK
- echo $$ >> $DSCFG_DEPEND_NOCHK
- fi
-}
-
-#
-# If necessary, remove the no dependency check flag
-#
-rm_no_depend_check()
-{
- $xopt
- if [ $OS_MINOR -lt 11 ]
- then
- rm -f $DSCFG_DEPEND_NOCHK
- fi
-}
-
-#
-# set the filesystem/local dependency type and refresh
-#
-# $1: service name
-# $2: either "require_all" or "optional_all"
-#
-set_fs_local_grouping()
-{
- $xopt
- typeset svc=$1
- typeset dep_group=$2
-
- # set proper dependency type for fs-local
- if [ $svc != nws_rdcsyncd ]; then
- svccfg -s $FS_LOCAL_SVC setprop \
- ${svc}-local-fs/grouping=$dep_group
- if [ $? -ne 0 ]
- then
- printf "command failed: svccfg -s $FS_LOCAL_SVC "
- printf "setprop ${svc}-local-fs/grouping=$dep_group "
- printf ">&2\n"
- return 1
- fi
-
- # we need local-fs to know about the new grouping attributes
- svcadm refresh ${FS_LOCAL_SVC}:default
- if [ $? -ne 0 ]
- then
- print "Failed to refresh ${FS_LOCAL_SVC} >&2"
- return 1
- fi
- fi
-
- return 0
-}
-
-#
-# check if the grouping dependency type for filesystem/local is correct
-#
-# input:
-# $1: service name
-#
-# returns:
-# 0 if the setting is correct
-# 1 if the setting is incorrect
-# outputs: sets CORRECT_GROUPING with the value of what the grouping should be.
-#
-check_fs_local_grouping()
-{
- $xopt
- typeset svc=$1
- typeset cur_grouping
-
- if [ $svc = nws_rdcsyncd ]
- then
- return 0
- fi
-
- # If it's not imported, we just return success, since we don't want
- # further processing
- is_imported $svc
- if [ $? = 0 ]
- then
- return 0
- fi
-
- # get the current grouping value from the repository
- cur_grouping=`svcprop -c -p ${svc}-local-fs/grouping $FS_LOCAL_SVC`
-
- # Figure out what the grouping should be (based on enabled status)
- is_enabled $svc
- if [ $? = 1 ]
- then
- CORRECT_GROUPING="require_all"
- else
- CORRECT_GROUPING="optional_all"
- fi
-
- if [ "$cur_grouping" != "$CORRECT_GROUPING" ]
- then
- # grouping is incorrect
- return 1
- else
- # grouping is just fine
- return 0
- fi
-}
-
-#
-# enable/disable the given SMF service. Also, update the filesystem-local
-# dependency, if appropriate.
-#
-# $1: service name to check for
-# $2: "enable" or "disable"
-#
-svc_operation()
-{
- $xopt
- typeset svc=$1
- typeset command=$2
- typeset enable_state
- typeset dep_group
-
- # If disabling, then enable_state better be true, and we are
- # transitioning to "option_all" grouping
- if [ $command = "disable" ]
- then
- enable_state=1
- dep_group="optional_all"
-
- # If enabling, then enable_state better be false, and we are
- # transitioning to "require_all" grouping
- elif [ $command = "enable" ]
- then
- enable_state=0
- dep_group="require_all"
- else
- echo "invalid command: $command" >&2
- fi
-
- is_imported $svc
- if [ $? = 1 ]
- then
- is_enabled $svc
- if [ $? = $enable_state ]
- then
- if [ $enable_state -eq 1 ]
- then
- # we're doing a disable--remove hard dependency
- set_fs_local_grouping $svc $dep_group
- if [ $? -ne 0 ]
- then
- return 1
- fi
- fi
-
- svcadm $command -s svc:/system/$svc
- if [ $? != 0 ]
- then
- echo "$svc failed to $command" >&2
- return 1
- fi
-
- if [ $enable_state -eq 0 ]
- then
- # we just did an enable--create hard dependency
- set_fs_local_grouping $svc $dep_group
- if [ $? -ne 0 ]
- then
- return 1
- fi
- fi
-
- else
- echo "$svc service already ${command}d... skipping"
- fi
- fi
-
- return 0
-}
-
-#
-# This chart summarizes the behavior of the -r and -p sub-options for the
-# -e and -d options.
-# There are 5 possible states, and 5 transitions out of each state.
-#
-# states: (vertical axis)
-# -------
-# 0: no services enabled
-# C: one or both core services enabled (illegal state)
-# R: both core services and RM services enabled
-# P: both core services and PITC service enabled
-# A: all services enabled
-#
-# transitions: (horizontal axis)
-# ------------
-# +/-a: enable/disable, respectively, with neither -r nor -p
-# +/-r: enable/disable, respectively, with -r flag
-# +p: enable with -p flag
-#
-# The result of the function is the next state after the action has been
-# successfully performed.
-#
-# +a | -a | +r | -r | +p |
-# ++----+----+----+----+----+
-# ++----+----+----+----+----+
-# 0 || A | 0* | R | 0* | P |
-# --++----+----+----+----+----+
-# C || A* | 0* | R | 0 | P |
-# --++----+----+----+----+----+
-# R || A* | 0* | R* | 0 | A |
-# --++----+----+----+----+----+
-# P || A* | 0* | A* | P* | P* |
-# --++----+----+----+----+----+
-# A || A* | 0 | A* | P | A* |
-# --++----+----+----+----+----+
-#
-# *: warning message is displayed, stating that a service is already
-# enabled/disabled.
-#
-
-# enable the SMF services needed for the Availability Suite
-#
-enable_services()
-{
- $xopt
- typeset svc
-
- # first, import them if they have not yet been imported
- import_services
-
- # if neither r_flag nor p_flag is set, enable all services
- if (( (r_flag | p_flag) == 0 ))
- then
- for svc in $SMF_ENABLE
- do
- if ! svc_operation $svc enable
- then
- return 1
- fi
- done
- else
- # figure out which services are enabled
- check_enabled
-
- # First, make sure both core services are enabled
- for svc in nws_scm nws_sv
- do
- if (( ${svc}_enabled == 0 )) && \
- ! svc_operation $svc enable
- then
- return 1
- fi
- done
-
- if ((p_flag))
- then
- if ! svc_operation nws_ii enable
- then
- return 1
- fi
- fi
-
- if ((r_flag))
- then
- for svc in nws_rdc nws_rdcsyncd
- do
- if ! svc_operation $svc enable
- then
- return 1
- fi
- done
- fi
-
- fi
-
- return 0
-}
-
-#
-# disable the SMF services needed for the Availability Suite
-#
-disable_services()
-{
- $xopt
- typeset svc
-
- check_device_groups
- if [ $? == 1 ]
- then
- return 1
- fi
-
- # This flags the shutdown scripts to not check to make sure the
- # services' dependents have been disabled. The flag must be removed
- # before returning from this function.
- no_depend_check
-
- # NB: p_flag is not allowed for disables. II should not be
- # disabled if sndr is enabled. If rdc is not enabled, disabling just
- # II is equivalent to disabling all the remaining services.
-
- # If no flags passed in, just disable everything
- if (( r_flag == 0 ))
- then
- for svc in $SMF_DISABLE
- do
- if ! svc_operation $svc disable
- then
- rm_no_depend_check
- return 1
- fi
- done
-
- # Now that we've disable the services, lets unload them
- # from the Solaris kernel
- #
- modinfo | grep '(nws:' | grep -v "kRPC Stub" | sort -r | cut -d' ' -f1 | xargs -l modunload -i 2>/dev/null
- modinfo | grep '(nws:' | grep -v "kRPC Stub" | sort -r | cut -d' ' -f1 | xargs -l modunload -i 2>/dev/null
- else
- # we're disabling just rdc. If II is not already enabled,
- # we disable core services, as well.
-
- # figure out which services are enabled
- check_enabled
-
- for svc in nws_rdcsyncd nws_rdc
- do
- if ! svc_operation $svc disable
- then
- rm_no_depend_check
- return 1
- fi
- done
-
- if (( nws_ii_enabled == 0 ))
- then
- for svc in nws_sv nws_scm
- do
- if ((${svc}_enabled)) && \
- ! svc_operation $svc disable
- then
- rm_no_depend_check
- return 1
- fi
- done
- fi
- fi
-
-
- rm_no_depend_check
- return 0
-}
-
-#
-# check if a service has been imported into the repository
-# $1: service to check
-# returns 1 if it is imported, 0 if it is not
-#
-is_imported()
-{
- $xopt
-
- typeset svc=$1
-
- svcprop -q -p general/entity_stability svc:/system/${svc}
- if [ $? = 1 ]
- then
- return 0
- else
- return 1
- fi
-}
-
-#
-# import the SMF services into the repository, if necessary
-#
-import_services()
-{
- $xopt
- typeset svc
-
- for svc in $SMF_ENABLE
- do
- import_service $svc
- done
-}
-
-#
-# check to see if an SMF service is in the repository. If it is not,
-# import it in.
-# $1: name of service to import
-#
-import_service()
-{
- $xopt
- typeset svc=$1
-
- is_imported $svc
- if [ $? = 0 ]
- then
- if [ -f $PKG_INSTALL_ROOT/$MANIFEST_PATH/$svc.xml ]
- then
- svccfg import $PKG_INSTALL_ROOT/$MANIFEST_PATH/$svc.xml
-
- if [ $OS_MINOR -lt 11 ]
- then
- # workaround for 6221374--let local-fs know
- # that it depends on us.
- svcadm refresh ${FS_LOCAL_SVC}:default
- fi
- fi
- fi
-}
-
-
-########################## MAIN ######################################
-
-# getopt processing
-enable=0
-disable=0
-set_location=0
-get_info=0
-r_flag=0
-p_flag=0
-while getopts "xedsirp" opt 2>/dev/null
-do
- case $opt in
- \?)
- help
- ;;
- e)
- enable=1
- ;;
- d)
- disable=1
- ;;
- x)
- xopt="set -x"
- set -x
- ;;
- s)
- set_location=1
- ;;
- i)
- get_info=1
- ;;
- r)
- r_flag=1
- ;;
- p)
- p_flag=1
- ;;
- esac
-done
-
-# at most one option (besides -x) may be specified at a time
-options_count=$((enable + disable + set_location + get_info))
-if [ $options_count -gt 1 ]
-then
- help
-elif [ $options_count = 0 ]
-then
- NO_ARGS=1
-fi
-
-if (( ((r_flag + p_flag) > 0) && ((enable | disable) == 0) ))
-then
- echo "-r and -p options may only be used with -d or -e options" >&2
- return 1
-elif (( p_flag && disable ))
-then
- echo "The -p option may not be used with the -d option" >&2
- return 1
-fi
-
-
-
-# set all the system information variables
-get_system_state
-
-# if we're enabling, we need to make sure we have a valid dscfg out there.
-if [ $enable = 1 -a $VALID_LOCAL_DB != 1 ]
-then
- echo "Cannot find a valid configuration database" >&2
- return 1
-fi
-
-if [ $NO_ARGS = 1 ]
-then
-
- # only initialize the database if necessary
- if [ $VALID_LOCAL_DB = 1 ]; then
- echo "Local configuration database is already initialized."
- else
- initialize_local_db
- if [ $? != 0 ]; then
- return 1
- fi
- fi
-
- if [ $CLUSTER_CONFIGURED = 1 ]
- then
- if [ $VALID_CLUSTER_DB = 1 ]; then
- printf "Cluster configuration database is already "
- printf "initialized.\n"
- else
- # ask the user for a cluster database location
- set_cluster_config
-
- # initialize the new db
- initialize_cluster_db
- if [ $? != 0 ]; then
- return 1
- fi
- fi
-
- fi
-
- # make sure that the local filesystem dependency type is correct
- for svc in $SMF_ENABLE
- do
- check_fs_local_grouping $svc
- if [ $? -ne 0 ]
- then
- # NOTE: check_fs_local_grouping sets CORRECT_GROUPING
- # To avoid this issue in the future, always administer
- # the services using dscfgadm.
- printf "Warning: Fixing dependency for $svc.\n"
- set_fs_local_grouping $svc $CORRECT_GROUPING
- if [ $? -ne 0 ]
- then
- return 1
- fi
- fi
- done
-
- # give the user the chance to startup AVS services, if not started
- check_enabled
- if [ $? = 1 ]; then
- if [ $OLD_VALID_LOCAL_DB = 0 ]; then
- printf "WARNING: AVS services are running on a system "
- printf "which had no valid configuration\ndatabase\n"
- fi
- show_enabled
- else
- ask_to_enable
- if [ $? = 1 ]; then
- enable_services
- if [ $? != 0 ]
- then
- return 1
- fi
- fi
- fi
-
-elif [ $enable = 1 ]
-then
- enable_services
- if [ $? != 0 ]
- then
- return 1
- fi
-
-elif [ $disable = 1 ]
-then
- disable_services
- if [ $? != 0 ]
- then
- return 1
- fi
-
-elif [ $get_info = 1 ]
-then
- display_info
-
-elif [ $set_location = 1 ]
-then
- if [ $CLUSTER_CONFIGURED = 1 ]
- then
- # ask the user for a cluster database location
- set_cluster_config
-
- # initialize the new db
- initialize_cluster_db
- if [ $? != 0 ]; then
- return 1
- fi
- else
- echo "$PROG -s is only available on Sun Cluster OE systems" >&2
- return 1
- fi
-fi
-
-return 0
-
-
-########################## MAIN ######################################
-
diff --git a/usr/src/cmd/avs/dscfg/etc/Makefile b/usr/src/cmd/avs/dscfg/etc/Makefile
deleted file mode 100644
index 725c36deac..0000000000
--- a/usr/src/cmd/avs/dscfg/etc/Makefile
+++ /dev/null
@@ -1,44 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-include ../../../Makefile.cmd
-
-ETCFILES = dscfg_format
-
-FILEMODE = 0744
-
-ROOTETCFILES= $(ETCFILES:%=$(ROOTETC)/%)
-
-.KEEP_STATE:
-
-all: $(ETCFILES)
-
-install: $(ROOTETCFILES)
-
-clean:
-
-clobber:
-
-lint:
-
-FRC:
diff --git a/usr/src/cmd/avs/dscfg/etc/dscfg_format b/usr/src/cmd/avs/dscfg/etc/dscfg_format
deleted file mode 100644
index fec9d86d43..0000000000
--- a/usr/src/cmd/avs/dscfg/etc/dscfg_format
+++ /dev/null
@@ -1,72 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# Default parser configuration file
-#
-# Lines starting `#' are comments, lines starting `%' are descriptive
-# text to be printed by dscfg -l, all other lines are parser rules.
-#
-# Descriptive text should be directly above the parser rule it relates to.
-#
-% Availability Suite - dscfg configuration database
-%
-% Storage Cache Manager - scmadm
-% threads csiz wrtcache filpat reserved1 niobuf ntdaemon fwrthru nofwrthru
-scm.thread.size.write_cache.fill_pattern.reserved1.iobuf.tdemons.forced_wrthru.no_forced_wrthru
-%
-% Cache Hints - scmadm
-% device wrthru nordcache
-cache_hint.device.wrthru.nordcache
-%
-% Point-in-Time Copy - iiadm
-% master shadow bitmap mode(D|I) [overflow] [device-group] [options] [group]
-ii.master.shadow.bitmap.mode.overflow.cnode.options.group
-%
-% Remote Mirror (internal) SetId
-% setid [device-group]
-setid.value.cnode
-%
-% Remote Mirror - sndradm
-% p_host p_dev p_bmp s_host s_dev s_bmp protocol(ip/fcal_device) mode \
-% [group] [device-group] [options] [diskq]
-sndr.phost.primary.pbitmap.shost.secondary.sbitmap.type.mode.group.cnode.options.diskq
-%
-% Remote Mirror - Point-in-Time mapping
-% SNDR-secondary II-shadow II-bitmap state [device-group]
-ndr_ii.secondary.shadow.bitmap.state.cnode
-%
-% Bitmap filesystem to mount before other filesystems
-% pathname_or_special_device [resource-group]
-bitmaps.bitmap.cnode
-%
-% Storage volumes - svadm
-% pathname [mode] [device-group]
-sv.vol.mode.cnode
-%
-% Ncall Core
-% nodeid [device-group]
-ncallcore.nodeid.cnode
-%
-% DsVol - volume usage
-% volume [device-group] users
-dsvol.path.cnode.users
diff --git a/usr/src/cmd/avs/dscfglockd/Makefile b/usr/src/cmd/avs/dscfglockd/Makefile
deleted file mode 100644
index 3d7c3e008e..0000000000
--- a/usr/src/cmd/avs/dscfglockd/Makefile
+++ /dev/null
@@ -1,84 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-DYNPROG = dscfglockd dscfgcli
-
-include ../../Makefile.cmd
-include ../Makefile.com
-
-PROG = $(DYNPROG)
-
-dscfglockd := POBJS = dscfglockd.o
-
-dscfgcli := POBJS = dscfgcli.o
-
-OBJS= dscfglockd.o dscfgcli.o
-SRCS= $(OBJS:%.o=%.c)
-POFILES= $(OBJS:%.o=%.po)
-
-dscfgcli := LDLIBS += -ldscfg -lnsl
-dscfglockd := LDLIBS += -lunistat -ldscfg -lsocket -lnsl
-
-CFLAGS += $(CCVERBOSE) -D_RDC_ -D_SYSCALL32
-CERRWARN += -_gcc=-Wno-switch
-LINTFLAGS += -Xa -n -s -x -m -u -Dlint -errhdr=%user -D_RDC_ -D_SYSCALL32
-LINTFLAGS += -DDEBUG -erroff=E_SEC_SCANF_UNBOUNDED_COPY
-LINTDIR = $(KBASE)/lintdir
-POFILE = dscfglockd_all.po
-LFILE = $(LINTDIR)/rdc.ln
-ROOTLINK = $(ROOTLIB)/dscfglockd
-
-all := TARGET= all
-install := TARGET= install
-clean := TARGET= clean
-clobber := TARGET= clobber
-lint := TARGET= lint
-
-.KEEP_STATE:
-
-.PARALLEL: $(OBJS)
-
-all: $(SUBDIRS) $(PROG) $(POFILES)
-
-install: $(SUBDIRS) all $(ROOTPROG) $(ROOTLINK)
-
-lint: $(SUBDIRS) lint_SRCS
-
-clean: $(SUBDIRS)
- $(RM) *.o $(POFILES)
-
-$(POFILE): $(POFILES)
- $(RM) $@
- $(CAT) $(POFILES) > $@
-
-$(PROG): $$(POBJS)
- $(LINK.c) $(POBJS) -o $@ $(LDLIBS)
- $(POST_PROCESS)
-
-$(ROOTLINK): $(ROOTLIB) $(ROOTBIN)/dscfglockd
- -$(RM) $@; $(LN) $(ROOTBIN)/dscfglockd $@
-
-FRC:
-
-include ../../Makefile.targ
diff --git a/usr/src/cmd/avs/dscfglockd/dscfgcli.c b/usr/src/cmd/avs/dscfglockd/dscfgcli.c
deleted file mode 100644
index 9fd71e8b98..0000000000
--- a/usr/src/cmd/avs/dscfglockd/dscfgcli.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <signal.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <locale.h>
-#include <sys/nsctl/cfg.h>
-
-CFGFILE *cfg;
-void cfg_lockd_stat();
-int tty;
-
-static void
-test(int count)
-{
- struct stat sb;
- int i;
-
- if (count < 1)
- count = 1;
- for (i = 0; count-- > 0; i++) {
- if (cfg_lock(cfg, CFG_RDLOCK) < 0)
- (void) printf("CFG_RDLOCK error\n");
- else
- (void) fstat(0, &sb);
-
- cfg_unlock(cfg);
- (void) fstat(1, &sb);
-
- if (cfg_lock(cfg, CFG_RDLOCK) < 0)
- (void) printf("CFG_RDLOCK error\n");
- else
- (void) fstat(0, &sb);
-
- cfg_unlock(cfg);
- (void) fstat(1, &sb);
-
- if (cfg_lock(cfg, CFG_WRLOCK) < 0)
- (void) printf("CFG_WRLOCK error\n");
- else
- (void) fstat(0, &sb);
-
- cfg_unlock(cfg);
- (void) fstat(1, &sb);
-
- if (i > 0) {
- if (i % 100 == 0)
- (void) write(1, "+", 1);
- if (i % 5000 == 0)
- (void) write(1, "\n", 1);
- }
- }
- (void) printf("\nTest complete\n");
-}
-
-static void
-cmd_loop()
-{
- char host[1024];
- char buffer[1024];
- int i;
-
- (void) gethostname(host, sizeof (host));
- for (;;) {
- if (tty)
- (void) printf(":%s: ", host);
- (void) fgets(buffer, sizeof (buffer), stdin);
- switch (tolower(buffer[0])) {
- case 'p':
- i = atoi(buffer + 1);
- (void) sleep(i);
- break;
- case 'q':
- exit(0);
- break;
- case 'r':
- if (cfg_lock(cfg, CFG_RDLOCK) < 0)
- (void) printf("CFG_RDLOCK error\n");
- break;
- case 's':
- cfg_lockd_stat();
- break;
- case 't':
- i = atoi(buffer + 1);
- test(i);
- break;
- case 'u':
- cfg_unlock(cfg);
- break;
- case 'w':
- if (cfg_lock(cfg, CFG_WRLOCK) < 0)
- (void) printf("CFG_WRLOCK error\n");
- break;
- default:
- (void) printf("don't understand %s\n", buffer);
- break;
- }
- }
-}
-
-static void
-init()
-{
- tty = isatty(0);
- if (tty)
- (void) printf("dscfglockd cli %s\n", "07/06/12");
- if ((cfg = cfg_open(NULL)) == NULL) {
- perror("cfg_open");
- exit(1);
- }
-}
-
-int
-main(void)
-{
- init();
- cmd_loop();
- return (0);
-}
diff --git a/usr/src/cmd/avs/dscfglockd/dscfglockd.c b/usr/src/cmd/avs/dscfglockd/dscfglockd.c
deleted file mode 100644
index 578c38f15e..0000000000
--- a/usr/src/cmd/avs/dscfglockd/dscfglockd.c
+++ /dev/null
@@ -1,1371 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <signal.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <fcntl.h>
-#include <string.h>
-#include <memory.h>
-#include <sys/param.h>
-#include <sys/pathconf.h>
-#include <netdir.h>
-#include <netconfig.h>
-#include <sys/sockio.h>
-#include <net/if.h>
-#include <sys/resource.h>
-#include <stdio.h>
-#include <errno.h>
-#include <assert.h>
-#include <locale.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_u.h>
-#include <sys/unistat/spcs_errors.h>
-
-#include <sys/nsctl/cfg.h>
-#include <sys/nsctl/cfg_lockd.h>
-
-#ifdef DEBUG
-#define DPF(m) if (debug) (void) fprintf m
-#else
-#define DPF(m)
-#endif
-
-#ifdef TTY_MESSAGES
-#define CLOSE_FD 3
-#else
-#define CLOSE_FD 0
-#endif
-
-#define MAX_LOCKQ 1024
-#define MAX_DAEMONS 1024
-#define MAX_LOCAL 1024
-#define MAX_UNLOCK 32
-#define MAX_TIMEOUTS 3
-#define TIMEOUT_SECS 5
-
-static char program[] = "dscfglockd";
-static int debug;
-static int lstate;
-static int msgtrace;
-static FILE *debugfile = NULL;
-
-struct lock_req {
- cfglockd_t type; /* read or write */
- pid_t pid; /* pid of read locker or local writer */
- daemonaddr_t remote; /* remote machine requesting write lock */
- int state; /* for write locks */
- int32_t order; /* who gets priority? */
-} lock_queue[MAX_LOCKQ];
-
-struct unlock_s {
- pid_t pid; /* pid of locker */
- uint8_t seq; /* seq number of last lock request */
-} unlock_buf[MAX_UNLOCK];
-
-int next_req;
-int32_t order;
-
-#define lock_wanted lock_queue[0]
-long ticker = 1l;
-
-#define ALIVE 0x10
-#define READ_LOCK 0x11
-#define WRITE_LOCK 0x12
-#define UNLOCK 0x13
-#define GRANTED 0x14
-
-int next_q;
-
-struct {
- cfglockd_t type;
- int nholders;
- int state;
- daemonaddr_t holder;
- struct lockdaemon *remote_daemon;
- pid_t holding_pid[MAX_LOCAL];
-} the_lock;
-
-daemonaddr_t thishost;
-daemonaddr_t localhost;
-
-#define STATE_CLEAR 0
-#define STATE_ASKED 1
-#define STATE_OKAYED 2
-#define STATE_WANTS 3
-#define lockdaemon_dead(ldp) ((ticker - (ldp)->timeout) > MAX_TIMEOUTS)
-#define CRIT_BEGIN() (void) sighold(SIGALRM)
-#define CRIT_END() (void) sigrelse(SIGALRM)
-
-#define NORMAL_UNLOCK 0
-#define FORCE_UNLOCK 1
-
-struct lockdaemon {
- daemonaddr_t host;
- int up;
- long timeout;
- int inuse;
- int state;
- int32_t order;
-} daemon_list[MAX_DAEMONS];
-
-unsigned short lock_port = CFG_SERVER_PORT;
-int lock_soc = 0;
-int pf_inet = PF_INET;
-#define dp_addr(p) inet_ntoa(((struct sockaddr_in *)p)->sin_addr)
-
-#define MAXIFS 32
-
-static char *
-lockd_type(cfglockd_t type)
-{
- switch (type) {
- case LOCK_NOTLOCKED: return "NotLocked";
- case LOCK_READ: return "Read";
- case LOCK_WRITE: return "Write";
- case LOCK_LOCKED: return "Locked";
- case LOCK_LOCKEDBY: return "LockedBy";
- case LOCK_STAT: return "Stat";
- case LOCK_ACK: return "Ack";
- default: return "*unknown*";
- }
-}
-
-static char *
-lockd_state(int state)
-{
- switch (state) {
- case STATE_CLEAR: return "Clear";
- case STATE_ASKED: return "Asked";
- case STATE_OKAYED: return "Okayed";
- case STATE_WANTS: return "Wants";
- default: return "*unknown*";
- }
-}
-
-static char *
-lockd_msg(int message)
-{
- switch (message) {
- case ALIVE: return "Alive";
- case READ_LOCK: return "ReadLock";
- case WRITE_LOCK: return "WriteLock";
- case UNLOCK: return "Unlock";
- case GRANTED: return "Granted";
- default: return lockd_type((cfglockd_t)message);
- }
-}
-
-/*
- * The following is stolen from autod_nfs.c
- */
-static void
-getmyaddrs(struct ifconf *ifc)
-{
- int sock;
- int numifs;
- char *buf;
- int family;
-
- ifc->ifc_buf = NULL;
- ifc->ifc_len = 0;
-
-#ifdef AF_INET6
- family = AF_INET6;
-#else
- family = AF_INET;
-#endif
- if ((sock = socket(family, SOCK_DGRAM, 0)) < 0) {
-#ifdef DEBUG
- perror("getmyaddrs(): socket");
-#endif
- return;
- }
-
- if (ioctl(sock, SIOCGIFNUM, (char *)&numifs) < 0) {
-#ifdef DEBUG
- perror("getmyaddrs(): SIOCGIFNUM");
-#endif
- numifs = MAXIFS;
- }
-
- buf = (char *)malloc(numifs * sizeof (struct ifreq));
- if (buf == NULL) {
-#ifdef DEBUG
- (void) fprintf(stderr, "getmyaddrs(): malloc failed\n");
-#endif
- (void) close(sock);
- return;
- }
-
- ifc->ifc_buf = buf;
- ifc->ifc_len = numifs * sizeof (struct ifreq);
-
- if (ioctl(sock, SIOCGIFCONF, (char *)ifc) < 0) {
-#ifdef DEBUG
- perror("getmyaddrs(): SIOCGIFCONF");
-#endif
- }
-
- (void) close(sock);
-}
-
-struct ifconf *ifc;
-
-static int
-cmp_addr(daemonaddr_t *a, daemonaddr_t *b)
-{
- int rc;
- rc = memcmp(&(a->sin_addr), &(b->sin_addr), sizeof (a->sin_addr));
- DPF((stderr, "compare %s %hu with", dp_addr(a), a->sin_port));
- DPF((stderr, " %s %hu = %d\n", dp_addr(b), b->sin_port, rc));
- return (rc);
-}
-
-static int
-addr_is_holder(int32_t order)
-{
- return ((the_lock.nholders > 0) && the_lock.remote_daemon != NULL &&
- (order == the_lock.remote_daemon->order));
-}
-
-static int
-islocalhost(daemonaddr_t *host)
-{
- int n;
- struct sockaddr_in *s1, *s2;
- struct ifreq *ifr;
- int retval = 0;
-
- ifr = ifc->ifc_req;
- n = ifc->ifc_len / sizeof (struct ifreq);
- s1 = host;
- s2 = NULL;
- for (; n > 0; n--, ifr++) {
- if (ifr->ifr_addr.sa_family != AF_INET)
- continue;
-
- /* LINTED pointer alignment */
- s2 = (struct sockaddr_in *)&ifr->ifr_addr;
-
- if (memcmp((char *)&s2->sin_addr,
- (char *)&s1->sin_addr, sizeof (s1->sin_addr)) == 0) {
- retval = 1;
- /* it's me */
- break;
- }
- }
- return (retval);
-}
-
-static void
-send_lockmsg(int cmd, pid_t pid, daemonaddr_t *dp, uint8_t seq)
-{
- struct lock_msg message_buf;
- int rc;
-
- if (msgtrace && debugfile) {
- time_t t = time(0);
- (void) fprintf(debugfile, "%19.19s send %-9.9s to %s\n",
- ctime(&t), lockd_msg(cmd), dp_addr(dp));
- }
- DPF((stderr, "send %d to %s port %hu\n", cmd,
- dp_addr(dp), dp->sin_port));
- message_buf.message = cmd;
- message_buf.pid = pid;
- message_buf.order = order;
- message_buf.seq = seq;
- do {
- rc = sendto(lock_soc, &message_buf, sizeof (message_buf), 0,
- (struct sockaddr *)dp, sizeof (struct sockaddr));
- } while (rc == -1 && errno == EINTR);
- if (rc == -1)
- spcs_log("cfglockd", NULL, "sendto rc -1 errno %d", errno);
-}
-
-/*
- * send an alive message to all configured daemons so that they can tell
- * us if they are holding a write lock.
- */
-
-static void
-send_aliveall()
-{
- struct lockdaemon *ldp;
- int i;
- for (i = 0, ldp = daemon_list; i < MAX_DAEMONS; i++, ldp++) {
- if (ldp->inuse == 0)
- break;
- send_lockmsg(ALIVE, (pid_t)0, &(ldp->host), 0);
- }
-}
-
-/* find the lock daemon structure for a give daemon address */
-
-static struct lockdaemon *
-find_lockdaemon(daemonaddr_t *d)
-{
- struct lockdaemon *ldp;
- int i;
- for (i = 0, ldp = daemon_list; i < MAX_DAEMONS; i++, ldp++) {
- if (ldp->inuse == 0)
- break;
- if (cmp_addr(&(ldp->host), d) == 0)
- return (ldp);
- }
- return (NULL);
-}
-
-/*
- * a messge has been received from daemon, note this and if the daemon
- * was previously dead and we have the write lock tell it that we do.
- */
-
-static void
-daemon_alive(daemonaddr_t *daemon, int32_t order)
-{
- struct lockdaemon *ldp;
- int i;
-
- for (i = 0, ldp = daemon_list; i < MAX_DAEMONS; i++, ldp++) {
- if (ldp->inuse == 0)
- break;
- if (cmp_addr(&(ldp->host), daemon) == 0) {
- ldp->order = order;
- ldp->timeout = ticker;
- if (ldp->up == 0) {
- spcs_log("cfglockd", NULL,
- "daemon restarted on %s\n",
- dp_addr(daemon));
- DPF((stderr, "daemon restarted on %s\n",
- dp_addr(daemon)));
- ldp->up = 1;
- goto come_up;
- }
- return;
- }
- }
- /* new daemon has announced itself */
- if (i < MAX_DAEMONS) {
- DPF((stderr, "new daemon on %s\n", dp_addr(daemon)));
- spcs_log("cfglockd", NULL,
- "new daemon on %s\n", dp_addr(daemon));
- ldp->host = *daemon;
- ldp->inuse = 1;
- ldp->timeout = ticker;
- ldp->order = order;
- } else {
- /* problem, more daemons than expected */
- i++;
- }
-come_up:
- if (the_lock.type == LOCK_WRITE && the_lock.remote_daemon == NULL)
- send_lockmsg(WRITE_LOCK, (pid_t)0, daemon, 0);
-}
-
-static void
-delete_queue_entry(struct lock_req *req)
-{
- int i;
-
- for (i = (req - lock_queue); i++ < next_req; req++)
- *req = *(req+1);
- next_req--;
-}
-
-static void
-take_lock(int ackmessage)
-{
- send_lockmsg(ackmessage, (pid_t)0, &lock_wanted.remote, 0);
- delete_queue_entry(lock_queue);
-}
-
-static void
-check_for_write_lock()
-{
- struct lockdaemon *ldp;
- int i;
- int wait = 0;
-
- DPF((stderr, "check for lock\n"));
- if (lock_wanted.state != STATE_ASKED)
- return;
- for (i = 0, ldp = daemon_list; i < MAX_DAEMONS; i++, ldp++) {
- if (ldp->inuse == 0)
- break;
- if (ldp->up && ldp->state != STATE_OKAYED) {
- wait = 1;
- break;
- }
- }
- if (wait == 0 && lock_wanted.type == LOCK_WRITE) {
- the_lock.type = LOCK_WRITE;
- the_lock.holding_pid[0] = lock_wanted.pid;
- the_lock.nholders = 1;
- the_lock.state = STATE_CLEAR;
- take_lock(LOCK_LOCKED);
- }
-}
-
-static void
-lock_granted(daemonaddr_t *da)
-{
- struct lockdaemon *ldp;
-
- if ((ldp = find_lockdaemon(da)) != NULL) {
- /* if we already own the lock, throw the msg away */
- if (the_lock.remote_daemon == NULL &&
- the_lock.type == LOCK_WRITE) {
- return;
- }
-
- /*
- * If the current lock isn't a write lock and we're not
- * asking for one
- * -OR-
- * The current lock is a write lock and it's not owned by us
- * -THEN-
- * send back an unlocked message.
- */
- if ((the_lock.type != LOCK_WRITE &&
- the_lock.state != STATE_ASKED) ||
- (the_lock.type == LOCK_WRITE &&
- the_lock.remote_daemon != NULL)) {
- send_lockmsg(UNLOCK, (pid_t)0, &(ldp->host), 0);
- return;
- }
- ldp->state = STATE_OKAYED;
- }
- check_for_write_lock();
-}
-
-static int
-try_lock()
-{
- struct lockdaemon *ldp;
- int i;
-
- switch (the_lock.type) {
- case LOCK_READ:
- if (lock_wanted.type == LOCK_READ) {
- i = the_lock.nholders++;
- the_lock.holding_pid[i] = lock_wanted.pid;
- the_lock.state = STATE_CLEAR;
- DPF((stderr, "increment read lockers to %d\n",
- the_lock.nholders));
- take_lock(LOCK_LOCKED);
- break;
- }
- /* write lock has to wait */
- break;
- case LOCK_WRITE:
- /* lock has to wait until write lock is cleared */
- break;
- case LOCK_NOTLOCKED:
- if (lock_wanted.type == LOCK_READ) {
- DPF((stderr, "local locker, 1 lock holder\n"));
- the_lock.holding_pid[0] = lock_wanted.pid;
- the_lock.nholders = 1;
- the_lock.type = LOCK_READ;
- the_lock.state = STATE_CLEAR;
- the_lock.remote_daemon = NULL;
- take_lock(LOCK_LOCKED);
- return (1);
- }
- if (islocalhost(&lock_wanted.remote)) {
- DPF((stderr, "local locker, take write lock\n"));
- /* tell everyone I'm locking */
- if (lock_wanted.state != STATE_ASKED) {
- for (i = 0, ldp = daemon_list; i < MAX_DAEMONS;
- i++, ldp++) {
- if (ldp->inuse == 0)
- break;
- ldp->state = STATE_ASKED;
- send_lockmsg(WRITE_LOCK, (pid_t)0,
- &(ldp->host), 0);
- }
- }
- lock_wanted.state = STATE_ASKED;
- check_for_write_lock();
- the_lock.remote_daemon = NULL;
- the_lock.state = STATE_ASKED;
- return (0);
- } else {
- DPF((stderr, "remote locker, take write lock\n"));
- the_lock.type = LOCK_WRITE;
- the_lock.holder = lock_wanted.remote;
- the_lock.nholders = 1;
- the_lock.remote_daemon =
- find_lockdaemon(&the_lock.holder);
- the_lock.state = STATE_CLEAR;
- /* okay to remote */
- take_lock(GRANTED);
- }
- break;
- default:
- DPF((stderr, "weird lock type held - %d\n", the_lock.type));
- the_lock.type = LOCK_NOTLOCKED;
- break;
- }
- return (0);
-}
-
-static void
-process_queue()
-{
- if (next_req < 1)
- return; /* no locks queued */
- while (try_lock())
- ;
-}
-
-static int
-lock_sort(const void *a, const void *b)
-{
- struct lock_req *left = (struct lock_req *)a;
- struct lock_req *right = (struct lock_req *)b;
-
- return (left->order - right->order);
-}
-
-static void
-queue_lock(cfglockd_t type, struct lock_msg *msg, daemonaddr_t *addr)
-{
- int i;
- struct lock_req *lrp;
- struct lockdaemon *ldp;
-
- /* first check if new lock matches current lock */
- if (the_lock.type == type && addr_is_holder(msg->order)) {
- /* remote daemon missed locked message */
- send_lockmsg(GRANTED, (pid_t)0, addr, msg->seq);
- return;
- }
-
- /* next search queue to check for duplicate */
- for (i = 0, lrp = lock_queue; i++ < next_req; lrp++) {
- if (lrp->type == type && lrp->pid == msg->pid &&
- cmp_addr(addr, &(lrp->remote)) == 0)
- return;
-
- }
-
- /*
- * It's a new lock request. Are we in the middle of
- * obtaining one for ourselves?
- */
-
- if (the_lock.type == LOCK_NOTLOCKED && the_lock.state == STATE_ASKED) {
- /* did a higher priority request just come in? */
- if (msg->order < order) {
- /* requeue our request */
- the_lock.state = STATE_CLEAR;
- lock_wanted.state = STATE_CLEAR;
-
- /* let the other lockds know */
- for (i = 0, ldp = daemon_list; i < MAX_DAEMONS;
- i++, ldp++) {
- if (ldp->inuse == 0)
- break;
- if (ldp->up && ldp->state == STATE_OKAYED) {
- send_lockmsg(UNLOCK, (pid_t)0,
- &(ldp->host), 0);
- }
- }
- }
- }
-
-
- lrp = lock_queue;
- lrp += (next_req++);
- lrp->type = type;
- lrp->pid = msg->pid;
- lrp->state = STATE_CLEAR;
- lrp->order = msg->order;
- if (addr) {
- lrp->remote = *addr;
- }
-
- if (next_req > 1)
- qsort(lock_queue, next_req, sizeof (lock_queue[0]), lock_sort);
-
- if (the_lock.type != LOCK_WRITE)
- process_queue();
-}
-
-static void
-lock_stat()
-{
- char *lt = "Unknown";
- struct lockdaemon *ldp;
- int i;
-
- switch (the_lock.type) {
- case LOCK_NOTLOCKED:
- lt = "not locked";
- break;
- case LOCK_READ:
- lt = "read locked";
- break;
- case LOCK_WRITE:
- lt = "write locked";
- break;
- }
- spcs_log("cfglockd", NULL, "Lock is %s (%d)", lt, the_lock.type);
- spcs_log("cfglockd", NULL, "There are %d holders of the lock",
- the_lock.nholders);
- if (the_lock.nholders > 0) {
- for (i = 0; i < the_lock.nholders; i++)
- spcs_log("cfglockd", NULL, "holding_pid[%d] = %6d", i,
- the_lock.holding_pid[i]);
- }
- spcs_log("cfglockd", NULL, "holder daemon was %s port %hu, remote %x",
- dp_addr(&the_lock.holder), the_lock.holder.sin_port,
- the_lock.remote_daemon);
- spcs_log("cfglockd", NULL, "Lock queue, %d requests", next_req);
- for (i = 0; i < next_req; i++) {
- spcs_log("cfglockd", NULL, "request %d type %d order %d", i,
- lock_queue[i].type, lock_queue[i].order);
- spcs_log("cfglockd", NULL, " client %s port %hu, pid %d",
- dp_addr(&lock_queue[i].remote),
- lock_queue[i].remote.sin_port, lock_queue[i].pid);
- }
- spcs_log("cfglockd", NULL, "Daemon list");
-
- for (i = 0, ldp = daemon_list; i < MAX_DAEMONS; i++, ldp++) {
- if (ldp->inuse == 0)
- break;
- spcs_log("cfglockd", NULL, "daemon %d, %s port %hu", i,
- dp_addr(&ldp->host), ldp->host.sin_port);
- spcs_log("cfglockd", NULL,
- " up %d timeout %ld missed %d state %d\n", ldp->up,
- ldp->timeout, ticker - ldp->timeout, ldp->state);
- }
-}
-
-static int
-is_duplicate(cfglockd_t type, pid_t pid, uint8_t seq)
-{
- struct unlock_s *bufp;
- int i;
-
- if (!pid) {
- return (0);
- }
-
- for (i = 0, bufp = unlock_buf; bufp->pid && i < MAX_UNLOCK;
- i++, bufp++) {
- if (bufp->pid == pid && bufp->seq == seq) {
- /* throw message away */
-#ifdef DEBUG
- spcs_log("cfglockd", NULL,
- "duplicate '%d' request received from %d",
- type, pid);
-#endif
- return (1);
- }
- }
-
- /* add it to the list */
- bcopy(unlock_buf, &unlock_buf[ 1 ],
- sizeof (unlock_buf) - sizeof (struct unlock_s));
- (*unlock_buf).pid = pid;
- (*unlock_buf).seq = seq;
-
- return (0);
-}
-
-static void
-local_lock(cfglockd_t type, struct lock_msg *msg, daemonaddr_t *client)
-{
- if (is_duplicate(type, msg->pid, msg->seq)) {
- if (the_lock.remote_daemon == NULL &&
- (the_lock.type == LOCK_WRITE ||
- the_lock.type == LOCK_READ) &&
- the_lock.holding_pid[0] == msg->pid) {
- send_lockmsg(LOCK_LOCKED, (pid_t)0, client, msg->seq);
- }
- } else {
- queue_lock(type, msg, client);
- }
-}
-
-static void
-remote_lock(struct sockaddr_in *remote, struct lock_msg *msg)
-{
- /* make sure remote knows we are alive */
- send_lockmsg(ALIVE, (pid_t)0, remote, 0);
-
- /* clear out pid as it is meaningless on this node */
- msg->pid = (pid_t)0;
-
- queue_lock(LOCK_WRITE, msg, (daemonaddr_t *)remote);
-}
-
-static void
-unqueue_lock(daemonaddr_t *d, pid_t pid)
-{
- int i;
- struct lock_req *lrp, *xrp;
- int diff;
-
- /* search queue to delete ungranted locks */
- for (i = 0, xrp = lrp = lock_queue; i++ < next_req; lrp++) {
- *xrp = *lrp;
- diff = 0;
- if (pid != (pid_t)0 && lrp->pid != pid)
- diff = 1;
- if (d != NULL && cmp_addr(d, &(lrp->remote)) != 0)
- diff = 1;
- if (!diff)
- continue;
-
- xrp++;
- }
- next_req = xrp - lock_queue;
-}
-
-static void
-xxunlock()
-{
- DPF((stderr, "** UNLOCK **\n"));
- the_lock.remote_daemon = NULL;
- the_lock.type = LOCK_NOTLOCKED;
- the_lock.nholders = 0;
- the_lock.state = STATE_CLEAR;
- process_queue();
-}
-
-
-static void
-local_unlock(pid_t pid, uint8_t seq, int method)
-{
- struct lockdaemon *ldp;
- int i;
-
- if (method == NORMAL_UNLOCK && is_duplicate(LOCK_NOTLOCKED, pid, seq)) {
- return;
- }
-
- if (the_lock.type == LOCK_READ) {
- /* delete reference to pid of reading process */
- for (i = 0; i < the_lock.nholders; i++) {
- if (the_lock.holding_pid[i] == pid) {
- DPF((stderr, "decrement lockers from %d\n",
- the_lock.nholders));
- --the_lock.nholders;
- break;
- }
- }
- for (; i < the_lock.nholders; i++) {
- the_lock.holding_pid[i] = the_lock.holding_pid[i+1];
- }
- if (the_lock.nholders > 0)
- return;
- } else {
- /* LOCK_WRITE */
- if (pid != the_lock.holding_pid[0])
- return;
- the_lock.holding_pid[0] = (pid_t)0;
- for (i = 0, ldp = daemon_list; i < MAX_DAEMONS; i++, ldp++) {
- if (ldp->inuse == 0)
- break;
- if (ldp->up)
- send_lockmsg(UNLOCK, (pid_t)0, &(ldp->host), 0);
- }
- }
- xxunlock();
-}
-
-static void
-remote_unlock(int32_t order, daemonaddr_t *d)
-{
- int i;
- struct lock_req *lrp;
-
- DPF((stderr, "remote unlock from %s ", dp_addr(d)));
- DPF((stderr, "when %s holds lock\n", dp_addr(&the_lock.holder)));
-
- /* search queue to check for ungranted lock */
- for (i = 0, lrp = lock_queue; i++ < next_req; lrp++) {
- if (lrp->type == LOCK_WRITE &&
- cmp_addr(d, &(lrp->remote)) == 0) {
- delete_queue_entry(lrp);
- return;
- }
-
- }
- if (addr_is_holder(order)) {
- xxunlock();
- }
-}
-
-static void
-lockedby(daemonaddr_t *d, uint8_t seq)
-{
- DPF((stderr, "lockby enquiry from %s ", dp_addr(d)));
- switch (the_lock.type) {
- case LOCK_NOTLOCKED:
- send_lockmsg(LOCK_NOTLOCKED, (pid_t)0, d, seq);
- break;
- case LOCK_READ:
- send_lockmsg(LOCK_READ, the_lock.holding_pid[0], d, seq);
- break;
- case LOCK_WRITE:
- send_lockmsg(LOCK_WRITE, the_lock.holding_pid[0], d, seq);
- break;
- }
-}
-
-/* ARGSUSED */
-static void
-keepalive(int signo)
-{
- int i;
- struct lock_req *locker;
- struct lockdaemon *ldp;
-
- DPF((stderr, "keepalive...\n"));
- ticker++;
-
- /*
- * tell any other daemon that has a lock request in our queue that
- * this daemon is still alive.
- */
-
- for (i = 0, locker = lock_queue; i < next_req; i++, locker++) {
- if (locker->pid == 0) /* remote lock request */
- send_lockmsg(ALIVE, (pid_t)0, &(locker->remote), 0);
- }
-
- /*
- * if a remote daemon holds the lock, check it is still alive and
- * if the remote daemon is sent it a grant message in case the
- * remote daemon missed our original grant.
- */
-
- if (the_lock.remote_daemon) {
- if (lockdaemon_dead(the_lock.remote_daemon)) {
- DPF((stderr, "lock owner died\n"));
- the_lock.remote_daemon->up = 0;
- xxunlock();
- } else {
- send_lockmsg(GRANTED, (pid_t)0, &the_lock.holder, 0);
- }
- }
-
- /*
- * check for response from daemons preventing this daemon
- * from taking a write lock by not sending a grant message.
- * if the remote daemon is alive send another lock request,
- * otherwise mark it as dead.
- * send alive message to any live remote daemons if this
- * daemon has the write lock.
- */
- if (lstate) {
- (void) printf("\nlock: %s\n", lockd_type(the_lock.type));
- (void) printf(" no. holders: %d\n", the_lock.nholders);
- (void) printf(" hold addr : %s\n", the_lock.remote_daemon?
- dp_addr(the_lock.remote_daemon): "0.0.0.0");
- (void) printf(" holding pid:");
- for (i = 0; i < the_lock.nholders; i++) {
- (void) printf(" %ld", the_lock.holding_pid[ i ]);
- }
- (void) printf("\n");
- }
- for (i = 0, ldp = daemon_list; i < MAX_DAEMONS; i++, ldp++) {
- if (ldp->inuse == 0)
- break;
-
- if (lstate) {
- (void) printf("%-15.15s ", dp_addr(&ldp->host));
- (void) printf("%-4.4s ", ldp->up? "up" : "down");
- (void) printf("%5ld ", ldp->timeout);
- (void) printf("%-10.10s ", lockd_state(ldp->state));
- (void) printf("%6d\n", ldp->order);
- }
-
- if (ldp->state == STATE_ASKED) {
- if (lockdaemon_dead(ldp)) {
- ldp->up = 0;
- ldp->state = STATE_CLEAR;
- continue;
- }
- send_lockmsg(WRITE_LOCK, (pid_t)0, &(ldp->host), 0);
- continue;
- }
- if (the_lock.type == LOCK_WRITE &&
- the_lock.remote_daemon == NULL)
- send_lockmsg(ALIVE, (pid_t)0, &(ldp->host), 0);
- }
-}
-
-static void
-dispatch(struct lock_msg *mp, daemonaddr_t *host)
-{
- int message = mp->message;
- int localhost;
-
- localhost = islocalhost(host);
- if (msgtrace && debugfile) {
- time_t t = time(0);
- if (localhost) {
- (void) fprintf(debugfile,
- "%19.19s recv %-9.9s from %s (%ld)\n", ctime(&t),
- lockd_msg(message), dp_addr(host), mp->pid);
- } else {
- (void) fprintf(debugfile,
- "%19.19s recv %-9.9s from %s order %d (%ld)\n",
- ctime(&t), lockd_msg(message), dp_addr(host),
- mp->order, mp->pid);
- }
- }
- DPF((stderr, "received message %d\n", message));
- DPF((stderr, "from %s port %hu\n", dp_addr(host), host->sin_port));
- if (!localhost)
- daemon_alive(host, mp->order);
- else
- mp->order = order;
- switch (message) {
- case ALIVE:
- DPF((stderr, "received ALIVE %s\n", dp_addr(host)));
- /* do nothing, general "not localhost" code above does this */
- break;
- case UNLOCK:
- DPF((stderr, "received UNLOCK\n"));
- remote_unlock(mp->order, host);
- break;
- case GRANTED:
- DPF((stderr, "received GRANTED\n"));
- lock_granted(host);
- break;
- case WRITE_LOCK:
- DPF((stderr, "received WRITE_LOCK\n"));
- assert(!localhost);
- remote_lock(host, mp);
- break;
- case READ_LOCK:
- case LOCK_READ:
- DPF((stderr, "received READ_LOCK\n"));
- assert(localhost);
- local_lock(LOCK_READ, mp, host);
- break;
- case LOCK_WRITE:
- DPF((stderr, "received LOCK_WRITE\n"));
- assert(localhost);
- local_lock(LOCK_WRITE, mp, host);
- break;
- case LOCK_NOTLOCKED:
- DPF((stderr, "received LOCK_NOTLOCKED\n"));
- send_lockmsg(LOCK_ACK, (pid_t)0, host, mp->seq);
- if (the_lock.type != LOCK_NOTLOCKED) {
- local_unlock(mp->pid, mp->seq, NORMAL_UNLOCK);
- }
- break;
- case LOCK_LOCKEDBY:
- lockedby(host, mp->seq);
- break;
- case LOCK_STAT:
- lock_stat();
- break;
- case LOCK_ACK:
- /* throw message away -- this is an error to receive */
- break;
- }
-}
-
-/*
- * unqueue any locks asked for by pid and unlock any locks held by pid.
- */
-
-static void
-purge_pid(pid_t pid)
-{
- DPF((stderr, "purge locks for %ld\n", pid));
- unqueue_lock(NULL, pid);
- if (the_lock.type != LOCK_NOTLOCKED)
- local_unlock(pid, 0, FORCE_UNLOCK);
-}
-
-/*
- * Check for exit or exec of client processes.
- * The lock protecting the processes pid in the lockfile will
- * be removed by the kernel when a client exits or execs.
- */
-
-static void
-check_for_dead()
-{
- int i, x;
- pid_t pid;
-
- for (i = 0; (x = cfg_filelock(i, 0)) != CFG_LF_EOF; i++) {
- if (x == CFG_LF_AGAIN)
- continue; /* can't take lock, must be still alive */
- cfg_readpid(i, &pid);
- cfg_writepid(i, (pid_t)0);
- (void) cfg_fileunlock(i);
- if (pid != (pid_t)0)
- purge_pid(pid);
- }
-}
-
-static void
-build_daemon_list(char *cf_file, int exe)
-{
- FILE *fp;
- char host[1024];
- int port;
- int i;
- struct hostent *hp;
- struct lockdaemon *ldp;
-
- if ((hp = gethostbyname("localhost")) == NULL) {
- (void) fprintf(stderr, "%s: Can't find hostent for %s\n",
- program, "localhost");
- spcs_log("cfglockd", NULL, "couldn't find localhost");
- exit(1);
- }
-
- (void) memcpy(&(localhost.sin_addr.s_addr), *(hp->h_addr_list),
- sizeof (localhost.sin_addr));
- if (cf_file == NULL) {
- (void) endhostent();
- return;
- }
- if (exe) {
- if ((fp = popen(cf_file, "r")) == NULL) {
- perror(cf_file);
- (void) fprintf(stderr,
- "%s: Can't open config program\n", program);
- spcs_log("cfglockd", NULL, "couldn't read config");
- exit(1);
- }
- } else {
- if ((fp = fopen(cf_file, "r")) == NULL) {
- perror(cf_file);
- (void) fprintf(stderr, "%s: Can't open config file\n",
- program);
- spcs_log("cfglockd", NULL, "couldn't read config");
- exit(1);
- }
- }
- ldp = daemon_list;
- while ((i = fscanf(fp, "%s %d\n", host, &port)) != EOF) {
- if (host[0] == '#') /* line starting with # are comments */
- continue;
- if (i == 1) {
- port = lock_port;
- } else {
- if (strcmp(host, "localhost") == 0) {
- lock_port = port;
- continue;
- }
- }
-
- if ((hp = gethostbyname(host)) == NULL) {
- (void) fprintf(stderr,
- "%s: Can't find hostent for %s\n", program, host);
- continue;
- }
-
- (void) memcpy(&(ldp->host.sin_addr.s_addr), *(hp->h_addr_list),
- sizeof (ldp->host.sin_addr));
- DPF((stderr, "daemon: %s\t%s\n",
- inet_ntoa(ldp->host.sin_addr), hp->h_name));
- if (islocalhost(&(ldp->host))) {
- DPF((stderr, "is an alias for this host, skipping\n"));
- continue;
- }
- ldp->host.sin_port = htons((short)port);
- ldp->host.sin_family = hp->h_addrtype;
- ldp->inuse = 1;
- ldp->up = 1;
- ldp++;
- }
- if (exe)
- (void) pclose(fp);
- else
- (void) fclose(fp);
- (void) endhostent();
-}
-
-static void
-usage()
-{
- (void) fprintf(stderr,
- gettext("usage: %s [-d] [-f file]|[-e program]\n"), program);
- exit(1);
-}
-
-static void
-unexpected(int sig)
-{
- spcs_log("cfglockd", NULL, "pid %d unexpected signal %d, ignoring",
- getpid(), sig);
-}
-
-static void
-term(int sig)
-{
- (void) unlink(CFG_PIDFILE);
- spcs_log("cfglockd", NULL, "pid %d terminate on signal %d", getpid(),
- sig);
- exit(0);
-}
-
-static void
-init(int argc, char *argv[])
-{
-#if defined(_SunOS_5_6) || defined(_SunOS_5_7) || defined(_SunOS_5_8)
- struct rlimit rl;
-#endif
- int c, i, x;
- int rc;
- char *cp = NULL;
- struct itimerval tv;
- struct timeval tp;
- socklen_t len = sizeof (thishost);
- int exe = 0;
- pid_t pid;
- FILE *fp;
-
- lstate = (getenv("LOCKD_STATE") != NULL);
- msgtrace = (getenv("LOCKD_MSG") != NULL);
-
- /*
- * Fork off a child that becomes the daemon.
- */
-
-#ifndef TTY_MESSAGES
- if ((rc = fork()) > 0)
- exit(0);
- else if (rc < 0) {
- spcs_log("cfglockd", NULL, "can't fork %d", errno);
- (void) fprintf(stderr, gettext("dscfglockd: cannot fork: %s\n"),
- strerror(errno));
- exit(1);
- }
-#endif
-
- /*
- * In child - become daemon.
- */
-
-#if !defined(_SunOS_5_6) && !defined(_SunOS_5_7) && !defined(_SunOS_5_8)
- /* use closefrom(3C) from PSARC/2000/193 when possible */
- closefrom(CLOSE_FD);
-#else
- (void) getrlimit(RLIMIT_NOFILE, &rl);
- for (i = CLOSE_FD; i < rl.rlim_max; i++)
- (void) close(i);
-#endif
-
-#ifdef DEBUG
-#ifndef TTY_MESSAGES
- (void) open("/dev/console", O_WRONLY|O_APPEND);
- (void) dup(0);
- (void) dup(0);
-#endif
-#endif
- (void) close(0);
-
- if (msgtrace || lstate) {
- debugfile = fopen("/var/tmp/dscfglockd.out", "a");
- if (debugfile) {
- time_t t = time(0);
- setbuf(debugfile, (char *)0);
- (void) fprintf(debugfile, "%19.19s dscfglockd start\n",
- ctime(&t));
- }
- }
-
- (void) setpgrp();
- spcs_log("cfglockd", NULL, "new lock daemon, pid %d", getpid());
-
- /*
- * Catch as unexpected all signals apart from SIGTERM.
- */
-
- for (i = 1; i < _sys_nsig; i++)
- (void) sigset(i, unexpected);
- (void) sigset(SIGTERM, term);
-
- for (i = 0; (c = getopt(argc, argv, "df:e:")) != EOF; i++) {
- switch (c) {
- case 'd':
- debug = 1;
- break;
- case 'e':
- exe = 1;
- if (cp) {
- usage();
- }
- cp = optarg;
- break;
- case 'f':
- if (cp) {
- usage();
- }
- cp = optarg;
- break;
- default:
- usage();
- break;
- }
- }
-
- ifc = (struct ifconf *)malloc(sizeof (struct ifconf));
- if (ifc == NULL) {
- perror(CFG_PIDFILE);
- DPF((stderr, "Can't open pid file\n"));
- exit(1);
- }
- (void) memset((char *)ifc, 0, sizeof (struct ifconf));
- getmyaddrs(ifc);
-
- /*
- * if (lockdaemonalive()) {
- * (void) fprintf(stderr, "%s: %s\n", program,
- * gettext("There is already a live lockdaemon"));
- * exit(1);
- * }
- */
- if ((fp = fopen(CFG_PIDFILE, "w")) == NULL) {
- perror(CFG_PIDFILE);
- DPF((stderr, "Can't open pid file\n"));
- exit(1);
- }
- (void) fprintf(fp, "%ld\n", getpid());
- (void) fclose(fp);
-
- /* order should be set to node number within cluster */
- order = cfg_iscluster();
- cfg_lfinit();
-
- if (!order) {
- (void) gettimeofday(&tp, NULL);
- srand48(tp.tv_usec);
- order = lrand48();
- if (debugfile) {
- (void) fprintf(debugfile, "WARNING: order number "
- "is 0 -- changing randomly to %d\n", order);
- }
- }
- c = 0;
- for (i = 0; (x = cfg_filelock(i, 0)) != CFG_LF_EOF; i++) {
- if (x == CFG_LF_AGAIN) {
- cfg_readpid(i, &pid);
- if (c++ == 0)
- spcs_log("cfglockd", NULL,
- "init .dscfg.lck slot %d pid %d locked",
- i, pid);
- DPF((stderr, "client process %ld still alive\n", pid));
- continue; /* can't take lock, must be still alive */
- }
- cfg_writepid(i, 0);
- (void) cfg_fileunlock(i);
- }
-
- tv.it_interval.tv_sec = TIMEOUT_SECS;
- tv.it_interval.tv_usec = 0;
- tv.it_value = tv.it_interval;
-
- bzero(unlock_buf, sizeof (unlock_buf));
- next_q = 0;
- build_daemon_list(cp, exe);
- if ((lock_soc = socket(pf_inet, SOCK_DGRAM, 0)) < 0) {
- (void) fprintf(stderr, "%s: %s\n", program,
- gettext("failed to create socket"));
- perror("socket");
- spcs_log("cfglockd", NULL, "couldn't create socket");
- exit(1);
- }
- thishost.sin_family = AF_INET;
- thishost.sin_addr.s_addr = INADDR_ANY;
- thishost.sin_port = htons(lock_port);
- rc = bind(lock_soc, (struct sockaddr *)&thishost, sizeof (thishost));
- if (rc < 0) {
- perror("bind");
- spcs_log("cfglockd", NULL, "couldn't bind");
- exit(1);
- }
- if (getsockname(lock_soc, (struct sockaddr *)&thishost, &len) < 0)
- perror("getsockname");
- send_aliveall();
- (void) sigset(SIGALRM, keepalive);
- (void) setitimer(ITIMER_REAL, &tv, NULL);
- /*
- * wait 2 time outs before allowing a lock to find if someone else
- * currently has the lock.
- */
-}
-
-#ifdef lint
-int
-lintmain(int argc, char *argv[])
-#else
-int
-main(int argc, char *argv[])
-#endif
-{
- struct lock_msg message_buf;
- daemonaddr_t from;
- int addrlen;
- int rc;
- int x = 1; /* kludge to stop warnings from compiler */
-
- init(argc, argv);
- CRIT_BEGIN();
- while (x) {
- CRIT_END();
- addrlen = sizeof (from);
- DPF((stderr, "begin recvfrom\n"));
- rc = recvfrom(lock_soc, &message_buf, sizeof (message_buf),
- 0, (struct sockaddr *)&from, &addrlen);
- DPF((stderr, "end recvfrom rc = %d\n", rc));
- CRIT_BEGIN();
- if (rc == sizeof (message_buf))
- dispatch(&message_buf, &from);
- else
- check_for_write_lock();
-
- /* if we own the lock, check to see if the process died */
- if (the_lock.type != LOCK_NOTLOCKED &&
- the_lock.remote_daemon == NULL)
- check_for_dead();
- }
- CRIT_END();
- return (0);
-}
diff --git a/usr/src/cmd/avs/dsstat/Makefile b/usr/src/cmd/avs/dsstat/Makefile
deleted file mode 100644
index 8a865c34a7..0000000000
--- a/usr/src/cmd/avs/dsstat/Makefile
+++ /dev/null
@@ -1,91 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#
-
-DYNPROG = dsstat
-
-include ../../Makefile.cmd
-include ../Makefile.com
-
-PROG = $(DYNPROG)
-
-SUBDIRS=
-
-dsstat := POBJS = dsstat.o ii_stats.o sndr_stats.o \
- sdbc_stats.o multi_stats.o common.o report.o
-
-OBJS= dsstat.o ii_stats.o sndr_stats.o sdbc_stats.o \
- multi_stats.o common.o report.o
-SRCS= $(OBJS:%.o=%.c)
-
-CFLAGS += $(CCVERBOSE)
-CERRWARN += -_gcc=-Wno-uninitialized
-CERRWARN += -_gcc=-Wno-parentheses
-CERRWARN += -_gcc=-Wno-unused-label
-CERRWARN += -_gcc=-Wno-clobbered
-LDLIBS += -lkstat
-LINTFLAGS += -Xa -n -s -x -m -u -Dlint -errhdr=%user
-LINTFLAGS += -erroff=E_SEC_PRINTF_VAR_FMT -erroff=E_SEC_SPRINTF_UNBOUNDED_COPY
-LINTDIR = $(KBASE)/lintdir
-POFILE = dsstat_all.po
-POFILES = $(OBJS:%.o=%.po)
-LFILE = $(LINTDIR)/dsstat.ln
-ROOTLINK = $(ROOTUSRSBIN)/$(PROG)
-
-all := TARGET= all
-install := TARGET= install
-clean := TARGET= clean
-clobber := TARGET= clobber
-lint := TARGET= lint
-
-.KEEP_STATE:
-
-.PARALLEL: $(OBJS)
-
-all: $(SUBDIRS) $(PROG)
-
-install: $(SUBDIRS) all $(ROOTPROG) $(ROOTLINK)
-
-lint: $(SUBDIRS) lint_SRCS
-
-clean: $(SUBDIRS)
- $(RM) *.o
-
-$(PROG): $$(POBJS)
- $(LINK.c) $(POBJS) -o $@ $(LDLIBS)
- $(POST_PROCESS)
-
-$(POFILE): $(POFILES)
- $(RM) $@
- $(CAT) $(POFILES) > $@
-
-$(SUBDIRS): FRC
- @cd $@; pwd; $(MAKE) $(TARGET)
-
-$(ROOTLINK): $(ROOTUSRSBIN) $(ROOTPROG)
- -$(RM) $@; $(LN) $(ROOTPROG) $@
-
-FRC:
-
-include ../../Makefile.targ
diff --git a/usr/src/cmd/avs/dsstat/common.c b/usr/src/cmd/avs/dsstat/common.c
deleted file mode 100644
index 45f8145591..0000000000
--- a/usr/src/cmd/avs/dsstat/common.c
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <errno.h>
-#include <kstat.h>
-#include <signal.h>
-#include <setjmp.h>
-
-#include "sdbc_stats.h"
-#include "report.h"
-#include "common.h"
-
-static sigjmp_buf env;
-static sig_atomic_t sig_raised = 0;
-static void sig_handler(int);
-
-void
-sig_handler(int sig)
-{
- switch (sig) {
- case SIGSEGV:
- sig_raised = 1;
- siglongjmp(env, sig);
- default:
- exit(sig);
- }
-}
-
-/*
- * kstat_retrieve() - populate the ks_data field of the kstat_t structure
- *
- * This function is a user-land equivalent of a ks_snapshot
- *
- * parameters
- * kstat_ctl_t *kc - kstat_ctl_t structure representing returned from
- * kstat_open()
- * kstat_t *ksp - kstat_t strcture to popluate ks_data into
- *
- * returns
- * NULL pointer on failure
- * kstat_t * structure on success
- */
-kstat_t *
-kstat_retrieve(kstat_ctl_t *kc, kstat_t *ksp)
-{
-
- kstat_t *rval;
- kstat_named_t *knp;
- char *end;
- int i;
- struct sigaction segv_act; /* default actions */
-
- if (ksp == NULL)
- return (NULL);
-
- if (ksp->ks_data == NULL &&
- kstat_read(kc, ksp, NULL) == -1)
- return (NULL);
-
- rval = (kstat_t *)calloc(1, sizeof (*ksp));
- (void) memcpy(rval, ksp, sizeof (*ksp));
-
- rval->ks_data = (void *) calloc(1, ksp->ks_data_size);
- (void) memcpy(rval->ks_data, ksp->ks_data,
- sizeof (kstat_named_t) * ksp->ks_ndata);
-
- /* special handling for variable length string KSTAT_DATA_STRING */
- knp = (kstat_named_t *)rval->ks_data;
- end = (char *)(knp + ksp->ks_ndata);
- for (i = 0; i < ksp->ks_ndata; i++, knp++) {
- if (knp->data_type == KSTAT_DATA_STRING &&
- KSTAT_NAMED_STR_PTR(knp) != NULL) {
- /* catch SIGSEGV (bug 6384130) */
- sig_raised = 0;
- (void) sigaction(SIGSEGV, NULL, &segv_act);
- (void) signal(SIGSEGV, sig_handler);
-
- (void) strncpy(end, KSTAT_NAMED_STR_PTR(knp),
- KSTAT_NAMED_STR_BUFLEN(knp));
- KSTAT_NAMED_STR_PTR(knp) = end;
- end += KSTAT_NAMED_STR_BUFLEN(knp);
-
- /* bug 6384130 */
- (void) sigsetjmp(env, 0);
- if (sig_raised) {
- bzero(end, KSTAT_NAMED_STR_BUFLEN(knp));
- KSTAT_NAMED_STR_PTR(knp) = end;
- end += KSTAT_NAMED_STR_BUFLEN(knp);
- }
- (void) sigaction(SIGSEGV, &segv_act, NULL);
- }
- }
-
- return (rval);
-}
-
-/*
- * kstat_value() - retrieve value of a field in a kstat_named_t kstat.
- *
- * parameters
- * kstat_t *ksp - kstat containing the field
- * char *name - text string representing the field name
- *
- * returns
- * void * - pointer to data retrieved
- */
-void *
-kstat_value(kstat_t *ksp, char *name)
-{
- kstat_named_t *knm;
-
- if ((knm = kstat_data_lookup(ksp, name)) == NULL)
- return (NULL);
-
- switch (knm->data_type) {
- case KSTAT_DATA_CHAR :
- return (knm->value.c);
- case KSTAT_DATA_INT32 :
- return (&knm->value.i32);
- case KSTAT_DATA_UINT32 :
- return (&knm->value.ui32);
- case KSTAT_DATA_INT64 :
- return (&knm->value.i64);
- case KSTAT_DATA_UINT64 :
- return (&knm->value.ui64);
- case KSTAT_DATA_STRING :
- return (KSTAT_NAMED_STR_PTR(knm));
- }
-
- return (NULL);
-}
-
-/*
- * kstat_free() - deallocated memory associated with a kstat
- *
- * paramters
- * kstat_t ksp - kstat to be deallocated
- *
- * returns
- * void
- */
-void
-kstat_free(kstat_t *ksp)
-{
- if (ksp != NULL) {
- if (ksp->ks_data != NULL)
- free(ksp->ks_data);
- free(ksp);
- }
-}
-
-uint32_t
-kstat_delta(kstat_t *pksp, kstat_t *cksp, char *name)
-{
- uint32_t *pv, *cv;
-
- pv = kstat_value(pksp, name);
- cv = kstat_value(cksp, name);
-
- return (u32_delta(*pv, *cv));
-}
diff --git a/usr/src/cmd/avs/dsstat/common.h b/usr/src/cmd/avs/dsstat/common.h
deleted file mode 100644
index 79805f8569..0000000000
--- a/usr/src/cmd/avs/dsstat/common.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _COMMON_H
-#define _COMMON_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Prototypes */
-void *kstat_value(kstat_t *, char *);
-kstat_t *kstat_retrieve(kstat_ctl_t *, kstat_t *);
-void kstat_free(kstat_t *);
-uint32_t kstat_delta(kstat_t *, kstat_t *, char *);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _COMMON_H */
diff --git a/usr/src/cmd/avs/dsstat/dsstat.c b/usr/src/cmd/avs/dsstat/dsstat.c
deleted file mode 100644
index a10ffc0a35..0000000000
--- a/usr/src/cmd/avs/dsstat/dsstat.c
+++ /dev/null
@@ -1,546 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <inttypes.h>
-#include <locale.h>
-
-#include <kstat.h>
-
-#include "dsstat.h"
-#include "multi_stats.h"
-
-/* Globals */
-int mode = 0;
-int interval = 1;
-int iterations = 1;
-int zflag = 0;
-int linesout = 0;
-
-short hflags = HEADERS_EXL;
-short dflags = 0;
-short rflags = 0;
-vslist_t *vs_top = NULL;
-
-void
-errout(char *msg)
-{
-
- (void) fprintf(stderr, msg);
-}
-
-void
-usage()
-{
- errout(gettext(
- "\ndsstat [-m <mode>[,<mode>]] [-f | -F] [-z] [-s <sets>] "
- "[-r <flags>] \\\n[-d <flags>] [<interval> [<count>]]\n\n"));
-}
-
-void
-help()
-{
- usage();
-
- errout(gettext("\t"
- "-d <flags> Specifies the statistics to be displayed\n\n"));
- errout(gettext("\t"
- " For 'cache' mode\n"));
- errout(gettext("\t"
- " Valid <flags> are 'rwfsdc', default <flags> are 'sf'\n"));
- errout(gettext("\t"
- " r=read, w=write, f=flags, s=summary,\n"));
- errout(gettext("\t"
- " only available for cache mode, need to combine with '-m'\n"));
- errout(gettext("\t"
- " d=destaged, c=write cancellations\n\n"));
- errout(gettext("\t"
- " For 'ii' mode;\n"));
- errout(gettext("\t"
- " Valid <flags> are 'rwtfps', default <flags> are 'sf'\n"));
- errout(gettext("\t"
- " r=read, w=write, t=timing, f=flags, p=percentages,\n"));
- errout(gettext("\t"
- " s=summary\n\n"));
- errout(gettext("\t"
- " For 'sndr' mode;\n"));
- errout(gettext("\t"
- " Valid <flags> are'rwtfpsq', default <flags> are 'spf'\n"));
- errout(gettext("\t"
- " r=read, w=write, t=timing, f=flags, p=percentages,\n"));
- errout(gettext("\t"
- " s=summary\n"));
- errout(gettext("\t"
- " only available for sndr mode, need to combine with '-m'\n"));
- errout(gettext("\t"
- " q=queue\n\n"));
- errout(gettext("\t"
- "-f prints field headers once for each iteration\n\n"));
- errout(gettext("\t"
- "-F prints field headers once, at the start of reporting\n\n"));
- errout(gettext("\t"
- "-h prints detailed usage message\n\n"));
- errout(gettext("\t"
- "-m <mode>[,<mode>] where mode is, 'cache', 'ii', or 'sndr'\n\n"));
- errout(gettext("\t"
- " Multiple modes may be specified as a comma separated list,\n"));
- errout(gettext("\t"
- " or multiple -m switches may be used.\n\n"));
- errout(gettext("\t"
- "-r <flags> specifies components to be reported\n\n"));
- errout(gettext("\t"
- " For 'cache' mode, this option is not used.\n\n"));
- errout(gettext("\t"
- " For 'ii' mode;\n"));
- errout(gettext("\t"
- " Valid <flags> are 'msbo', default <flags> are 'msbo'\n"));
- errout(gettext("\t"
- " m=master, s=shadow, b=bitmap, o=overflow\n\n"));
- errout(gettext("\t"
- " For 'sndr' mode;\n"));
- errout(gettext("\t"
- " Valid <flags> are 'nb', default <flags> are 'nb'\n"));
- errout(gettext("\t"
- " n=network, b=bitmap\n\n"));
- errout(gettext("\t"
- "-s <sets> outputs specified sets\n"));
- errout(gettext("\t"
- " Where <sets> is a comma delimited list of set names\n\n"));
- errout(gettext("\t"
- "-z suppress reports with zero value (no activity)\n\n"));
- errout(gettext("\t"
- "<interval> is the number of seconds between reports\n\n"));
- errout(gettext("\t"
- "<count> is the number of reports to be generated\n\n"));
-}
-
-void
-fail(int err, char *msg)
-{
- errout(gettext("\ndsstat: "));
- errout(msg);
-
- usage();
-
- errout(gettext("For detailed usage run \"dsstat -h\"\n"));
-
- exit(err);
-}
-
-int
-set_mode(char *user_modes)
-{
- char *m;
- int local_mode = 0;
-
- for (m = strtok(user_modes, ","); m != NULL; m = strtok(NULL, ",")) {
- if (local_mode != 0) {
- local_mode |= MULTI;
- }
-
- if (strncasecmp("sndr", m, strlen(m)) == 0) {
- local_mode |= SNDR;
- continue;
- }
-
- if (strncasecmp("ii", m, strlen(m)) == 0) {
- local_mode |= IIMG;
- continue;
- }
-
- if (strncasecmp("cache", m, strlen(m)) == 0) {
- local_mode |= SDBC;
- continue;
- }
-
- fail(DSSTAT_EINVAL, gettext("Invalid mode specified"));
- }
-
- return (local_mode);
-}
-
-short
-set_dflags(char *flags)
-{
- int index;
- short user_dflags = 0;
-
- for (index = 0; index < strlen(flags); index++) {
- switch (flags[index]) {
- case 'r':
- user_dflags |= READ;
- break;
- case 'w':
- user_dflags |= WRITE;
- break;
- case 't':
- user_dflags |= TIMING;
- break;
- case 'f':
- user_dflags |= FLAGS;
- break;
- case 'p':
- user_dflags |= PCTS;
- break;
- case 's':
- user_dflags |= SUMMARY;
- break;
- case 'd':
- user_dflags |= DESTAGED;
- break;
- case 'c':
- user_dflags |= WRCANCEL;
- break;
- case 'h':
- user_dflags |= RATIO;
- break;
- case 'q':
- user_dflags |= ASYNC_QUEUE;
- break;
- default:
- fail(DSSTAT_EINVAL,
- gettext("Invalid display-flags set\n"));
- }
- }
-
- return (user_dflags);
-}
-
-short
-set_rflags(char *flags)
-{
- int index;
- short user_rflags = 0;
-
- for (index = 0; index < strlen(flags); index++) {
- switch (flags[index]) {
- case 'm':
- user_rflags |= IIMG_MST;
- break;
- case 's':
- user_rflags |= IIMG_SHD;
- break;
- case 'b':
- user_rflags |= IIMG_BMP;
- user_rflags |= SNDR_BMP;
- break;
- case 'o':
- user_rflags |= IIMG_OVR;
- break;
- case 'n':
- user_rflags |= SNDR_NET;
- break;
- default:
- fail(DSSTAT_EINVAL,
- gettext("Invalid report-flags set\n"));
- }
- }
-
- return (user_rflags);
-}
-
-void
-set_vol_list(char *list)
-{
- vslist_t *pre;
- vslist_t *newvol;
- vslist_t *vslist;
- char *volume;
-
- for (volume = strtok(list, ","); volume != NULL;
- volume = strtok(NULL, ",")) {
- int dup = 0;
- char *vh = NULL;
- char *vn = NULL;
-
- /* get user-specified set information */
- if ((vn = strchr(volume, ':')) == NULL) {
- vn = volume;
- } else {
- *vn = '\0';
- vn++;
- vh = volume;
- }
-
- /* check for duplicates */
- dup = 0;
-
- for (vslist = vs_top; vslist != NULL; vslist = vslist->next) {
- if (vslist->volhost && vh) {
- if (strcmp(vslist->volhost, vh) == 0 &&
- strcmp(vslist->volname, vn) == 0)
- dup = 1;
- } else {
- if (strcmp(vslist->volname, vn) == 0)
- dup = 1;
- }
-
- pre = vslist;
- }
-
- if (dup)
- continue;
-
- /* initialize new vslist record */
- newvol = (vslist_t *)calloc(1, sizeof (vslist_t));
-
- newvol->volname = (char *)calloc((strlen(vn) + 1),
- sizeof (char));
- (void) strcpy(newvol->volname, vn);
-
- if (vh == NULL)
- goto save;
-
- newvol->volhost = (char *)calloc((strlen(vh) + 1),
- sizeof (char));
- (void) strcpy(newvol->volhost, vh);
-
-save:
- /* save record */
- if (vs_top == NULL) {
- vslist = vs_top = newvol;
- vslist->next = NULL;
- continue;
- }
-
- if (vslist == NULL) {
- vslist = pre->next = newvol;
- vslist->next = NULL;
- continue;
- }
- }
-}
-
-int
-main(int argc, char **argv)
-{
- extern char *optarg;
- extern int optind;
-
- int c;
- int error;
- short user_dflags = 0;
- short user_rflags = 0;
-
- /* Parse command line */
- while ((c = getopt(argc, argv, "d:fFhm:r:s:z")) != EOF) {
- switch (c) {
- case 'd': /* what to display */
- user_dflags = set_dflags(optarg);
- break;
- case 'f':
- hflags = HEADERS_ATT;
- break;
- case 'F':
- hflags = HEADERS_BOR;
- break;
- case 'h': /* usage */
- help();
- exit(0);
- break;
- case 'm': /* Mode */
- mode |= set_mode(optarg);
- break;
- case 'r': /* what to report on */
- user_rflags = set_rflags(optarg);
- break;
- case 's':
- set_vol_list(optarg);
- break;
- case 'z':
- zflag = 1;
- break;
-
- default:
- fail(DSSTAT_EINVAL,
- "Invalid argument specified\n");
- }
- }
-
- /* Parse additional arguments */
- if (optind < argc) {
- if ((interval = atoi(argv[optind])) <= 0) {
- fail(DSSTAT_EINVAL,
- gettext("Invalid interval specified.\n"));
- } else {
- iterations = -1;
- }
-
- optind++;
-
- if (optind < argc) {
- if ((iterations = atoi(argv[optind])) <= 0) {
- fail(DSSTAT_EINVAL,
- gettext("Invalid count specified.\n"));
- }
- }
-
- optind++;
- }
-
- if (optind < argc) {
- fail(DSSTAT_EINVAL,
- gettext("Too many parameters specified.\n"));
- }
-
- if (mode == 0)
- mode |= MULTI | IIMG | SNDR | SDBC;
-
- /* Select statistics to gather */
- if (mode & SNDR) {
- if (! (mode & MULTI)) {
- if (user_rflags & IIMG_BMP)
- user_rflags ^= IIMG_BMP;
-
- if ((user_dflags | SNDR_DIS_MASK) != SNDR_DIS_MASK) {
- fail(DSSTAT_EINVAL, gettext("Invalid "
- "display-flags for RemoteMirror\n"));
- }
-
- if ((user_rflags | SNDR_REP_MASK) != SNDR_REP_MASK) {
- fail(DSSTAT_EINVAL,
- gettext("Invalid report-flags for "
- "Remote Mirror\n"));
- }
- }
-
- if ((mode & MULTI) && (user_dflags & ASYNC_QUEUE)) {
- fail(DSSTAT_EINVAL, gettext("Remote Mirror async. queue"
- "statistics can not be displayed with mutiple "
- "modes."));
- }
-
- if (user_dflags)
- dflags = user_dflags;
- else
- dflags |= (SUMMARY | PCTS | FLAGS | RATIO);
-
- if (user_rflags)
- rflags = user_rflags;
- else
- rflags |= (SNDR_NET | SNDR_BMP);
- }
-
- if (mode & IIMG) {
- if (! (mode & MULTI)) {
- if (user_rflags & SNDR_BMP)
- user_rflags ^= SNDR_BMP;
-
- if ((user_dflags | IIMG_DIS_MASK) != IIMG_DIS_MASK) {
- fail(DSSTAT_EINVAL,
- gettext("Invalid display-flags for "
- "Point-in-Time Copy\n"));
- }
-
- if ((user_rflags | IIMG_REP_MASK) != IIMG_REP_MASK) {
- fail(DSSTAT_EINVAL,
- gettext("Invalid report-flags for "
- "Point-in-Time Copy\n"));
- }
- }
-
- if (user_dflags)
- dflags = user_dflags;
- else
- dflags |= (SUMMARY | PCTS | FLAGS | RATIO);
-
- if (user_rflags)
- rflags = user_rflags;
- else
- rflags |= (IIMG_MST | IIMG_SHD | IIMG_BMP | IIMG_OVR);
- }
-
- if (mode & SDBC) {
- if (! (mode & MULTI)) {
- if ((user_dflags | CACHE_DIS_MASK) != CACHE_DIS_MASK) {
- fail(DSSTAT_EINVAL, gettext("Invalid "
- "display-flags for CACHE\n"));
- }
-
- if ((user_rflags | CACHE_REP_MASK) != CACHE_REP_MASK) {
- fail(DSSTAT_EINVAL, gettext("Invalid "
- "report-flags for CACHE\n"));
- }
- } else {
- if ((user_dflags & DESTAGED) || (user_dflags & WRCANCEL)) {
- if (user_dflags & DESTAGED)
- fail(DSSTAT_EINVAL, gettext("Cache, destaged "
- "statistics can not be displayed with mutiple "
- "modes."));
- else
- fail(DSSTAT_EINVAL, gettext("Cache, write "
- "cancellations "
- "statistics can not be displayed with mutiple "
- "modes."));
- }
- }
-
- if (user_dflags)
- dflags = user_dflags;
- else
- if (mode & MULTI)
- dflags |= (SUMMARY);
- else
- dflags |= (SUMMARY | FLAGS);
-
- if (user_rflags)
- rflags = user_rflags;
- else
- rflags |= user_rflags;
- }
-
- error = do_stats();
-
- if (error == EAGAIN) {
- fail(DSSTAT_NOSTAT, gettext("No statistics available for the "
- "specified mode(s).\n"));
- }
-
- if (error == EINVAL) {
- fail(DSSTAT_EINVAL,
- gettext("Invalid kstat format detected.\n"));
- }
-
- if (error == ENOMEM) {
- fail(DSSTAT_ENOMEM,
- gettext("Unable to open kstat device for reading.\n"));
- }
-
- if (error == -1) {
- if (execv("/usr/sbin/dsstat", argv) != 0) {
- fail(DSSTAT_EMAP, gettext("Kstat is invalid.\n"));
- }
- }
-
- if (error) {
- fail(DSSTAT_EUNKNWN, gettext("An unknown error occured.\n"));
- }
-
- return (0);
-}
diff --git a/usr/src/cmd/avs/dsstat/dsstat.h b/usr/src/cmd/avs/dsstat/dsstat.h
deleted file mode 100644
index eb73bcd48c..0000000000
--- a/usr/src/cmd/avs/dsstat/dsstat.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _DSSTAT_H
-#define _DSSTAT_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct vslist_s
-{
- char *volname;
- char *volhost;
- struct vslist_s *next;
-} vslist_t;
-
-extern int mode;
-extern int interval;
-extern int iterations;
-extern int zflag;
-extern int linesout;
-extern short hflags;
-extern short dflags;
-extern short rflags;
-extern vslist_t *vs_top;
-
-/* kstat named character limit */
-#define NAMED_LEN 15
-
-/* Mode */
-#define MULTI 0x01
-#define SNDR 0x02
-#define IIMG 0x04
-#define SDBC 0x08
-
-/* Error codes */
-#define DSSTAT_SUCCESS 0 /* Success */
-#define DSSTAT_NOSTAT 1 /* No Statistics Avaiable */
-#define DSSTAT_EINVAL 2 /* Invalid Argument */
-#define DSSTAT_ENOMEM 3 /* No Memory Available To Get Statistics */
-#define DSSTAT_EUNKNWN 4 /* Unknown Error */
-#define DSSTAT_EMAP 5 /* Mapped kstat memory is invalid */
-
-/* Report flags */
-#define IIMG_MST 0x01
-#define IIMG_SHD 0x02
-#define IIMG_BMP 0x04
-#define IIMG_OVR 0x08
-
-#define SNDR_PRI 0x10
-#define SNDR_NET 0x20
-#define SNDR_BMP 0x40
-
-/* Display flags */
-#define SUMMARY 0x01
-#define READ 0x02
-#define WRITE 0x04
-#define TIMING 0x08
-#define FLAGS 0x10
-#define PCTS 0x20
-#define DESTAGED 0x40
-#define WRCANCEL 0x80
-#define RATIO 0x100
-#define ASYNC_QUEUE 0x200
-
-/* Flag masks */
-#define SNDR_REP_MASK (SNDR_PRI | SNDR_NET | SNDR_BMP)
-#define SNDR_DIS_MASK (SUMMARY | READ | WRITE | TIMING | FLAGS | PCTS | \
- RATIO | ASYNC_QUEUE)
-
-#define IIMG_REP_MASK (IIMG_MST | IIMG_SHD | IIMG_BMP | IIMG_OVR)
-#define IIMG_DIS_MASK (SUMMARY | READ | WRITE | TIMING | FLAGS | PCTS | RATIO)
-
-#define CACHE_REP_MASK 0
-#define CACHE_DIS_MASK (SUMMARY | READ | WRITE | FLAGS | DESTAGED | WRCANCEL)
-
-/* Field header defines */
-#define DISPLAY_LINES 19
-#define HEADERS_OUT 0x01 /* flag to show headers output for cycle */
-#define HEADERS_BOR 0x02 /* field headers at beginning of run */
-#define HEADERS_ATT 0x04 /* field headers all the time */
-#define HEADERS_EXL 0x08 /* field headers every X lines */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _DSSTAT_H */
diff --git a/usr/src/cmd/avs/dsstat/ii_stats.c b/usr/src/cmd/avs/dsstat/ii_stats.c
deleted file mode 100644
index e37ea891cb..0000000000
--- a/usr/src/cmd/avs/dsstat/ii_stats.c
+++ /dev/null
@@ -1,811 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include <sys/mutex.h>
-
-#include <kstat.h>
-
-#include <sys/unistat/spcs_s.h>
-#include <sys/nsctl/dsw.h>
-#include "../../../uts/common/avs/ns/dsw/dsw_dev.h"
-#include <sys/nsctl/dsw_dev.h>
-
-#include "sdbc_stats.h"
-#include "ii_stats.h"
-
-#include "dsstat.h"
-#include "common.h"
-#include "report.h"
-
-static iistat_t *ii_top = NULL;
-
-void ii_add_stat(iistat_t *);
-iistat_t *ii_del_stat(iistat_t *);
-
-int ii_value_check(iistat_t *iistat);
-int ii_validate(kstat_t *ksp);
-int ii_vol_selected(kstat_t *);
-
-/*
- * ii_discover() - looks for new statistics to be monitored.
- * Verifies that any statistics found are now already being
- * monitored.
- *
- */
-int
-ii_discover(kstat_ctl_t *kc)
-{
- static int validated = 0;
-
- kstat_t *ksp;
-
- /* Loop on all kstats */
- for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {
- char *kname;
- iistat_t *cur;
- iistat_t *iistat = NULL;
- kstat_t *mst_ksp;
- kstat_t *shd_ksp;
- kstat_t *bmp_ksp;
- kstat_t *ovr_ksp;
-
- /* Search for II set */
- if (strcmp(ksp->ks_class, II_KSTAT_CLASS) != 0)
- continue;
-
- if (kstat_read(kc, ksp, NULL) == -1)
- continue;
-
- /*
- * Validate kstat structure
- */
- if (! validated) {
- if (ii_validate(ksp))
- return (EINVAL);
-
- validated++;
- }
-
- /*
- * Duplicate check
- */
- for (cur = ii_top; cur != NULL; cur = cur->next) {
- char *cur_vname, *tst_vname;
- uint32_t cur_inst, tst_inst;
-
- cur_vname = cur->pre_set->ks_name;
- cur_inst = cur->pre_set->ks_instance;
-
- tst_vname = ksp->ks_name;
- tst_inst = ksp->ks_instance;
-
- if (strcmp(cur_vname, tst_vname) == 0 &&
- cur_inst == tst_inst)
- goto next;
- }
-
- /*
- * Initialize new record
- */
- iistat = (iistat_t *)calloc(1, sizeof (iistat_t));
-
- /*
- * Set kstat
- */
- iistat->pre_set = kstat_retrieve(kc, ksp);
-
- if (iistat->pre_set == NULL)
- goto next;
-
- iistat->collected |= GOT_SETSTAT;
-
- /*
- * Master kstat
- */
- kname = kstat_value(iistat->pre_set, DSW_SKSTAT_MSTIO);
-
- mst_ksp = kstat_lookup(kc, II_KSTAT_MODULE, -1, kname);
- iistat->pre_mst = kstat_retrieve(kc, mst_ksp);
-
- if (iistat->pre_mst == NULL)
- goto next;
-
- iistat->collected |= GOT_MSTSTAT;
-
- /*
- * Shadow kstat
- */
- kname = kstat_value(iistat->pre_set, DSW_SKSTAT_SHDIO);
-
- shd_ksp = kstat_lookup(kc, II_KSTAT_MODULE, -1, kname);
- iistat->pre_shd = kstat_retrieve(kc, shd_ksp);
-
- if (iistat->pre_shd == NULL)
- goto next;
-
- iistat->collected |= GOT_SHDSTAT;
-
- /*
- * Bitmap kstat
- */
- kname = kstat_value(iistat->pre_set, DSW_SKSTAT_BMPIO);
-
- bmp_ksp = kstat_lookup(kc, II_KSTAT_MODULE, -1, kname);
- iistat->pre_bmp = kstat_retrieve(kc, bmp_ksp);
-
- if (iistat->pre_bmp == NULL)
- goto next;
-
- iistat->collected |= GOT_BMPSTAT;
-
- /*
- * Overflow kstat
- */
- kname = kstat_value(iistat->pre_set, DSW_SKSTAT_OVRIO);
-
- ovr_ksp = kstat_lookup(kc, II_KSTAT_MODULE, -1, kname);
- iistat->pre_ovr = kstat_retrieve(kc, ovr_ksp);
-
- if (iistat->pre_ovr == NULL)
- goto next;
-
- iistat->collected |= GOT_OVRSTAT;
-
-next:
- /*
- * Check if we got a complete set of stats
- */
- if (iistat == NULL)
- continue;
-
- if (IIMG_COMPLETE(iistat->collected)) {
- (void) ii_del_stat(iistat);
- continue;
- }
-
- /*
- * Add to linked list
- */
- ii_add_stat(iistat);
- }
-
- if (ii_top == NULL)
- return (EAGAIN);
-
- return (0);
-}
-
-/*
- * ii_update() - updates all of the statistics currently being monitored.
- *
- */
-int
-ii_update(kstat_ctl_t *kc)
-{
- iistat_t *cur;
-
- for (cur = ii_top; cur != NULL; cur = cur->next) {
- char volname[KSTAT_STRLEN + 1];
- char *kname;
-
- kstat_t *ksp = NULL;
-
- cur->collected = 0;
-
- /*
- * Age off old stats
- */
- if (cur->cur_set != NULL) {
- kstat_free(cur->pre_set);
- kstat_free(cur->pre_mst);
- kstat_free(cur->pre_shd);
- kstat_free(cur->pre_bmp);
-
- cur->pre_set = cur->cur_set;
- cur->pre_mst = cur->cur_mst;
- cur->pre_shd = cur->cur_shd;
- cur->pre_bmp = cur->cur_bmp;
-
- if (cur->cur_ovr != NULL) {
- kstat_free(cur->pre_ovr);
- cur->pre_ovr = cur->cur_ovr;
- }
- }
-
- /*
- * Set kstat
- */
- (void) strncpy(volname, cur->pre_set->ks_name, KSTAT_STRLEN);
- volname[KSTAT_STRLEN] = '\0';
-
- ksp = kstat_lookup(kc, II_KSTAT_MODULE, -1, volname);
-
- if ((cur->cur_set = kstat_retrieve(kc, ksp)) == NULL)
- continue;
-
- cur->collected |= GOT_SETSTAT;
-
- /*
- * Validate set
- */
- if (strcmp(cur->pre_set->ks_name, cur->cur_set->ks_name) != 0 ||
- cur->pre_set->ks_instance != cur->cur_set->ks_instance)
- continue;
-
- /*
- * Master kstat
- */
- kname = kstat_value(cur->cur_set, DSW_SKSTAT_MSTIO);
-
- ksp = kstat_lookup(kc, II_KSTAT_MODULE, -1, kname);
-
- if ((cur->cur_mst = kstat_retrieve(kc, ksp)) == NULL)
- continue;
-
- cur->collected |= GOT_MSTSTAT;
-
- /*
- * Shadow kstat
- */
- kname = kstat_value(cur->cur_set, DSW_SKSTAT_SHDIO);
-
- ksp = kstat_lookup(kc, II_KSTAT_MODULE, -1, kname);
-
- if ((cur->cur_shd = kstat_retrieve(kc, ksp)) == NULL)
- continue;
-
- cur->collected |= GOT_SHDSTAT;
-
- /*
- * Bitmap kstat
- */
- kname = kstat_value(cur->pre_set, DSW_SKSTAT_BMPIO);
-
- ksp = kstat_lookup(kc, II_KSTAT_MODULE, -1, kname);
-
- if ((cur->cur_bmp = kstat_retrieve(kc, ksp)) == NULL)
- continue;
-
- cur->collected |= GOT_BMPSTAT;
-
- /*
- * Overflow kstat
- */
- kname = kstat_value(cur->cur_set, DSW_SKSTAT_OVRIO);
-
- ksp = kstat_lookup(kc, II_KSTAT_MODULE, -1, kname);
-
- if (ksp == NULL) {
- if (cur->pre_ovr != NULL) {
- kstat_free(cur->pre_ovr);
- cur->pre_ovr = NULL;
- }
- if (cur->cur_ovr != NULL) {
- kstat_free(cur->cur_ovr);
- cur->cur_ovr = NULL;
- }
- continue;
- }
-
- if (cur->pre_ovr == NULL) {
- if ((cur->pre_ovr = kstat_retrieve(kc, ksp)) == NULL)
- continue;
- } else {
- if ((cur->cur_ovr = kstat_retrieve(kc, ksp)) == NULL)
- continue;
- }
-
- cur->collected |= GOT_OVRSTAT;
- }
-
- return (0);
-}
-
-/*
- * ii_report() - outputs statistics for the statistics currently being
- * monitored. Deletes statistics for volumes that have been disabled.
- *
- */
-int
-ii_report()
-{
- uint32_t *flags;
- int padsz = 0;
- char pad[20] = {0};
- iistat_t *cur, *pre = NULL;
-
- if (ii_top == NULL) {
- return (0);
- }
-
- /* Create padding string for secondary report lines */
- if (dflags & FLAGS) {
- padsz += STAT_HDR_SIZE;
- padsz += STAT_HDR_SIZE;
- }
-
- if (dflags & PCTS)
- padsz += PCT_HDR_SIZE;
-
- if (padsz) {
- char fmt[20];
- (void) sprintf(fmt, "%%%ds", padsz);
- (void) sprintf(pad, fmt, "");
- }
-
- for (cur = ii_top; cur; /* CSTYLED */) {
- int first = 1;
- char data[20] = {0};
-
- /* Check to see if this is this a complete */
- if (IIMG_COMPLETE(cur->collected)) {
- char *c;
- char vol[(NAMED_LEN * 4) + 1] = {0};
- int offset;
- iistat_t *next;
-
- /* notify user of set being disabled */
- c = kstat_value(cur->pre_set, DSW_SKSTAT_SETA);
- (void) strncpy(vol, c, NAMED_LEN);
- c = kstat_value(cur->pre_set, DSW_SKSTAT_SETB);
- (void) strncat(vol, c, NAMED_LEN);
- c = kstat_value(cur->pre_set, DSW_SKSTAT_SETC);
- (void) strncat(vol, c, NAMED_LEN);
- c = kstat_value(cur->pre_set, DSW_SKSTAT_SETD);
- (void) strncat(vol, c, NAMED_LEN);
-
- offset = strlen(vol) - NAMED_LEN;
-
- if (offset < 0)
- offset = 0;
-
- (void) printf(DATA_C16, vol + offset);
- (void) printf(" %s\n", II_DISABLED);
-
- /* free memory and remove stat from list */
- next = ii_del_stat(cur);
-
- if (! pre)
- cur = ii_top = next;
- else
- cur = pre->next = next;
-
- continue;
- }
-
- /* Check to see if the user specified this volume */
- if (! ii_vol_selected(cur->pre_set))
- goto next;
-
- /* Check to see if zflag applies */
- if (zflag && ii_value_check(cur) == 0)
- goto next;
-
- /* Calculate flags */
- flags = kstat_value(cur->cur_set, DSW_SKSTAT_FLAGS);
-
- if (dflags & FLAGS) {
-
- char c[STAT_HDR_SIZE];
- char vtype[STAT_HDR_SIZE];
- char vstat[STAT_HDR_SIZE];
-
- if (*flags & DSW_GOLDEN)
- (void) strcpy(c, II_INDEPENDENT);
- else
- (void) strcpy(c, II_DEPENDENT);
-
- (void) sprintf(vtype, DATA_C2, c);
- (void) strcat(data, vtype);
-
- if (*flags & DSW_COPYINGP)
- (void) strcpy(c, II_COPYING);
- else
- (void) strcpy(c, NO_INFO);
-
-
- (void) sprintf(vstat, DATA_C2, c);
- (void) strcat(data, vstat);
- }
-
- /* Calculate sync needed precentage */
- if (dflags & PCTS) {
- char snpct[10];
- uint32_t *chkbits;
- uint32_t *cpybits;
- uint32_t *shdbits;
- uint32_t *volsize;
- float pct;
-
- cpybits =
- kstat_value(cur->cur_set, DSW_SKSTAT_COPYBITS);
-
- shdbits =
- kstat_value(cur->cur_set, DSW_SKSTAT_SHDBITS);
-
- volsize =
- kstat_value(cur->cur_set, DSW_SKSTAT_SIZE);
-
- *volsize /= DSW_SIZE;
-
- chkbits = *cpybits >= *shdbits ? cpybits : shdbits;
-
- pct = ((float)*chkbits / *volsize) * 100.0;
-
- (void) sprintf(snpct, DATA_F62, pct);
-
- (void) strcat(data, snpct);
- }
-
- /* Master statistics */
- if (rflags & IIMG_MST) {
- char *c;
- char vol[(NAMED_LEN * 4) + 1] = {0};
- int offset;
-
- c = kstat_value(cur->cur_set, DSW_SKSTAT_MSTA);
- (void) strncat(vol, c, NAMED_LEN);
- c = kstat_value(cur->cur_set, DSW_SKSTAT_MSTB);
- (void) strncat(vol, c, NAMED_LEN);
- c = kstat_value(cur->cur_set, DSW_SKSTAT_MSTC);
- (void) strncat(vol, c, NAMED_LEN);
- c = kstat_value(cur->cur_set, DSW_SKSTAT_MSTD);
- (void) strncat(vol, c, NAMED_LEN);
-
- offset = strlen(vol) - NAMED_LEN;
-
- if (offset < 0)
- offset = 0;
-
- header();
- (void) printf(DATA_C16, vol + offset);
- (void) printf("%s", data);
- (void) printf(ROLE_INF_FMT, II_MASTER);
-
- if (*flags & DSW_MSTOFFLINE) {
- (void) printf(" <<offline>>");
- linesout++;
- } else {
- io_report(cur->cur_mst, cur->pre_mst,
- sdbc_getstat(vol + offset));
- }
-
- (void) printf("\n");
-
- if (first) {
- (void) strcpy(data, strlen(pad) > 0 ? pad : "");
- first = 0;
- }
- }
-
- /* Shadow statistics */
- if (rflags & IIMG_SHD) {
- char *c;
- char vol[(NAMED_LEN * 4) + 1] = {0};
- int offset;
-
- c = kstat_value(cur->cur_set, DSW_SKSTAT_SETA);
- (void) strncat(vol, c, NAMED_LEN);
- c = kstat_value(cur->cur_set, DSW_SKSTAT_SETB);
- (void) strncat(vol, c, NAMED_LEN);
- c = kstat_value(cur->cur_set, DSW_SKSTAT_SETC);
- (void) strncat(vol, c, NAMED_LEN);
- c = kstat_value(cur->cur_set, DSW_SKSTAT_SETD);
- (void) strncat(vol, c, NAMED_LEN);
-
- offset = strlen(vol) - NAMED_LEN;
-
- if (offset < 0)
- offset = 0;
-
- header();
- (void) printf(DATA_C16, vol + offset);
- (void) printf("%s", data);
- (void) printf(ROLE_INF_FMT, II_SHADOW);
-
- if (*flags & DSW_SHDOFFLINE) {
- (void) printf(" <<offline>>");
- linesout++;
- } else {
- io_report(cur->cur_shd, cur->pre_shd,
- sdbc_getstat(vol + offset));
- }
-
- (void) printf("\n");
-
- if (first) {
- (void) strcpy(data, strlen(pad) > 0 ? pad : "");
- first = 0;
- }
- }
-
- /* Bitmap statistics */
- if (rflags & IIMG_BMP) {
- char *c;
- char vol[(NAMED_LEN * 4) + 1] = {0};
- int offset;
-
- c = kstat_value(cur->cur_set, DSW_SKSTAT_BMPA);
- (void) strncat(vol, c, NAMED_LEN);
- c = kstat_value(cur->cur_set, DSW_SKSTAT_BMPB);
- (void) strncat(vol, c, NAMED_LEN);
- c = kstat_value(cur->cur_set, DSW_SKSTAT_BMPC);
- (void) strncat(vol, c, NAMED_LEN);
- c = kstat_value(cur->cur_set, DSW_SKSTAT_BMPD);
- (void) strncat(vol, c, NAMED_LEN);
-
- offset = strlen(vol) - NAMED_LEN;
-
- if (offset < 0)
- offset = 0;
-
- header();
- (void) printf(DATA_C16, vol + offset);
- (void) printf("%s", data);
- (void) printf(ROLE_INF_FMT, II_BITMAP);
-
- if (*flags & DSW_BMPOFFLINE) {
- (void) printf(" <<offline>>");
- linesout++;
- } else {
- io_report(cur->cur_bmp, cur->pre_bmp,
- sdbc_getstat(vol + offset));
- }
- (void) printf("\n");
-
- if (first) {
- (void) strcpy(data, strlen(pad) > 0 ? pad : "");
- first = 0;
- }
- }
-
- /* Overflow statistics */
- if (rflags & IIMG_OVR) {
- char *c;
- char msg[20] = {0};
- char vol[(NAMED_LEN * 4) + 1] = {0};
- int offset;
-
- if (cur->cur_ovr == NULL && cur->pre_ovr != NULL)
- (void) strcpy(msg, " <<attached>>");
-
- if (! (cur->collected & GOT_OVRSTAT))
- (void) strcpy(msg, " <<not attached>>");
-
- c = kstat_value(cur->cur_set, DSW_SKSTAT_OVRA);
- (void) strncpy(vol, c, NAMED_LEN);
- c = kstat_value(cur->cur_set, DSW_SKSTAT_OVRB);
- (void) strncat(vol, c, NAMED_LEN);
- c = kstat_value(cur->cur_set, DSW_SKSTAT_OVRC);
- (void) strncat(vol, c, NAMED_LEN);
- c = kstat_value(cur->cur_set, DSW_SKSTAT_OVRD);
- (void) strncat(vol, c, NAMED_LEN);
-
- offset = strlen(vol) - NAMED_LEN;
-
- if (offset < 0)
- offset = 0;
-
- header();
- (void) printf(DATA_C16, vol + offset);
- (void) printf("%s", data);
- (void) printf(ROLE_INF_FMT, II_OVERFLOW);
-
- if (strlen(msg)) {
- (void) printf("%s\n", msg);
- linesout++;
- goto next;
- }
-
- if (*flags & DSW_OVROFFLINE) {
- (void) printf(" <<offline>>");
- linesout++;
- } else {
- io_report(cur->cur_ovr, cur->pre_ovr,
- sdbc_getstat(vol + offset));
- }
-
- (void) printf("\n");
-
- if (first) {
- (void) strcpy(data, strlen(pad) > 0 ? pad : "");
- first = 0;
- }
- }
-
-
-next:
- pre = cur;
- cur = cur->next;
- }
-
- return (0);
-}
-
-/*
- * ii_add_stat() - adds a fully populated iistat_t structure
- * to the linked list of currently monitored kstats. The structure
- * will be added in alphabetical order, using the volume name of
- * the shadow volume as the key.
- *
- */
-void
-ii_add_stat(iistat_t *iistat)
-{
-
- iistat_t *cur;
-
- if (ii_top == NULL) {
- ii_top = iistat;
- return;
- }
-
- for (cur = ii_top; cur != NULL; cur = cur->next) {
- if (strcmp(cur->pre_set->ks_name,
- iistat->pre_set->ks_name) <= 0) {
- /*
- * If we get to the last item in the list, then just
- * add this one to the end
- */
- if (cur->next == NULL) {
- cur->next = iistat;
- return;
- }
-
- if (strcmp(cur->next->pre_set->ks_name,
- iistat->pre_set->ks_name) > 0) {
- iistat->next = cur->next;
- cur->next = iistat;
- return;
- }
- } else {
- if (cur == ii_top)
- ii_top = iistat;
-
- iistat->next = cur;
-
- return;
- }
- }
-}
-
-/*
- * ii_del_stat() - deallocate memory for the structure being
- * passed in.
- *
- * parameters
- * iistat_t *iistat - structure to be deallocated
- *
- * returns
- * iistat_t * - pointer to the "next" structures in the
- * linked list. May be NULL if we are removing the last
- * structure in the linked list.
- *
- */
-iistat_t *
-ii_del_stat(iistat_t *iistat)
-{
-
- iistat_t *next = iistat->next;
-
- kstat_free(iistat->pre_set);
- kstat_free(iistat->pre_mst);
- kstat_free(iistat->pre_shd);
- kstat_free(iistat->pre_bmp);
- kstat_free(iistat->pre_ovr);
- kstat_free(iistat->cur_set);
- kstat_free(iistat->cur_mst);
- kstat_free(iistat->cur_shd);
- kstat_free(iistat->cur_bmp);
- kstat_free(iistat->cur_ovr);
-
- free(iistat);
-
- return (next);
-}
-
-int
-ii_value_check(iistat_t *iistat)
-{
- if (IIMG_COMPLETE(iistat->collected))
- return (1);
-
- if (io_value_check(iistat->pre_mst->ks_data,
- iistat->cur_mst->ks_data)) {
- return (1);
- }
-
- if (io_value_check(iistat->pre_shd->ks_data,
- iistat->cur_shd->ks_data)) {
- return (1);
- }
-
- if (io_value_check(iistat->pre_bmp->ks_data,
- iistat->cur_bmp->ks_data)) {
- return (1);
- }
-
- if (iistat->pre_ovr && iistat->cur_ovr) {
- if (io_value_check(iistat->pre_ovr->ks_data,
- iistat->cur_ovr->ks_data)) {
- return (1);
- }
- }
-
- return (0);
-}
-
-int
-ii_validate(kstat_t *ksp)
-{
- if (! kstat_value(ksp, DSW_SKSTAT_MSTIO) ||
- ! kstat_value(ksp, DSW_SKSTAT_SHDIO) ||
- ! kstat_value(ksp, DSW_SKSTAT_BMPIO) ||
- ! kstat_value(ksp, DSW_SKSTAT_OVRIO) ||
- ! kstat_value(ksp, DSW_SKSTAT_FLAGS) ||
- ! kstat_value(ksp, DSW_SKSTAT_MSTA) ||
- ! kstat_value(ksp, DSW_SKSTAT_SETA) ||
- ! kstat_value(ksp, DSW_SKSTAT_BMPA) ||
- ! kstat_value(ksp, DSW_SKSTAT_OVRA) ||
- ! kstat_value(ksp, DSW_SKSTAT_SHDBITS) ||
- ! kstat_value(ksp, DSW_SKSTAT_COPYBITS) ||
- ! kstat_value(ksp, DSW_SKSTAT_SIZE))
- return (1);
-
- return (0);
-}
-
-int
-ii_vol_selected(kstat_t *ksp)
-{
- vslist_t *vslist = vs_top;
-
- for (vslist = vs_top; vslist != NULL; vslist = vslist->next) {
- char *vn;
- int off = 0;
-
- vn = ksp->ks_name;
-
- if ((off = strlen(vn) - NAMED_LEN) <= 0) {
- off = 0;
- }
-
- if (strcmp(vslist->volname, &vn[off]) == 0) {
- break;
- }
- }
-
- if (vs_top != NULL && vslist == NULL) {
- return (0);
- } else {
- return (1);
- }
-}
diff --git a/usr/src/cmd/avs/dsstat/ii_stats.h b/usr/src/cmd/avs/dsstat/ii_stats.h
deleted file mode 100644
index 35307b4b95..0000000000
--- a/usr/src/cmd/avs/dsstat/ii_stats.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _II_STATS_H
-#define _II_STATS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define GOT_SETSTAT 0x01
-#define GOT_MSTSTAT 0x02
-#define GOT_SHDSTAT 0x04
-#define GOT_BMPSTAT 0x08
-#define GOT_OVRSTAT 0x10
-
-#define GOT_COMPLETE_IIMG (GOT_SETSTAT|GOT_MSTSTAT|GOT_SHDSTAT|GOT_BMPSTAT)
-
-#define IIMG_COMPLETE(x) (((x) & (GOT_COMPLETE_IIMG)) != (GOT_COMPLETE_IIMG))
-
-/* II strings */
-#define II_KSTAT_MODULE "ii"
-#define II_KSTAT_CLASS "iiset"
-
-#define II_DISABLED "<<set disabled>>"
-#define II_INDEPENDENT "I"
-#define II_DEPENDENT "D"
-#define II_COPYING "C"
-#define II_MASTER "mst"
-#define II_SHADOW "shd"
-#define II_BITMAP "bmp"
-#define II_OVERFLOW "ovr"
-
-
-typedef struct iistat_s
-{
- kstat_t *pre_set;
- kstat_t *pre_mst;
- kstat_t *pre_shd;
- kstat_t *pre_bmp;
- kstat_t *pre_ovr;
- kstat_t *cur_set;
- kstat_t *cur_mst;
- kstat_t *cur_shd;
- kstat_t *cur_bmp;
- kstat_t *cur_ovr;
- int collected;
- struct iistat_s *next;
-} iistat_t;
-
-/* Prototypes */
-int ii_discover(kstat_ctl_t *);
-int ii_update(kstat_ctl_t *);
-int ii_report();
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _II_STATS_H */
diff --git a/usr/src/cmd/avs/dsstat/multi_stats.c b/usr/src/cmd/avs/dsstat/multi_stats.c
deleted file mode 100644
index cac76d4cd6..0000000000
--- a/usr/src/cmd/avs/dsstat/multi_stats.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <stdio.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include <kstat.h>
-
-#include "ii_stats.h"
-#include "sdbc_stats.h"
-#include "sndr_stats.h"
-
-#include "multi_stats.h"
-
-#include "dsstat.h"
-#include "common.h"
-#include "report.h"
-
-/*
- * do_stats() - called by main() to start monitoring
- *
- */
-int
-do_stats()
-{
- int error;
- int pass;
-
- /* Collection/reporting loop */
- for (pass = 0; ; pass++) { /* CSTYLED */
- if (iterations != -1 && pass >= iterations)
- return (0);
-
- error = discover();
-
- if (error == ENOMEM || error == EINVAL)
- return (error);
-
- if (error == EAGAIN && pass == 0)
- return (error);
-
- (void) sleep(interval);
-
- if ((error = update()) != 0)
- return (error);
-
- if (report())
- break;
- }
-
- /* No stats on this system */
- return (EAGAIN);
-}
-
-int
-discover()
-{
- int err = 0;
-
- int sdbc_err = 0;
- int sndr_err = 0;
- int ii_err = 0;
-
- kstat_ctl_t *kc;
-
- if ((kc = kstat_open()) == NULL)
- return (ENOMEM);
-
- if (mode & SDBC) {
- sdbc_err = sdbc_discover(kc);
- err = sdbc_err;
- if (sdbc_err && !(mode & MULTI))
- goto fail;
- if (sdbc_err && (mode & MULTI) && sdbc_err != EAGAIN)
- goto fail;
- }
-
- if (mode & SNDR) {
- sndr_err = sndr_discover(kc);
- err = sndr_err;
- if (sndr_err && !(mode & MULTI))
- goto fail;
- if (sndr_err && (mode & MULTI) && sndr_err != EAGAIN)
- goto fail;
- }
-
- if (mode & IIMG) {
- ii_err = ii_discover(kc);
- err = ii_err;
- if (ii_err && !(mode & MULTI))
- goto fail;
- if (ii_err && ii_err != EAGAIN && (mode & MULTI))
- goto fail;
- }
-
- (void) kstat_close(kc);
- if (sdbc_err && sndr_err && ii_err)
- return (err);
- else
- return (0);
-
-fail:
- (void) kstat_close(kc);
- return (err);
-}
-
-int
-update()
-{
- int err = 0;
-
- int sdbc_err = 0;
- int sndr_err = 0;
- int ii_err = 0;
-
- kstat_ctl_t *kc;
-
- if ((kc = kstat_open()) == NULL)
- goto fail;
-
- if (mode & SDBC) {
- sdbc_err = sdbc_update(kc);
- err = sdbc_err;
- if (sdbc_err && !(mode & MULTI))
- goto fail;
- if (sdbc_err && (mode & MULTI) && sdbc_err != EAGAIN)
- goto fail;
- }
-
- if (mode & SNDR) {
- sndr_err = sndr_update(kc);
- err = sndr_err;
- if (sndr_err && !(mode & MULTI))
- goto fail;
- if (sndr_err && (mode & MULTI) && sndr_err != EAGAIN)
- goto fail;
- }
-
- if (mode & IIMG) {
- ii_err = ii_update(kc);
- err = ii_err;
- if (ii_err && !(mode & MULTI))
- goto fail;
- if (ii_err && (mode & MULTI) && ii_err != EAGAIN)
- goto fail;
- }
-
- (void) kstat_close(kc);
- if (sdbc_err && sndr_err && ii_err)
- return (err);
- else
- return (0);
-
-fail:
- (void) kstat_close(kc);
- return (err);
-}
-
-int
-report()
-{
- int err = 0;
-
- int sdbc_err = 0;
- int sndr_err = 0;
- int ii_err = 0;
-
- hflags &= (HEADERS_EXL | HEADERS_ATT | HEADERS_BOR);
-
- if (mode & SNDR)
- if (sndr_err = sndr_report())
- err = sndr_err;
-
- if (mode & IIMG)
- if (ii_err = ii_report())
- err = ii_err;
-
- if ((mode & SDBC) && !(mode & MULTI))
- if (sdbc_err = sdbc_report())
- err = sdbc_err;
-
- return (err);
-}
diff --git a/usr/src/cmd/avs/dsstat/multi_stats.h b/usr/src/cmd/avs/dsstat/multi_stats.h
deleted file mode 100644
index 2c092d4fab..0000000000
--- a/usr/src/cmd/avs/dsstat/multi_stats.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _MULTI_STATS_H
-#define _MULTI_STATS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Prototypes */
-int do_stats();
-int discover();
-int update();
-int report();
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _MULTI_STATS_H */
diff --git a/usr/src/cmd/avs/dsstat/report.c b/usr/src/cmd/avs/dsstat/report.c
deleted file mode 100644
index 4b91c255d5..0000000000
--- a/usr/src/cmd/avs/dsstat/report.c
+++ /dev/null
@@ -1,439 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <stdio.h>
-#include <string.h>
-
-#include <kstat.h>
-#include <sys/inttypes.h>
-
-#include <nsctl.h>
-
-#include "dsstat.h"
-#include "common.h"
-
-#include "sdbc_stats.h"
-#include "report.h"
-
-extern short dflags;
-
-/*
- * Return the number of ticks delta between two hrtime_t
- * values. Attempt to cater for various kinds of overflow
- * in hrtime_t - no matter how improbable.
- */
-uint64_t
-hrtime_delta(hrtime_t old, hrtime_t new)
-{
-
- uint64_t del;
-
- if ((new >= old) && (old >= 0L)) {
- return (new - old);
- } else {
- /*
- * We've overflowed the positive portion of an
- * hrtime_t.
- */
- if (new < 0L) {
- /*
- * The new value is negative. Handle the
- * case where the old value is positive or
- * negative.
- */
- uint64_t n1;
- uint64_t o1;
-
- n1 = -new;
-
- if (old > 0L) {
- return (n1 - old);
- } else {
- o1 = -old;
- del = n1 - o1;
- return (del);
- }
- } else {
- /*
- * Either we've just gone from being negative
- * to positive *or* the last entry was positive
- * and the new entry is also positive but *less*
- * than the old entry. This implies we waited
- * quite a few days on a very fast system between
- * iostat displays.
- */
- if (old < 0L) {
- uint64_t o2;
-
- o2 = -old;
- del = UINT64_MAX - o2;
- } else {
- del = UINT64_MAX - old;
- }
-
- del += new;
-
- return (del);
- }
- }
-}
-
-/*
- * Take the difference of an unsigned 32
- * bit int attempting to cater for
- * overflow.
- */
-uint32_t
-u32_delta(uint32_t old, uint32_t new)
-{
-
- if (new >= old)
- return (new - old);
- else
- return ((UINT32_MAX - old) + new + 1);
-}
-
-/*
- * Take the difference of an unsigned 64
- * bit int attempting to cater for
- * overflow.
- */
-uint64_t
-u64_delta(uint64_t old, uint64_t new)
-{
-
- if (new >= old)
- return (new - old);
- else
- return ((UINT64_MAX - old) + new + 1);
-}
-
-/*
- * io_report() - diffs and reports data contained in
- * kstat_io_t structures.
- *
- * parameters
- * kstat_io_t *cur - pointer to current data
- *
- * kstat_io_t *pre - pointer to data as it was
- * at the beginning of an interval.
- */
-void
-io_report(kstat_t *cur_kstat, kstat_t *pre_kstat, sdbcstat_t *sdbcstat)
-{
- sdbcvals_t vals;
-
- double rd_cnt, wr_cnt;
- double rd_kb, wr_kb, hr_etime;
-
- double rtm, tps, avs, etime;
-
- kstat_io_t *cur = cur_kstat->ks_data;
- kstat_io_t *pre = pre_kstat->ks_data;
-
- if (sdbcstat &&
- sdbc_getvalues(sdbcstat, &vals, (SDBC_KBYTES | SDBC_INTAVG)))
- return;
-
- /* Time */
- hr_etime = hrtime_delta(pre_kstat->ks_snaptime, cur_kstat->ks_snaptime);
- etime = hr_etime / (double)NANOSEC;
-
- /* Read count */
- rd_cnt = (double)u32_delta(pre->reads, cur->reads);
- if (rd_cnt) rd_cnt /= etime;
-
- /* Bytes read */
- rd_kb = (double)u64_delta(pre->nread, cur->nread) / KILOBYTE;
- if (rd_kb) rd_kb /= etime;
-
- /* Write count */
- wr_cnt = (double)u32_delta(pre->writes, cur->writes);
- if (wr_cnt) wr_cnt /= etime;
-
- /* Bytes written */
- wr_kb = (double)u64_delta(pre->nwritten, cur->nwritten) / KILOBYTE;
- if (wr_kb) wr_kb /= etime;
-
- /* Calculate service times */
- avs = (double)hrtime_delta(pre->rlentime, cur->rlentime) / hr_etime;
- tps = (double)rd_cnt + wr_cnt;
-
- if (tps > 0)
- rtm = (1000 / tps) * avs;
- else
- rtm = 0.0;
-
- /* Output */
- if (dflags & SUMMARY) {
- if ((mode & MULTI) && (mode & SDBC)) {
- if (sdbcstat) {
- (void) printf(KPS_INF_FMT,
- (float)vals.total_cache);
- (void) printf(KPS_INF_FMT,
- (float)vals.total_disk);
- } else {
- (void) printf(DATA_C6, NO_INFO);
- (void) printf(KPS_INF_FMT, rd_kb + wr_kb);
- }
- } else
- (void) printf(KPS_INF_FMT, rd_kb + wr_kb);
-
- (void) printf(TPS_INF_FMT, (uint32_t)(rd_cnt + wr_cnt));
- (void) printf(SVT_INF_FMT, rtm);
-
- goto done;
- }
-
- if (dflags & READ) {
- if ((mode & MULTI) && (mode & SDBC)) {
- if (sdbcstat) {
- (void) printf(KPS_INF_FMT,
- (float)vals.cache_read);
- (void) printf(KPS_INF_FMT,
- (float)vals.disk_read);
- } else {
- (void) printf(DATA_C6, NO_INFO);
- (void) printf(KPS_INF_FMT, rd_kb);
- }
-
- } else
- (void) printf(KPS_INF_FMT, rd_kb);
-
- (void) printf(TPS_INF_FMT, (uint32_t)rd_cnt);
- }
-
- if (dflags & WRITE) {
- if ((mode & MULTI) && (mode & SDBC)) {
- if (sdbcstat) {
- (void) printf(KPS_INF_FMT,
- (float)vals.cache_write);
- (void) printf(KPS_INF_FMT,
- (float)vals.disk_write);
- } else {
- (void) printf(DATA_C6, NO_INFO);
- (void) printf(KPS_INF_FMT, wr_kb);
- }
-
- } else
- (void) printf(KPS_INF_FMT, wr_kb);
-
- (void) printf(TPS_INF_FMT, (uint32_t)wr_cnt);
- }
-
- if (dflags & TIMING) {
- (void) printf(SVT_INF_FMT, rtm);
- }
-
-done:
- linesout++;
-}
-
-int
-io_value_check(kstat_io_t *pre, kstat_io_t *cur)
-{
- if (u32_delta(pre->reads, cur->reads))
- return (1);
- if (u32_delta(pre->writes, cur->writes))
- return (1);
-
- return (0);
-}
-
-/*
- * cd_report() - reports cache desriptor related statistics
- * based on the dflags global variable
- *
- * parameters
- * sdbcstat_t *sdbcstat - pointer to the cache structure
- * to be reported on.
- */
-void
-cd_report(sdbcstat_t *sdbcstat)
-{
- sdbcvals_t vals;
-
- /* Extract statistics, average for time */
- if (sdbc_getvalues(sdbcstat, &vals, (SDBC_KBYTES | SDBC_INTAVG)))
- return;
-
- /* Output */
- if (rflags & MULTI) {
- (void) printf(VOL_HDR_FMT, "");
-
- if (dflags & FLAGS) {
- (void) printf(STAT_HDR_FMT, "");
- (void) printf(STAT_HDR_FMT, "");
- }
-
- if (dflags & PCTS)
- (void) printf(PCT_HDR_FMT, "");
-
- if (dflags & SUMMARY) {
- (void) printf(KPS_INF_FMT, (float)vals.total_cache);
- (void) printf(DATA_C4, NO_INFO);
- (void) printf(DATA_C4, NO_INFO);
- (void) printf("\n");
- linesout++;
- return;
- }
-
- if (dflags & READ) {
- (void) printf(KPS_INF_FMT, (float)vals.cache_read);
- (void) printf(DATA_C4, NO_INFO);
- }
-
- if (dflags & WRITE) {
- (void) printf(KPS_INF_FMT, (float)vals.cache_write);
- (void) printf(DATA_C4, NO_INFO);
- }
-
- if (dflags & TIMING) {
- (void) printf(DATA_C4, NO_INFO);
- }
-
- linesout++;
- (void) printf("\n");
- return;
- }
-
- if (dflags & SUMMARY) {
- (void) printf(DATA_I32, vals.total_cache);
- (void) printf(DATA_I32, vals.total_disk);
- (void) printf(HIT_INF_FMT, vals.cache_hit);
-
- linesout++;
- (void) printf("\n");
- return;
- }
-
- if (dflags & READ) {
- (void) printf(DATA_I32, vals.cache_read);
- (void) printf(DATA_I32, vals.disk_read);
- (void) printf(HIT_INF_FMT, vals.read_hit);
- }
-
- if (dflags & WRITE) {
- (void) printf(DATA_I32, vals.cache_write);
- (void) printf(DATA_I32, vals.disk_write);
- (void) printf(HIT_INF_FMT, vals.write_hit);
- }
-
- if (dflags & DESTAGED)
- (void) printf(DATA_I32, vals.destaged);
-
- if (dflags & WRCANCEL)
- (void) printf(DATA_I32, vals.write_cancellations);
-
- linesout++;
- (void) printf("\n");
-}
-
-/*
- * header() - outputs an appropriate header by referencing the
- * global variables dflsgs and rflags
- *
- */
-void
-header()
-{
- if (hflags & HEADERS_EXL)
- if ((linesout % DISPLAY_LINES) != 0)
- return;
-
- if (hflags & HEADERS_BOR)
- if (linesout != 0)
- return;
-
- if (hflags & HEADERS_ATT)
- if (hflags & HEADERS_OUT)
- return;
- else
- hflags |= HEADERS_OUT;
-
- if (linesout)
- (void) printf("\n");
-
- (void) printf(VOL_HDR_FMT, SET_HDR_TXT);
-
- if (dflags & FLAGS) {
- (void) printf(STAT_HDR_FMT, TYPE_HDR_TXT);
- (void) printf(STAT_HDR_FMT, STAT_HDR_TXT);
- }
-
- if (dflags & ASYNC_QUEUE)
- (void) printf(STAT_HDR_FMT, QUEUE_HDR_TXT);
-
- if (dflags & PCTS)
- (void) printf(PCT_HDR_FMT, PCT_HDR_TXT);
-
- (void) printf(ROLE_HDR_FMT, ROLE_HDR_TXT);
-
- if (dflags & ASYNC_QUEUE) {
- (void) printf(TPS_HDR_FMT, QUEUE_ITEMS_TXT);
- (void) printf(KPS_HDR_FMT, QUEUE_KBYTES_TXT);
- (void) printf(TPS_HDR_FMT, QUEUE_ITEMS_HW_TXT);
- (void) printf(KPS_HDR_FMT, QUEUE_KBYTES_HW_TXT);
- }
-
- if (dflags & SUMMARY) {
- if ((mode & MULTI) && (mode & SDBC)) {
- (void) printf(KPS_HDR_FMT, CKPS_HDR_TXT);
- (void) printf(KPS_HDR_FMT, DKPS_HDR_TXT);
- } else
- (void) printf(KPS_HDR_FMT, KPS_HDR_TXT);
- (void) printf(TPS_HDR_FMT, TPS_HDR_TXT);
- (void) printf(SVT_HDR_FMT, SVT_HDR_TXT);
-
- (void) printf("\n");
-
- return;
- }
-
- if (dflags & READ) {
- if ((mode & MULTI) && (mode & SDBC)) {
- (void) printf(KPS_HDR_FMT, CRKPS_HDR_TXT);
- (void) printf(KPS_HDR_FMT, DRKPS_HDR_TXT);
- } else
- (void) printf(KPS_HDR_FMT, RKPS_HDR_TXT);
-
- (void) printf(TPS_HDR_FMT, RTPS_HDR_TXT);
- }
-
- if (dflags & WRITE) {
- if ((mode & MULTI) && (mode & SDBC)) {
- (void) printf(KPS_HDR_FMT, CWKPS_HDR_TXT);
- (void) printf(KPS_HDR_FMT, DWKPS_HDR_TXT);
- } else
- (void) printf(KPS_HDR_FMT, WKPS_HDR_TXT);
-
- (void) printf(TPS_HDR_FMT, WTPS_HDR_TXT);
- }
-
- if (dflags & TIMING)
- (void) printf(SVT_HDR_FMT, SVT_HDR_TXT);
-
- (void) printf("\n");
-}
diff --git a/usr/src/cmd/avs/dsstat/report.h b/usr/src/cmd/avs/dsstat/report.h
deleted file mode 100644
index 56f7a21cb8..0000000000
--- a/usr/src/cmd/avs/dsstat/report.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _REPORT_H
-#define _REPORT_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Prototypes */
-uint64_t hrtime_delta(hrtime_t, hrtime_t);
-uint32_t u32_delta(uint32_t, uint32_t);
-uint64_t u64_delta(uint64_t, uint64_t);
-void io_report(kstat_t *, kstat_t *, sdbcstat_t *);
-int io_value_check(kstat_io_t *, kstat_io_t *);
-void cd_report(sdbcstat_t *);
-void header();
-
-/* BEGIN CSTYLED */
-/* END CSTYLED */
-
-#define VOL_HDR_FMT "%-16s"
-#define VOL_HDR_SIZE 17
-#define SET_HDR_TXT "name"
-
-#define STAT_HDR_FMT "%3s"
-#define STAT_HDR_SIZE 3
-#define STAT_HDR_TXT "s"
-#define TYPE_HDR_TXT "t"
-
-#define ROLE_HDR_FMT "%5s"
-#define ROLE_HDR_SIZE 5
-#define ROLE_INF_FMT " %4s"
-#define ROLE_HDR_TXT "role"
-
-#define PCT_HDR_FMT "%7s"
-#define PCT_HDR_SIZE 7
-#define PCT_INF_FMT " %6.2f"
-#define SN_HDR_TXT "sn"
-#define PCT_HDR_TXT "pct"
-
-#define KPS_HDR_FMT "%7s"
-#define KPS_HDR_SIZE 7
-#define KPS_INF_FMT " %6.0f"
-#define KPS_HDR_TXT "kps"
-#define RKPS_HDR_TXT "rkps"
-#define WKPS_HDR_TXT "wkps"
-#define CKPS_HDR_TXT "ckps"
-#define DKPS_HDR_TXT "dkps"
-#define CRKPS_HDR_TXT "crkps"
-#define CWKPS_HDR_TXT "cwkps"
-#define DRKPS_HDR_TXT "drkps"
-#define DWKPS_HDR_TXT "dwkps"
-
-#define TPS_HDR_FMT "%6s"
-#define TPS_HDR_SIZE 6
-#define TPS_INF_FMT " %5u"
-#define TPS_HDR_TXT "tps"
-#define RTPS_HDR_TXT "rtps"
-#define WTPS_HDR_TXT "wtps"
-
-#define SVT_HDR_FMT "%5s"
-#define SVT_HDR_SIZE 5
-#define SVT_INF_FMT " %4.0f"
-#define SVT_HDR_TXT "svt"
-
-#define HIT_HDR_FMT "%6s"
-#define HIT_HDR_SIZE 6
-#define HIT_INF_FMT " %5.1f"
-#define HIT_PAD_FMT " %5s"
-#define HIT_HDR_TXT "hit"
-#define RHIT_HDR_TXT "rhit"
-#define WHIT_HDR_TXT "whit"
-
-#define QUEUE_HDR_TXT "q"
-#define QUEUE_ITEMS_TXT "qi"
-#define QUEUE_KBYTES_TXT "qk"
-#define QUEUE_ITEMS_HW_TXT "qhwi"
-#define QUEUE_KBYTES_HW_TXT "qhwk"
-
-#define NO_INFO "-"
-
-#define DATA_C16 "%-16s"
-#define DATA_C2 " %2s"
-#define DATA_C4 " %4s"
-#define DATA_C5 " %5s"
-#define DATA_C6 " %6s"
-#define DATA_I32 " %6u"
-#define DATA_I64 " %6llu"
-#define DATA_F62 " %6.2f"
-#define DATA_F60 " %6.0f"
-#define DATA_F50 " %5.0f"
-#define DATA_F40 " %4.0f"
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _REPORT_H */
diff --git a/usr/src/cmd/avs/dsstat/sdbc_stats.c b/usr/src/cmd/avs/dsstat/sdbc_stats.c
deleted file mode 100644
index f1af1acdd0..0000000000
--- a/usr/src/cmd/avs/dsstat/sdbc_stats.c
+++ /dev/null
@@ -1,788 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <inttypes.h>
-
-#include <kstat.h>
-
-#include <sys/nsctl/nsctl.h>
-#include <sys/nsctl/sd_bcache.h>
-
-#include "sdbc_stats.h"
-
-#include "dsstat.h"
-#include "common.h"
-#include "report.h"
-
-static sdbcstat_t *sdbc_top;
-kstat_t *sdbc_global = NULL;
-
-void sdbc_header();
-int sdbc_value_check(sdbcstat_t *);
-int sdbc_validate(kstat_t *);
-uint32_t sdbc_getdelta(sdbcstat_t *, char *);
-
-void sdbc_addstat(sdbcstat_t *);
-sdbcstat_t *sdbc_delstat(sdbcstat_t *);
-void center(int, char *);
-
-/*
- * sdbc_discover() - looks for new statistics to be monitored.
- * Verifies that any statistics found are now already being
- * monitored.
- *
- */
-int
-sdbc_discover(kstat_ctl_t *kc)
-{
- static int validated = 0;
-
- kstat_t *ksp;
-
- for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {
- int kinst;
- char kname[KSTAT_STRLEN + 1];
- sdbcstat_t *cur;
- sdbcstat_t *sdbcstat = NULL;
- kstat_t *io_ksp;
-
- if (strcmp(ksp->ks_module, SDBC_KSTAT_MODULE) != 0 ||
- strncmp(ksp->ks_name, SDBC_KSTAT_CDSTATS, 2) != 0)
- continue;
-
- if (kstat_read(kc, ksp, NULL) == -1)
- continue;
-
- /*
- * Validate kstat structure
- */
- if (! validated) {
- if (sdbc_validate(ksp))
- return (EINVAL);
-
- validated++;
- }
-
- /*
- * Duplicate check
- */
- for (cur = sdbc_top; cur; cur = cur->next) {
- char *cur_vname, *tst_vname;
-
- cur_vname = kstat_value(cur->pre_set,
- SDBC_CDKSTAT_VOL_NAME);
-
- tst_vname = kstat_value(ksp,
- SDBC_CDKSTAT_VOL_NAME);
-
- if (strncmp(cur_vname, tst_vname, NAMED_LEN) == 0)
- goto next;
- }
-
- /*
- * Initialize new record
- */
- sdbcstat = (sdbcstat_t *)calloc(1, sizeof (sdbcstat_t));
-
- kinst = ksp->ks_instance;
-
- /*
- * Set kstat
- */
- sdbcstat->pre_set = kstat_retrieve(kc, ksp);
-
- if (sdbcstat->pre_set == NULL)
- goto next;
-
- sdbcstat->collected |= GOT_SET_KSTAT;
-
- /*
- * I/O kstat
- */
- (void) sprintf(kname, "%s%d", SDBC_IOKSTAT_CDSTATS, kinst);
-
- io_ksp = kstat_lookup(kc, SDBC_KSTAT_MODULE, kinst, kname);
- sdbcstat->pre_io = kstat_retrieve(kc, io_ksp);
-
- if (sdbcstat->pre_io == NULL)
- goto next;
-
- sdbcstat->collected |= GOT_IO_KSTAT;
-
-next:
- /*
- * Check if we got a complete set of stats
- */
- if (sdbcstat == NULL)
- continue;
-
- if (SDBC_COMPLETE(sdbcstat->collected)) {
- (void) sdbc_delstat(sdbcstat);
- continue;
- }
-
- sdbc_addstat(sdbcstat);
- }
-
- if (sdbc_top == NULL)
- return (EAGAIN);
-
- return (0);
-}
-
-/*
- * sdbc_update() - updates all of the statistics currently being monitored.
- *
- */
-int
-sdbc_update(kstat_ctl_t *kc)
-{
- kstat_t *ksp;
- sdbcstat_t *cur;
-
- /* Update global kstat information */
- ksp = kstat_lookup(kc, SDBC_KSTAT_MODULE, -1, SDBC_KSTAT_GSTATS);
-
- if (ksp == NULL)
- return (EAGAIN);
-
- if (sdbc_global)
- kstat_free(sdbc_global);
-
- sdbc_global = kstat_retrieve(kc, ksp);
-
- for (cur = sdbc_top; cur != NULL; cur = cur->next) {
- int kinst;
- char *kname, *cname, *pname;
-
- kstat_t *set_ksp, *io_ksp;
-
- cur->collected = 0;
-
- /*
- * Age off old stats
- */
- if (cur->cur_set != NULL) {
- kstat_free(cur->pre_set);
- kstat_free(cur->pre_io);
-
- cur->pre_set = cur->cur_set;
- cur->pre_io = cur->cur_io;
- }
-
- /*
- * Update set kstat
- */
- kinst = cur->pre_set->ks_instance;
- kname = cur->pre_set->ks_name;
-
- set_ksp = kstat_lookup(kc, SDBC_KSTAT_MODULE, kinst, kname);
-
- if ((cur->cur_set = kstat_retrieve(kc, set_ksp)) == NULL)
- continue;
-
- cur->collected |= GOT_SET_KSTAT;
-
- /*
- * Validate set
- */
- pname = kstat_value(cur->pre_set, SDBC_CDKSTAT_VOL_NAME);
- cname = kstat_value(cur->cur_set, SDBC_CDKSTAT_VOL_NAME);
-
- if (strncmp(pname, cname, NAMED_LEN) != 0)
- continue;
-
- /*
- * Update I/O kstat
- */
- kinst = cur->pre_io->ks_instance;
- kname = cur->pre_io->ks_name;
-
- io_ksp = kstat_lookup(kc, SDBC_KSTAT_MODULE, kinst, kname);
-
- if ((cur->cur_io = kstat_retrieve(kc, io_ksp)) == NULL)
- continue;
-
- cur->collected |= GOT_IO_KSTAT;
- }
-
- return (0);
-}
-
-/*
- * sdbc_report() - outputs statistics for the statistics currently being
- * monitored. Deletes statistics for volumes that have been disabled.
- *
- */
-int
-sdbc_report()
-{
- vslist_t *vslist = vs_top;
- sdbcstat_t *cur, *pre = NULL;
-
- if (sdbc_top == NULL)
- return (0);
-
- for (cur = sdbc_top; cur != NULL; ) { /* CSTYLED */
- static uint32_t linesout = 0;
- uint32_t *offline;
-
- char volname[NAMED_LEN + 1];
- char rmode[STAT_HDR_SIZE];
- char wmode[STAT_HDR_SIZE];
-
- /* Parse volume name */
- (void) strncpy(volname, kstat_value(cur->pre_set,
- SDBC_CDKSTAT_VOL_NAME), NAMED_LEN);
- volname[NAMED_LEN] = '\0';
-
- /* Check to see if the user specified this volume */
- for (vslist = vs_top; vslist != NULL; vslist = vslist->next)
- if (strcmp(volname, vslist->volname) == 0)
- break;
-
- if (vs_top != NULL && vslist == NULL)
- goto next;
-
- /* Check if volume is offline and zflag applies */
- if (zflag && sdbc_value_check(cur) == 0)
- goto next;
-
- /* Output volume name */
- sdbc_header();
-
- (void) printf(DATA_C16, volname);
-
- if (SDBC_COMPLETE(cur->collected)) {
- sdbcstat_t *next = sdbc_delstat(cur);
-
- if (! pre)
- cur = sdbc_top = next;
- else
- cur = pre->next = next;
-
- (void) printf(" <<volume disabled>>\n");
- continue;
- }
-
- offline = kstat_value(cur->cur_set, SDBC_CDKSTAT_FAILED);
- if (*offline) {
- (void) printf(" <<volume offline>>\n");
- linesout++;
- goto next;
- }
-
- /* Type/status flags */
- if (dflags & FLAGS) {
-
- uint32_t *dhint, *nhint;
- uint32_t hints;
-
- dhint = kstat_value(cur->cur_set, SDBC_CDKSTAT_CDHINTS);
- nhint = kstat_value(sdbc_global, SDBC_GKSTAT_NODEHINTS);
-
- if (! nhint)
- return (EINVAL);
-
- hints = *nhint;
- hints &= (NSC_FORCED_WRTHRU | NSC_NO_FORCED_WRTHRU |
- NSC_NOCACHE);
- hints |= *dhint;
-
- if (hints & NSC_NOCACHE)
- (void) strcpy(rmode, "D");
- else
- (void) strcpy(rmode, "C");
-
- if ((hints & NSC_FORCED_WRTHRU) || (hints & NSC_WRTHRU))
- (void) strcpy(wmode, "D");
- else
- (void) strcpy(wmode, "C");
-
- (void) printf(DATA_C2, rmode);
- (void) printf(DATA_C2, wmode);
- }
-
- /* Output set information */
- cd_report(cur);
-
-next:
- pre = cur;
- cur = cur->next;
- }
-
- return (0);
-}
-
-/*
- * sdbc_header() - outputs an appropriate header by referencing the
- * global variables dflsgs
- *
- */
-void
-sdbc_header()
-{
- int rcount = 0;
-
- if (hflags == HEADERS_EXL)
- if ((linesout % DISPLAY_LINES) != 0)
- return;
-
- if (hflags == HEADERS_BOR)
- if (linesout != 0)
- return;
-
- if (hflags & HEADERS_ATT)
- if (hflags & HEADERS_OUT)
- return;
- else
- hflags |= HEADERS_OUT;
-
- if (linesout)
- (void) printf("\n");
-
- /* first line header */
- if (! (dflags & SUMMARY) && dflags != FLAGS) {
-
- (void) printf(VOL_HDR_FMT, " ");
-
- if (dflags & FLAGS) {
- (void) printf(STAT_HDR_FMT, " ");
- (void) printf(STAT_HDR_FMT, " ");
- }
-
- if (dflags & READ) {
- int size;
-
- size = KPS_HDR_SIZE * 2 + HIT_HDR_SIZE;
- center(size, "- read -");
- rcount++;
- }
-
- if (dflags & WRITE) {
- int size;
-
- size = KPS_HDR_SIZE * 2 + HIT_HDR_SIZE;
- center(size, "- write -");
- rcount++;
- }
-
- if (dflags != FLAGS)
- (void) printf("\n");
- }
-
- /* second line header */
- (void) printf(VOL_HDR_FMT, "volume");
-
- if (dflags & FLAGS) {
- (void) printf(STAT_HDR_FMT, "rd");
- (void) printf(STAT_HDR_FMT, "wr");
- }
-
- if (dflags & SUMMARY) {
- (void) printf(KPS_HDR_FMT, "ckps");
- (void) printf(KPS_HDR_FMT, "dkps");
- (void) printf(HIT_HDR_FMT, HIT_HDR_TXT);
-
- goto out;
- }
-
- if (dflags & READ) {
- (void) printf(KPS_HDR_FMT, "ckps");
- (void) printf(KPS_HDR_FMT, "dkps");
- (void) printf(HIT_HDR_FMT, RHIT_HDR_TXT);
- }
-
- if (dflags & WRITE) {
- (void) printf(KPS_HDR_FMT, "ckps");
- (void) printf(KPS_HDR_FMT, "dkps");
- (void) printf(HIT_HDR_FMT, WHIT_HDR_TXT);
- }
-
- if (dflags & DESTAGED)
- (void) printf(KPS_HDR_FMT, "dstg");
-
- if (dflags & WRCANCEL)
- (void) printf(KPS_HDR_FMT, "cwrl");
-
-out:
- (void) printf("\n");
-}
-
-/*
- * sdbc_getstat() - find cache stat by name matching
- *
- * paraemters
- * char *vn - the volume name to match against
- * returns
- * sdbcstat_t * - the matching strcture, NULL if not found
- */
-sdbcstat_t *
-sdbc_getstat(char *vn)
-{
- sdbcstat_t *cur, *pre = NULL;
-
- for (cur = sdbc_top; cur; ) { /* CSTYLED */
- char *volname =
- kstat_value(cur->pre_set, SDBC_CDKSTAT_VOL_NAME);
-
- if (SDBC_COMPLETE(cur->collected)) {
- sdbcstat_t *next = sdbc_delstat(cur);
-
- if (! pre)
- cur = sdbc_top = next;
- else
- cur = pre->next = next;
-
- continue;
- }
-
- if (strncmp(volname, vn, NAMED_LEN) == 0)
- return (cur);
-
- pre = cur;
- cur = cur->next;
- }
-
- return (NULL);
-}
-
-/*
- * sdbc_addstat() - adds a fully populated sdbcstat_t structure
- * to the linked list of currently monitored kstats. The structure
- * will be added in alphabetical order, using the volume name as the
- * key.
- *
- * parameters
- * sdbcstat_t *sdbcstat - to be added to the list.
- *
- */
-void
-sdbc_addstat(sdbcstat_t *sdbcstat)
-{
- sdbcstat_t *cur;
-
- if (sdbc_top == NULL) {
- sdbc_top = sdbcstat;
- return;
- }
-
- for (cur = sdbc_top; cur != NULL; cur = cur->next) {
- char *cur_vname, *nxt_vname, *tst_vname;
-
- cur_vname = kstat_value(cur->pre_set,
- SDBC_CDKSTAT_VOL_NAME);
- tst_vname = kstat_value(sdbcstat->pre_set,
- SDBC_CDKSTAT_VOL_NAME);
-
- if (strncmp(cur_vname, tst_vname, NAMED_LEN) > 0) {
- if (cur == sdbc_top)
- sdbc_top = sdbcstat;
-
- sdbcstat->next = cur;
-
- return;
- }
-
- /*
- * If we get to the last item in the list, then just
- * add this one to the end
- */
- if (cur->next == NULL) {
- cur->next = sdbcstat;
- return;
- }
-
- nxt_vname = kstat_value(cur->next->pre_set,
- SDBC_CDKSTAT_VOL_NAME);
-
- if (strncmp(nxt_vname, tst_vname, NAMED_LEN) > 0) {
- sdbcstat->next = cur->next;
- cur->next = sdbcstat;
- return;
- }
- }
-}
-
-/*
- * sdbc_delstat() - deallocate memory for the structure being
- * passed in.
- *
- * parameters
- * sdbcstat_t *sdbcstat - structure to be deallocated
- *
- * returns
- * sdbcstat_t * - pointer to the "next" structures in the
- * linked list. May be NULL if we are removing the last
- * structure in the linked list.
- */
-sdbcstat_t *
-sdbc_delstat(sdbcstat_t *sdbcstat)
-{
-
- sdbcstat_t *next = sdbcstat->next;
-
- kstat_free(sdbcstat->pre_set);
- kstat_free(sdbcstat->pre_io);
- kstat_free(sdbcstat->cur_set);
- kstat_free(sdbcstat->cur_io);
-
- free(sdbcstat);
- sdbcstat = NULL;
-
- return (next);
-}
-
-/*
- * sdbc_value_check() - Checks for activity, supports -z switch
- *
- * parameters
- * sdbcstat_t *sdbcstat - structure to be checked
- *
- * returns
- * 1 - activity
- * 0 - no activity
- */
-int
-sdbc_value_check(sdbcstat_t *sdbcstat)
-{
- if (SDBC_COMPLETE(sdbcstat->collected))
- return (1);
-
- if (sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_CACHE_READ) != 0)
- return (1);
-
- if (sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_DISK_READ) != 0)
- return (1);
-
- if (sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_CACHE_WRITE) != 0)
- return (1);
-
- if (sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_DISK_WRITE) != 0)
- return (1);
-
- if (sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_WRCANCELNS) != 0)
- return (1);
-
- if (io_value_check(sdbcstat->pre_io->ks_data,
- sdbcstat->cur_io->ks_data) != 0)
- return (1);
-
- return (0);
-}
-
-/*
- * sdbc_validate() - validates the structure of the kstats by attempting to
- * lookup fields used by this module
- *
- * parameters
- * kstat_t *ksp - kstat to be examined
- *
- * returns
- * 1 - one or more fields missing
- * 0 - all fields present
- */
-int
-sdbc_validate(kstat_t *ksp)
-{
- if (! kstat_value(ksp, SDBC_CDKSTAT_VOL_NAME) ||
- ! kstat_value(ksp, SDBC_CDKSTAT_FAILED) ||
- ! kstat_value(ksp, SDBC_CDKSTAT_CDHINTS) ||
- ! kstat_value(ksp, SDBC_CDKSTAT_CACHE_READ) ||
- ! kstat_value(ksp, SDBC_CDKSTAT_DISK_READ) ||
- ! kstat_value(ksp, SDBC_CDKSTAT_CACHE_WRITE) ||
- ! kstat_value(ksp, SDBC_CDKSTAT_DISK_WRITE) ||
- ! kstat_value(ksp, SDBC_CDKSTAT_DESTAGED) ||
- ! kstat_value(ksp, SDBC_CDKSTAT_WRCANCELNS))
- return (1);
-
- return (0);
-}
-
-/*
- * sdbc_getvalues() - populates a values structure with data obtained from the
- * kstat
- *
- * parameters
- * sdbcstat_t *sdbcstat - pointer to the structure containing the kstats
- * sdbcvals_t *vals - pointer to the structure that will receive the values
- * int flags - flags that describe adjustments made to the values
- *
- * returns
- * 1 - failure
- * 0 - success
- */
-int
-sdbc_getvalues(sdbcstat_t *sdbcstat, sdbcvals_t *vals, int flags)
-{
- int divisor = 0;
- int factors;
- uint64_t hr_etime;
- double etime;
-
- kstat_io_t *cur;
- kstat_io_t *pre;
-
- if (sdbcstat == NULL)
- return (1);
-
- cur = sdbcstat->cur_io->ks_data;
- pre = sdbcstat->pre_io->ks_data;
-
- hr_etime = hrtime_delta(pre->rlastupdate, cur->rlastupdate);
- etime = hr_etime / (double)NANOSEC;
-
- /* read data */
- vals->cache_read =
- FBA_SIZE(sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_CACHE_READ));
- vals->disk_read =
- FBA_SIZE(sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_DISK_READ));
-
-
- vals->total_reads = vals->cache_read + vals->disk_read;
-
- if (vals->cache_read == 0)
- vals->read_hit = 0.0;
- else
- vals->read_hit =
- ((float)vals->cache_read / vals->total_reads) * 100.0;
-
- /* write data */
- vals->cache_write =
- FBA_SIZE(sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_CACHE_WRITE));
- vals->disk_write =
- FBA_SIZE(sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_DISK_WRITE));
-
- vals->total_writes = vals->cache_write + vals->disk_write;
-
- vals->destaged =
- FBA_SIZE(sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_DESTAGED));
-
- if (vals->cache_write == 0)
- vals->write_hit = 0.0;
- else
- vals->write_hit = ((float)vals->cache_write /
- (vals->total_writes - vals->destaged)) * 100.0;
-
- /* miscellaneous */
- vals->write_cancellations =
- FBA_SIZE(sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_WRCANCELNS));
-
- vals->total_cache = vals->cache_read + vals->cache_write;
- vals->total_disk = vals->disk_read + vals->disk_write;
-
- /* total cache hit calculation */
- vals->cache_hit = 0;
- factors = 0;
-
- if (vals->cache_read != 0) {
- vals->cache_hit += vals->read_hit;
- factors++;
- }
-
- if (vals->cache_write != 0) {
- vals->cache_hit += vals->write_hit;
- factors++;
- }
-
- if (vals->cache_hit)
- vals->cache_hit /= (float)factors;
-
- /* adjustments */
- divisor = 1;
-
- if (flags & SDBC_KBYTES)
- divisor *= KILOBYTE;
- if ((flags & SDBC_INTAVG) && (etime > 0))
- divisor *= etime;
-
- if (divisor != 1) {
- vals->cache_read /= divisor;
- vals->disk_read /= divisor;
- vals->total_reads /= divisor;
-
- vals->cache_write /= divisor;
- vals->disk_write /= divisor;
- vals->total_writes /= divisor;
-
- vals->total_cache /= divisor;
- vals->total_disk /= divisor;
-
- vals->destaged /= divisor;
- vals->write_cancellations /= divisor;
- }
-
- return (0);
-}
-
-/*
- * sdbc_getdelta() - calculates the difference between two kstat fields
- *
- * parameters
- * sdbcstat_t *sdbcstat - the SDBC stat strcture containing the two fields
- * char *name - the name of the fields
- * returns
- * uint32_t value of the differences adjusted for overflow of the data type
- */
-uint32_t
-sdbc_getdelta(sdbcstat_t *sdbcstat, char *name)
-{
- uint32_t *cur_val;
- uint32_t *pre_val;
-
- pre_val = kstat_value(sdbcstat->pre_set, name);
- cur_val = kstat_value(sdbcstat->cur_set, name);
-
- return (u32_delta(*pre_val, *cur_val));
-}
-
-void
-center(int size, char *hdr)
-{
- int lpad = 0;
- int rpad = 0;
- char fmt[10];
-
- if (size == 0)
- return;
-
- if (strlen(hdr) < size) {
- lpad = (size - strlen(hdr)) / 2;
-
- if (lpad * 2 < size)
- lpad++;
-
- rpad = size - (lpad + strlen(hdr));
- }
-
-output:
- (void) sprintf(fmt, "%%%ds%%s%%%ds", lpad, rpad);
- (void) printf(fmt, " ", hdr, " ");
-}
diff --git a/usr/src/cmd/avs/dsstat/sdbc_stats.h b/usr/src/cmd/avs/dsstat/sdbc_stats.h
deleted file mode 100644
index ed455a7099..0000000000
--- a/usr/src/cmd/avs/dsstat/sdbc_stats.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SDBC_STATS_H
-#define _SDBC_STATS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Internal flags to denote data collection status
- */
-#define GOT_SET_KSTAT 0x01
-#define GOT_IO_KSTAT 0x02
-#define GOT_COMPLETE_SDBC (GOT_SET_KSTAT | GOT_IO_KSTAT)
-
-#define SDBC_COMPLETE(x) (((x) & (GOT_COMPLETE_SDBC)) != \
- (GOT_COMPLETE_SDBC))
-
-#define SDBC_KBYTES 0x01
-#define SDBC_INTAVG 0x02
-
-#define KILOBYTE 1024
-
-typedef struct sdbcstat_s
-{
- kstat_t *pre_set;
- kstat_t *pre_io;
- kstat_t *cur_set;
- kstat_t *cur_io;
- int collected;
- struct sdbcstat_s *next;
-} sdbcstat_t;
-
-typedef struct sdbcvals_t
-{
- uint32_t cache_read;
- uint32_t cache_write;
- uint32_t total_cache;
-
- float cache_hit;
- float read_hit;
- float write_hit;
-
- uint32_t disk_read;
- uint32_t disk_write;
- uint32_t total_disk;
-
- uint32_t destaged;
- uint32_t write_cancellations;
-
- uint32_t total_reads;
- uint32_t total_writes;
-} sdbcvals_t;
-
-extern kstat_t *sdbc_global;
-
-/* Prototypes */
-int sdbc_discover(kstat_ctl_t *);
-int sdbc_update(kstat_ctl_t *);
-int sdbc_report();
-sdbcstat_t *sdbc_getstat(char *);
-int sdbc_getvalues(sdbcstat_t *, sdbcvals_t *, int);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SDBC_STATS_H */
diff --git a/usr/src/cmd/avs/dsstat/sndr_stats.c b/usr/src/cmd/avs/dsstat/sndr_stats.c
deleted file mode 100644
index 2d65ee2036..0000000000
--- a/usr/src/cmd/avs/dsstat/sndr_stats.c
+++ /dev/null
@@ -1,852 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <signal.h>
-#include <setjmp.h>
-
-#include <kstat.h>
-
-#include <sys/nsctl/rdc.h>
-#include <sys/nsctl/rdc_io.h>
-#include <sys/nsctl/rdc_bitmap.h>
-
-#include "sdbc_stats.h"
-#include "sndr_stats.h"
-
-#include "dsstat.h"
-#include "common.h"
-#include "report.h"
-
-static sndrstat_t *sndr_top;
-
-void sndr_add_stat(sndrstat_t *);
-sndrstat_t *sndr_del_stat(sndrstat_t *);
-
-int sndr_value_check(sndrstat_t *);
-int sndr_validate(kstat_t *);
-int sndr_strcmp(char *, char *);
-int sndr_vol_selected(kstat_t *);
-
-void getType(kstat_t *, char *);
-void getStat(kstat_t *, char *);
-void getQueue(kstat_t *, char *);
-void printQueueStats(int, kstat_t *);
-float getSyncNeeded(kstat_t *);
-
-static void update_sighandler(int);
-static void discover_sighandler(int);
-
-static sigjmp_buf update_env, discover_env;
-static sig_atomic_t sig_raised = 0;
-/*
- * sndr_discover() - looks for new statistics to be monitored.
- * Verifies that any statistics found are now already being
- * monitored.
- *
- */
-int
-sndr_discover(kstat_ctl_t *kc)
-{
- static int validated = 0;
- struct sigaction segv_act;
- int rc = 0;
- kstat_t *ksp;
-
-
- (void) signal(SIGSEGV, discover_sighandler);
- (void) sigaction(SIGSEGV, NULL, &segv_act);
-
- /* Loop on all kstats */
- for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {
- int kinst;
- char kname[KSTAT_STRLEN + 1];
- sndrstat_t *cur;
- sndrstat_t *sndrstat = NULL;
- kstat_t *bmp_ksp;
- kstat_t *sec_ksp;
-
- /* Serach for SNDR set */
- if (strcmp(ksp->ks_module, RDC_KSTAT_MODULE) != 0 ||
- strcmp(ksp->ks_name, RDC_KSTAT_INFO) != 0) {
- continue;
- }
-
- if (kstat_read(kc, ksp, NULL) == -1)
- continue;
-
- /*
- * Validate kstat structure
- */
- if (! validated) {
- if (sndr_validate(ksp))
- return (EINVAL);
-
- validated++;
- }
-
- /*
- * Duplicate check
- */
- for (cur = sndr_top; cur != NULL; cur = cur->next) {
- char *cur_vname, *tst_vname;
- uint32_t cur_inst, tst_inst;
-
- cur_vname = kstat_value(cur->pre_set, RDC_IKSTAT_FILE);
- cur_inst = cur->pre_set->ks_instance;
-
- tst_vname = kstat_value(ksp, RDC_IKSTAT_FILE);
- tst_inst = ksp->ks_instance;
-
- if (strcmp(cur_vname, tst_vname) == 0 &&
- cur_inst == tst_inst)
- goto next;
- }
-
- /*
- * Initialize new record
- */
- sndrstat = (sndrstat_t *)calloc(1, sizeof (sndrstat_t));
- kinst = ksp->ks_instance;
-
- /*
- * Set kstat
- */
- sndrstat->pre_set = kstat_retrieve(kc, ksp);
-
- if (sndrstat->pre_set == NULL)
- goto next;
-
- sndrstat->collected |= GOT_SET_KSTAT;
-
- /*
- * Bitmap kstat
- */
- (void) sprintf(kname, "%s%d", RDC_KSTAT_BMPNAME, kinst);
-
- bmp_ksp = kstat_lookup(kc, RDC_KSTAT_BMPNAME, kinst, kname);
- sndrstat->pre_bmp = kstat_retrieve(kc, bmp_ksp);
-
- if (sndrstat->pre_bmp == NULL)
- goto next;
-
- sndrstat->collected |= GOT_BMP_KSTAT;
-
- /*
- * Secondary kstat
- */
- (void) sprintf(kname, "%s%d", RDC_KSTAT_RDCNAME, kinst);
-
- sec_ksp = kstat_lookup(kc, RDC_KSTAT_MODULE, kinst, kname);
- sndrstat->pre_sec = kstat_retrieve(kc, sec_ksp);
-
- if (sndrstat->pre_sec == NULL)
- goto next;
-
- sndrstat->collected |= GOT_SEC_KSTAT;
-
-next:
- /*
- * Check if we got a complete set of stats
- */
- if (sndrstat == NULL)
- continue;
-
- if (SNDR_COMPLETE(sndrstat->collected)) {
- (void) sndr_del_stat(sndrstat);
- continue;
- }
-
- /*
- * Add to linked list
- */
- sndr_add_stat(sndrstat);
- }
-
- (void) sigsetjmp(discover_env, 0);
- if (sig_raised) {
- sig_raised = 0;
- rc = -1;
- }
- (void) sigaction(SIGSEGV, &segv_act, NULL);
-
- return (rc);
-}
-
-void
-discover_sighandler(int sig)
-{
- switch (sig) {
- case SIGSEGV:
- sig_raised = 1;
- siglongjmp(discover_env, sig);
- default:
- exit(sig);
- }
-}
-
-void
-update_sighandler(int sig)
-{
- switch (sig) {
- case SIGSEGV:
- sig_raised = 1;
- siglongjmp(update_env, sig);
- default:
- exit(sig);
- }
-}
-
-/*
- * sndr_update() - updates all of the statistics currently being monitored.
- *
- */
-int
-sndr_update(kstat_ctl_t *kc)
-{
- sndrstat_t *cur;
- struct sigaction segv_act;
- int rc = 0;
-
- (void) signal(SIGSEGV, update_sighandler);
- (void) sigaction(SIGSEGV, NULL, &segv_act);
-
- for (cur = sndr_top; cur != NULL; cur = cur->next) {
- int kinst;
- char kname[KSTAT_STRLEN + 1];
- kstat_t *ksp = NULL;
- char *cur_vname, *tst_vname;
-
- cur->collected = 0;
-
- /*
- * Age off old stats
- */
- if (cur->cur_set != NULL) {
- kstat_free(cur->pre_set);
- kstat_free(cur->pre_bmp);
- kstat_free(cur->pre_sec);
-
- cur->pre_set = cur->cur_set;
- cur->pre_bmp = cur->cur_bmp;
- cur->pre_sec = cur->cur_sec;
- }
-
- /*
- * Set kstat
- */
- (void) strncpy(kname, cur->pre_set->ks_name, KSTAT_STRLEN);
- kname[KSTAT_STRLEN] = '\0';
-
- kinst = cur->pre_set->ks_instance;
-
- ksp = kstat_lookup(kc, RDC_KSTAT_MODULE, kinst, kname);
-
- if ((cur->cur_set = kstat_retrieve(kc, ksp)) == NULL)
- continue;
-
- cur->collected |= GOT_SET_KSTAT;
-
- /*
- * Validate set
- */
- cur_vname = kstat_value(cur->pre_set, RDC_IKSTAT_FILE);
- tst_vname = kstat_value(cur->cur_set, RDC_IKSTAT_FILE);
-
- if (strcmp(cur_vname, tst_vname) != 0)
- continue;
-
- /*
- * Bitmap kstat
- */
- (void) sprintf(kname, "%s%d", RDC_KSTAT_BMPNAME, kinst);
-
- ksp = kstat_lookup(kc, RDC_KSTAT_BMPNAME, kinst, kname);
-
- if ((cur->cur_bmp = kstat_retrieve(kc, ksp)) == NULL)
- continue;
-
- cur->collected |= GOT_BMP_KSTAT;
-
- /*
- * Secondary kstat
- */
- (void) sprintf(kname, "%s%d", RDC_KSTAT_RDCNAME, kinst);
-
- ksp = kstat_lookup(kc, RDC_KSTAT_MODULE, kinst, kname);
-
- if ((cur->cur_sec = kstat_retrieve(kc, ksp)) == NULL)
- continue;
-
- cur->collected |= GOT_SEC_KSTAT;
-
- }
-
- (void) sigsetjmp(update_env, 0);
- if (sig_raised) {
- sig_raised = 0;
- rc = -1;
- }
- (void) sigaction(SIGSEGV, &segv_act, NULL);
-
- return (rc);
-}
-
-/*
- * sndr_report() - outputs statistics for the statistics currently being
- * monitored. Deletes statistics for volumes that have been disabled.
- *
- */
-int
-sndr_report()
-{
- int padsz;
- char pad[20] = "";
- sndrstat_t *cur, *pre = NULL;
-
- if (sndr_top == NULL)
- return (0);
-
- /* Create padding string for secondary report lines */
- padsz = 0;
- if (dflags & FLAGS) {
- padsz += STAT_HDR_SIZE;
- padsz += STAT_HDR_SIZE;
- }
-
- if (dflags & ASYNC_QUEUE)
- padsz += STAT_HDR_SIZE;
-
- if (dflags & PCTS)
- padsz += PCT_HDR_SIZE;
-
- if (padsz) {
- char fmt[20];
- (void) sprintf(fmt, "%%%ds", padsz);
- (void) sprintf(pad, fmt, " ");
- }
-
- for (cur = sndr_top; cur != NULL; ) { /*CSTYLED */
- int first = 1;
- char data[20] = "";
-
- /* Check to see if this is this a complete */
- if (SNDR_COMPLETE(cur->collected)) {
- char *c;
- char vn[NSC_MAXPATH + 1];
- sndrstat_t *next;
-
- /* notify user of set being disabled */
- c = kstat_value(cur->pre_set, RDC_IKSTAT_SECFILE);
- (void) strncpy(vn, c, NSC_MAXPATH);
- vn[NSC_MAXPATH] = '\0';
-
- (void) printf(DATA_C16, vn);
- (void) printf(" %s\n", RDC_DISABLED);
-
- next = sndr_del_stat(cur);
-
- /* free memory and remove stat from list */
- if (! pre)
- cur = sndr_top = next;
- else
- cur = pre->next = next;
-
- continue;
- }
-
- /* Check to see if the user specified this volume */
- if (! sndr_vol_selected(cur->pre_set))
- goto next;
-
- /* Check to see if zflag applies */
- if (zflag && sndr_value_check(cur) == 0)
- goto next;
-
- /* Calculate flags */
- if (dflags & FLAGS) {
- char c[STAT_HDR_SIZE];
- char vtype[STAT_HDR_SIZE];
- char vstat[STAT_HDR_SIZE];
-
- getType(cur->cur_set, &c[0]);
- (void) sprintf(vtype, DATA_C2, c);
- (void) strcat(data, vtype);
-
- getStat(cur->cur_set, &c[0]);
- (void) sprintf(vstat, DATA_C2, c);
- (void) strcat(data, vstat);
- }
-
- /* Async. queue statistics */
- if (dflags & ASYNC_QUEUE) {
- char c[STAT_HDR_SIZE];
- char qtype[STAT_HDR_SIZE];
-
- getQueue(cur->cur_set, &c[0]);
- (void) sprintf(qtype, DATA_C2, c);
- (void) strcat(data, qtype);
- }
-
- /* Calculate sync needed percentages */
- if (dflags & PCTS) {
- char snpct[10];
-
- (void) sprintf(snpct, DATA_F62,
- getSyncNeeded(cur->cur_set));
- (void) strcat(data, snpct);
- }
-
- /* Output */
- if (rflags & SNDR_NET) {
- char *c;
- char type[STAT_HDR_SIZE];
- char vn[NAMED_LEN + 1];
-
- getType(cur->cur_set, &type[0]);
-
- if (type[0] == 'S') {
- c = kstat_value(cur->pre_set,
- RDC_IKSTAT_FILE);
- } else {
- c = kstat_value(cur->pre_set,
- RDC_IKSTAT_SECFILE);
- }
-
- /* Only print last 15 characters */
- if (strlen(c) >= NAMED_LEN) {
- c += strlen(c) - NAMED_LEN;
- }
- (void) strncpy(vn, c, NAMED_LEN);
- vn[NAMED_LEN] = '\0';
-
- header();
- (void) printf(DATA_C16, vn);
- (void) printf("%s", data);
- (void) printf(ROLE_INF_FMT, RDC_SECONDARY);
-
- /* Async. queue statistics */
- if (dflags & ASYNC_QUEUE)
- printQueueStats(first, cur->cur_set);
-
- io_report(cur->cur_sec, cur->pre_sec,
- sdbc_getstat(vn));
- (void) printf("\n");
-
- if (first) {
- (void) strcpy(data, strlen(pad) > 0 ? pad : "");
- first = 0;
- }
- }
-
- if (rflags & SNDR_BMP) {
- char *c;
- char vn[16];
-
- c = kstat_value(cur->pre_set, RDC_IKSTAT_BITMAP);
-
- /* Only print last 15 characters */
- if (strlen(c) >= NAMED_LEN) {
- c += strlen(c) - NAMED_LEN;
- }
- (void) strncpy(vn, c, NAMED_LEN);
- vn[NAMED_LEN] = '\0';
-
- header();
- (void) printf(DATA_C16, vn);
- (void) printf("%s", data);
- (void) printf(ROLE_INF_FMT, RDC_BITMAP);
-
- /* Async. queue statistics */
- if (dflags & ASYNC_QUEUE)
- printQueueStats(first, cur->cur_set);
-
- io_report(cur->cur_bmp, cur->pre_bmp,
- sdbc_getstat(vn));
- (void) printf("\n");
-
- if (first) {
- (void) strcpy(data, strlen(pad) > 0 ? pad : "");
- first = 0;
- }
- }
-next:
- pre = cur;
- cur = cur->next;
- }
-
- return (0);
-}
-
-/*
- * sndr_add_stat() - adds a fully populated sndrstat_t structure
- * to the linked list of currently monitored kstats. The structure
- * will be added in alphabetical order, using the volume name as the
- * key.
- *
- * parameters
- * sndrstat_t *sndrstat - to be added to the list.
- *
- */
-void
-sndr_add_stat(sndrstat_t *sndrstat)
-{
-
- sndrstat_t *cur;
-
- if (sndr_top == NULL) {
- sndr_top = sndrstat;
- return;
- }
-
- for (cur = sndr_top; cur != NULL; cur = cur->next) {
- char *cur_vname, *nxt_vname, *tst_vname;
-
- cur_vname = kstat_value(cur->pre_set, RDC_IKSTAT_FILE);
- tst_vname = kstat_value(sndrstat->pre_set, RDC_IKSTAT_FILE);
-
- if (strcmp(cur_vname, tst_vname) <= 0) {
- /*
- * If we get to the last item in the list, then just
- * add this one to the end
- */
- if (cur->next == NULL) {
- cur->next = sndrstat;
- return;
- }
-
- nxt_vname = kstat_value(cur->next->pre_set,
- RDC_IKSTAT_FILE);
-
- if (strcmp(nxt_vname, tst_vname) > 0) {
- sndrstat->next = cur->next;
- cur->next = sndrstat;
- return;
- }
- } else {
- if (cur == sndr_top)
- sndr_top = sndrstat;
-
- sndrstat->next = cur;
-
- return;
- }
- }
-}
-
-/*
- * sndr_del_stat() - deallocate memory for the structure being
- * passed in.
- *
- * parameters
- * sndrstat_t *sndrstat - structure to be deallocated
- *
- * returns
- * sndrstat_t * - pointer to the "next" structures in the
- * linked list. May be NULL if we are removing the last
- * structure in the linked list.
- *
- */
-sndrstat_t *
-sndr_del_stat(sndrstat_t *sndrstat)
-{
-
- sndrstat_t *next = sndrstat->next;
-
- kstat_free(sndrstat->pre_set);
- kstat_free(sndrstat->pre_bmp);
- kstat_free(sndrstat->pre_sec);
- kstat_free(sndrstat->cur_set);
- kstat_free(sndrstat->cur_bmp);
- kstat_free(sndrstat->cur_sec);
-
- free(sndrstat);
-
- return (next);
-}
-
-/*
- * sndr_value_check() - check to determine if any activity was registered
- * on this volume by checking the previous stats vs. the current stats.
- *
- * parameters
- * sndrstat_t *sndrstat - structure to be checked
- *
- * returns
- * 0 - no activity
- * 1 - activity
- */
-int
-sndr_value_check(sndrstat_t *sndrstat)
-{
- if (SNDR_COMPLETE(sndrstat->collected))
- return (1);
-
- if (io_value_check(sndrstat->pre_bmp->ks_data,
- sndrstat->cur_bmp->ks_data)) {
- return (1);
- }
-
- if (io_value_check(sndrstat->pre_sec->ks_data,
- sndrstat->cur_sec->ks_data)) {
- return (1);
- }
-
- return (0);
-}
-
-/*
- * sndr_validate() - validates the fields required by dsstat exist in
- * the kstat_t structure passed in. This check keeps dsstat from
- * core dumping if the kstat_named_t structures change in any of the
- * services that dsstat monitors.
- *
- * paramaters
- * kstat_t *ksp - kstat_t structure to check. The ks_data field
- * should have been populated with a call to kstat_read()
- *
- * returns
- * 0 - all fields are contained in the kstat
- * 1 - a field required by dsstat is not in the kstat
- */
-int
-sndr_validate(kstat_t *ksp)
-{
- if (! kstat_value(ksp, RDC_IKSTAT_FILE) ||
- ! kstat_value(ksp, RDC_IKSTAT_FLAGS) ||
- ! kstat_value(ksp, RDC_IKSTAT_SYNCFLAGS) ||
- ! kstat_value(ksp, RDC_IKSTAT_BMPFLAGS) ||
- ! kstat_value(ksp, RDC_IKSTAT_VOLSIZE) ||
- ! kstat_value(ksp, RDC_IKSTAT_BITSSET) ||
- ! kstat_value(ksp, RDC_IKSTAT_QUEUE_TYPE) ||
- ! kstat_value(ksp, RDC_IKSTAT_ASYNC_ITEMS) ||
- ! kstat_value(ksp, RDC_IKSTAT_ASYNC_BLOCKS) ||
- ! kstat_value(ksp, RDC_IKSTAT_ASYNC_ITEM_HWM) ||
- ! kstat_value(ksp, RDC_IKSTAT_ASYNC_BLOCK_HWM))
- return (1);
-
- return (0);
-}
-
-void
-getType(kstat_t *ksp, char *vtype)
-{
- uint32_t *set_flags;
-
- set_flags = kstat_value(ksp, RDC_IKSTAT_FLAGS);
-
- if (*set_flags & RDC_PRIMARY)
- (void) strcpy(vtype, "P");
- else
- (void) strcpy(vtype, "S");
-}
-
-void
-getStat(kstat_t *ksp, char *vstat)
-{
- uint32_t *set_flags;
- uint32_t *syn_flags;
- uint32_t *bmp_flags;
-
- set_flags = kstat_value(ksp, RDC_IKSTAT_FLAGS);
- syn_flags = kstat_value(ksp, RDC_IKSTAT_SYNCFLAGS);
- bmp_flags = kstat_value(ksp, RDC_IKSTAT_BMPFLAGS);
-
- (void) strcpy(vstat, "R");
-
- if (*set_flags & RDC_SYNCING) {
- if (*set_flags & RDC_SLAVE)
- if (*set_flags & RDC_PRIMARY)
- (void) strcpy(vstat, "RS");
- else
- (void) strcpy(vstat, "SY");
- else
- if (*set_flags & RDC_PRIMARY)
- (void) strcpy(vstat, "SY");
- else
- (void) strcpy(vstat, "RS");
- }
-
- if (*set_flags & RDC_LOGGING) {
- (void) strcpy(vstat, "L");
-
- if (*set_flags & RDC_QUEUING)
- (void) strcpy(vstat, "Q");
-
- if (*set_flags & RDC_DISKQ_FAILED)
- (void) strcpy(vstat, "QF");
-
- if (*syn_flags & RDC_SYNC_NEEDED)
- (void) strcpy(vstat, "SN");
-
- if (*syn_flags & RDC_RSYNC_NEEDED)
- (void) strcpy(vstat, "RN");
- }
-
- if (*syn_flags & RDC_FCAL_FAILED)
- (void) strcpy(vstat, "FF");
-
- if (*bmp_flags & RDC_BMP_FAILED)
- (void) strcpy(vstat, "BF");
-
- if (*syn_flags & RDC_VOL_FAILED)
- (void) strcpy(vstat, "VF");
-}
-
-void
-getQueue(kstat_t *ksp, char *vqueue)
-{
- char *qtype;
-
- (void) strcpy(vqueue, "-");
-
- qtype = kstat_value(ksp, RDC_IKSTAT_QUEUE_TYPE);
-
- if (strcmp(qtype, "memory") == 0)
- (void) strcpy(vqueue, "M");
-
- if (strcmp(qtype, "disk") == 0)
- (void) strcpy(vqueue, "D");
-}
-
-float
-getSyncNeeded(kstat_t *ksp)
-{
- uint32_t *volsize, *bitsset;
- uint32_t bits, segs;
- float pct;
-
- volsize = kstat_value(ksp, RDC_IKSTAT_VOLSIZE);
- bitsset = kstat_value(ksp, RDC_IKSTAT_BITSSET);
-
- segs = FBA_TO_LOG_LEN(*volsize);
- bits = *bitsset > 0 ? *bitsset : 0;
-
- pct = segs ? ((float)bits/(float)segs) : 0.0;
- pct *= 100;
-
- return (pct);
-}
-
-/*
- * Special handling for compatibility.
- * "dsstat -s <set>" allows set name to be the last 15 chars,
- * due to 15 characters limit of old kstat information.
- *
- * return 0 if:
- * 1) full and partial are same
- * 2) partial is the last 15 chars of full
- */
-int
-sndr_strcmp(char *full, char *partial)
-{
- char *f = full;
- int rc;
-
- rc = strcmp(full, partial);
-
- if (rc != 0 &&
- (strlen(partial) == NAMED_LEN) &&
- (strlen(full) > NAMED_LEN)) {
- f += strlen(full) - NAMED_LEN;
- rc = strncmp(f, partial, NAMED_LEN);
- }
-
- return (rc);
-}
-
-int
-sndr_vol_selected(kstat_t *ksp)
-{
- vslist_t *vslist = vs_top;
-
- for (vslist = vs_top; vslist != NULL; vslist = vslist->next) {
- char *vn;
- char *vh;
-
- /* If no host specified, check local only */
- if (vslist->volhost == NULL) {
- vn = kstat_value(ksp, RDC_IKSTAT_FILE);
-
- if (sndr_strcmp(vn, vslist->volname))
- continue;
- else
- break;
- }
-
- /* Check primary */
- vn = kstat_value(ksp, RDC_IKSTAT_FILE);
- vh = kstat_value(ksp, RDC_IKSTAT_PRIMARY_HOST);
-
- if (sndr_strcmp(vn, vslist->volname) == 0 &&
- sndr_strcmp(vh, vslist->volhost) == 0)
- break;
-
- /* Check secondary */
- vn = kstat_value(ksp, RDC_IKSTAT_SECFILE);
- vh = kstat_value(ksp, RDC_IKSTAT_SECONDARY_HOST);
-
- if (sndr_strcmp(vn, vslist->volname) == 0 &&
- sndr_strcmp(vh, vslist->volhost) == 0)
- break;
- }
-
- if (vs_top != NULL && vslist == NULL)
- return (0);
-
- return (1);
-}
-
-void
-printQueueStats(int first, kstat_t *cur_set)
-{
- uint32_t *val;
-
- if (! first) {
- /* Filler for async. queue fields */
- (void) printf(TPS_HDR_FMT, NO_INFO);
- (void) printf(KPS_HDR_FMT, NO_INFO);
- (void) printf(TPS_HDR_FMT, NO_INFO);
- (void) printf(KPS_HDR_FMT, NO_INFO);
-
- return;
- }
-
- val = (uint32_t *)kstat_value(cur_set, RDC_IKSTAT_ASYNC_ITEMS);
- (void) printf(TPS_INF_FMT, *val);
-
- val = (uint32_t *)kstat_value(cur_set, RDC_IKSTAT_ASYNC_BLOCKS);
- (void) printf(KPS_INF_FMT, (float)(*val / 2));
-
- val = (uint32_t *)kstat_value(cur_set, RDC_IKSTAT_ASYNC_ITEM_HWM);
- (void) printf(TPS_INF_FMT, *val);
-
- val = (uint32_t *)kstat_value(cur_set, RDC_IKSTAT_ASYNC_BLOCK_HWM);
- (void) printf(KPS_INF_FMT, (float)(*val / 2));
-}
diff --git a/usr/src/cmd/avs/dsstat/sndr_stats.h b/usr/src/cmd/avs/dsstat/sndr_stats.h
deleted file mode 100644
index d5b730c96c..0000000000
--- a/usr/src/cmd/avs/dsstat/sndr_stats.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SNDR_STATS_H
-#define _SNDR_STATS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define GOT_SET_KSTAT 0x01
-#define GOT_BMP_KSTAT 0x02
-#define GOT_SEC_KSTAT 0x04
-
-#define GOT_COMPLETE_SNDR (GOT_SET_KSTAT|GOT_BMP_KSTAT|GOT_SEC_KSTAT)
-
-#define SNDR_COMPLETE(x) (((x) & (GOT_COMPLETE_SNDR)) != (GOT_COMPLETE_SNDR))
-
-/* SNDR strings */
-#define RDC_KSTAT_RDCNAME "sndr"
-#define RDC_KSTAT_BMPNAME "sndrbmp"
-
-#define RDC_DISABLED "<<set disabled>>"
-#define RDC_SECONDARY "net"
-#define RDC_BITMAP "bmp"
-
-typedef struct sndrstat_s
-{
- kstat_t *pre_set;
- kstat_t *pre_bmp;
- kstat_t *pre_sec;
- kstat_t *cur_set;
- kstat_t *cur_bmp;
- kstat_t *cur_sec;
- int collected;
- struct sndrstat_s *next;
-} sndrstat_t;
-
-/* Prototypes */
-int sndr_discover(kstat_ctl_t *);
-int sndr_update(kstat_ctl_t *);
-int sndr_report();
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SNDR_STATS_H */
diff --git a/usr/src/cmd/avs/dsw/Makefile b/usr/src/cmd/avs/dsw/Makefile
deleted file mode 100644
index 7dced4b925..0000000000
--- a/usr/src/cmd/avs/dsw/Makefile
+++ /dev/null
@@ -1,102 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-include ../../Makefile.cmd
-include ../Makefile.com
-
-DYNPROG = iiadm iiboot iicpbmp iicpshd
-
-PROG=$(DYNPROG)
-
-PROG1 = iiadm
-PROG2 = iiboot
-PROG3 = iicpbmp
-PROG4 = iicpshd
-
-SUBDIRS= etc
-
-iiadm := POBJS = iiadm.o
-iiboot := POBJS = iiboot.o
-iicpbmp := POBJS = iicpbmp.o
-iicpshd := POBJS = iicpshd.o
-
-iiadm := LDLIBS += -lnsctl -ldscfg -lunistat -lm
-iiboot := LDLIBS += -ldscfg -lunistat
-iicpbmp := LDLIBS += -ldscfg -lunistat
-iicpshd := LDLIBS += -ldscfg -lunistat
-
-OBJS= iiadm.o iiboot.o iicpbmp.o iicpshd.o
-POFILE = dsw_all.po
-SRCS= $(OBJS:%.o=%.c)
-POFILES= $(OBJS:%.o=%.po)
-
-CFLAGS += $(CCVERBOSE) -D_DSW_
-LINTFLAGS += -Xa -n -s -x -m -u -Dlint -errhdr=%user -D_DSW_ -DDEBUG
-LINTFLAGS += -erroff=E_SEC_SCANF_UNBOUNDED_COPY
-LINTFLAGS += -erroff=E_SEC_PRINTF_VAR_FMT
-CERRWARN += -_gcc=-Wno-unused-variable
-CERRWARN += -_gcc=-Wno-parentheses
-CERRWARN += -_gcc=-Wno-uninitialized
-
-all := TARGET= all
-install := TARGET= install
-clean := TARGET= clean
-clobber := TARGET= clobber
-lint := TARGET= lint
-
-.KEEP_STATE:
-
-.PARALLEL: $(OBJS)
-
-all: $(SUBDIRS) $(PROG) $(POFILES)
-
-install: $(SUBDIRS) all $(ROOTPROG)
- -$(RM) $(ROOT)/usr/sbin/$(PROG1)
- -$(RM) $(ROOT)/usr/sbin/$(PROG2)
- -$(RM) $(ROOT)/usr/sbin/$(PROG3)
- -$(RM) $(ROOT)/usr/sbin/$(PROG4)
- -$(SYMLINK) ../bin/$(PROG1) $(ROOT)/usr/sbin/$(PROG1)
- -$(SYMLINK) ../bin/$(PROG2) $(ROOT)/usr/sbin/$(PROG2)
- -$(SYMLINK) ../bin/$(PROG3) $(ROOT)/usr/sbin/$(PROG3)
- -$(SYMLINK) ../bin/$(PROG4) $(ROOT)/usr/sbin/$(PROG4)
-
-$(POFILE): $(POFILES)
- $(RM) $@
- $(CAT) $(POFILES) > $@
-
-lint: $(SUBDIRS) lint_SRCS
-
-clean: $(SUBDIRS)
- $(RM) *.o $(POFILES)
-
-$(PROG): $(OBJS)
- $(LINK.c) $(POBJS) -o $@ $(LDLIBS)
- $(POST_PROCESS)
-
-$(SUBDIRS): FRC
- @cd $@; pwd; $(MAKE) $(TARGET)
-
-FRC:
-
-include ../../Makefile.targ
diff --git a/usr/src/cmd/avs/dsw/etc/Makefile b/usr/src/cmd/avs/dsw/etc/Makefile
deleted file mode 100644
index c627f1cbb1..0000000000
--- a/usr/src/cmd/avs/dsw/etc/Makefile
+++ /dev/null
@@ -1,63 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-include ../../../Makefile.cmd
-include ../../Makefile.com
-
-
-SHFILES = ii ii.cluster
-ROOTINIT_D = $(ROOTETC)/init.d
-USRTOOL_D = $(ROOTUSRTOOLS)
-
-FILEMODE = 0744
-
-ROOTINIT_DPROG = $(ROOTINIT_D)/ii
-ROOTINIT_DPROG2= $(ROOTINIT_D)/ii.cluster
-
-.KEEP_STATE:
-
-all: $(SHFILES)
-
-install: $(ROOTINIT_DPROG) $(ROOTINIT_DPROG2) $(CLUSTERSBINDIR) $(ROOTLIBSVCMETHOD)
- -$(RM) $(CLUSTERLIBDSCFGSTOPDIR)/20ii
- -$(RM) $(CLUSTERLIBDSCFGSTARTDIR)/05ii
- -$(RM) $(CLUSTERSBINDIR)/ii
- -$(RM) $(ROOTLIBSVCMETHOD)/svc-ii
- -$(SYMLINK) ../../../sbin/ii $(CLUSTERLIBDSCFGSTOPDIR)/20ii
- -$(SYMLINK) ../../../sbin/ii $(CLUSTERLIBDSCFGSTARTDIR)/05ii
- $(LN) $(ROOTINIT_D)/ii $(ROOTLIBSVCMETHOD)/svc-ii
- $(CP) $(ROOTINIT_D)/ii.cluster $(CLUSTERSBINDIR)/ii
-
-$(ROOTINIT_DPROG): ii
- $(INS.file) ii
-
-$(ROOTINIT_DPROG2): ii.cluster
- $(INS.file) ii.cluster
-
-clean:
- $(RM) $(SHFILES)
-
-clobber: clean
-
-lint:
diff --git a/usr/src/cmd/avs/dsw/etc/ii.cluster.sh b/usr/src/cmd/avs/dsw/etc/ii.cluster.sh
deleted file mode 100644
index 0be90c16a7..0000000000
--- a/usr/src/cmd/avs/dsw/etc/ii.cluster.sh
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/usr/bin/ksh
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-CMD=/usr/sbin/iiboot
-SVCS=/usr/bin/svcs
-SVCS_NAME=system/nws_ii
-
-# Determine if SMF service is online
-#
-ONLINE=`$SVCS -D $SVCS_NAME 2>>/dev/null | grep "^online"`
-if [ -z $ONLINE ]
-then
- echo "$SVCS_NAME not online"
- exit 1
-fi
-
-if [[ -z "$2" ]]
-then
- opt=usage
-else
- opt=$1
-fi
-
-case $opt in
-'start')
- if [[ -x $CMD ]]
- then
- $CMD -C "$2" -r > /dev/null 2>&1
- fi
- ;;
-
-'stop')
- if [[ -x $CMD ]]
- then
- $CMD -C "$2" -s > /dev/null 2>&1
- fi
- ;;
-
-*)
- echo "usage: ii {start|stop} cluster_resource"
- ;;
-esac
diff --git a/usr/src/cmd/avs/dsw/etc/ii.sh b/usr/src/cmd/avs/dsw/etc/ii.sh
deleted file mode 100644
index b40fc2bad4..0000000000
--- a/usr/src/cmd/avs/dsw/etc/ii.sh
+++ /dev/null
@@ -1,144 +0,0 @@
-#!/bin/sh
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-CMD=/usr/sbin/iiboot
-IIADM=/usr/sbin/iiadm
-SVCS=/usr/bin/svcs
-DSCFG_DEPEND_NOCHK="/tmp/.dscfgadm_pid"
-OS_MINOR=`/usr/bin/uname -r | /usr/bin/cut -d '.' -f2`
-
-. /lib/svc/share/smf_include.sh
-
-# Make sure prior SMF dependents are not 'online'
-# $1 = name of SMF service to validate dependents
-#
-do_smf_depends ()
-{
- times=0
- count=1
-
- if [ $OS_MINOR -ge 11 ]
- then
- return 0
- elif [ -f $DSCFG_DEPEND_NOCHK ]
- then
- for pid in `pgrep dscfgadm`
- do
- if [ `grep -c $pid $DSCFG_DEPEND_NOCHK` -gt 0 ]
- then
- return 0
- fi
- done
- elif [ `ps -ef | grep preremove | grep -c SUNWiiu` -gt 0 ]
- then
- return 0
-
- fi
-
- while [ $count -ne 0 ]
- do
- count=`$SVCS -o STATE -D $1 2>>/dev/null | grep "^online" | wc -l`
- if [ $count -ne 0 ]
- then
- # Output banner after waiting first 5 seconds
- #
- if [ $times -eq 1 ]
- then
- echo "Waiting for $1 dependents to be 'offline'"
- $SVCS -D $1 2>>/dev/null | grep "^online"
- fi
-
- # Has it been longer then 5 minutes? (60 * 5 secs.)
- #
- if [ $times -eq 60 ]
- then
- echo "Error: Failed waiting for $1 dependents to be 'offline'"
- $SVCS -D $1 2>>/dev/null | grep "^online"
- exit $SMF_EXIT_ERR_FATAL
- fi
-
- # Now sleep, giving other services time to stop
- #
- sleep 5
- times=`expr $times + 1`
- fi
- done
- return 0
-}
-
-
-CLINFO=/usr/sbin/clinfo
-
-rc=0
-
-case $1 in
-'start')
-
- COPT=
-
- if [ -x ${CMD} ]
- then
- if ${CLINFO}
- then
- # in cluster - look for local volumes only
- COPT="-C -"
- fi
-
- ${CMD} $COPT -r > /dev/null 2>&1
- rc=$?
- fi
- ;;
-'stop')
- if [ ! -r /dev/ii ]
- then
- exit $SMF_EXIT_OK
- fi
-
- do_smf_depends "system/nws_ii"
-
- COPT=
-
- if [ -x ${CMD} ]
- then
- if ${CLINFO}
- then
- # in cluster - look for local volumes only
- COPT="-C -"
- fi
-
- ${CMD} $COPT -s > /dev/null 2>&1
- rc=$?
- fi
- ;;
-*)
- echo "usage: /etc/init.d/ii {start|stop} "
- exit 1
- ;;
-esac
-if [ $rc -ne 0 ]
-then
- exit $SMF_MON_OFFLINE
-else
- exit $SMF_EXIT_OK
-fi
diff --git a/usr/src/cmd/avs/dsw/iiadm.c b/usr/src/cmd/avs/dsw/iiadm.c
deleted file mode 100644
index dd49e10e4e..0000000000
--- a/usr/src/cmd/avs/dsw/iiadm.c
+++ /dev/null
@@ -1,4377 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <errno.h>
-#include <signal.h>
-#include <stdio.h>
-#include <string.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <values.h>
-#include <locale.h>
-#include <langinfo.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <strings.h>
-#include <stdarg.h>
-#include <ctype.h>
-#include <math.h>
-#include <sys/param.h>
-#include <sys/mnttab.h>
-#include <nsctl.h>
-#include <netdb.h>
-#include <search.h>
-
-#include <sys/nsctl/cfg.h>
-#include <sys/nsctl/nsc_hash.h>
-
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_u.h>
-#include <sys/unistat/spcs_errors.h>
-#include <sys/nsctl/dsw.h>
-#include <sys/nsctl/dsw_dev.h> /* for bit map header format */
-
-#include <sys/nskernd.h>
-
-typedef struct mstcount_s {
- int count;
-} mstcount_t;
-typedef struct shdvol_s {
- char master[ DSW_NAMELEN ];
-} shdvol_t;
-typedef struct grptag_s {
- char ctag[ DSW_NAMELEN ];
-} grptag_t;
-hash_node_t **volhash = NULL;
-
-#define DSW_TEXT_DOMAIN "II"
-
-#include <dlfcn.h>
-#define RDC_LIB "/usr/lib/librdc.so.1"
-static int (*self_check)(char *);
-
-/*
- * Support for the special cluster tag "local" to be used with -C in a
- * cluster for local volumes.
- */
-#define II_LOCAL_TAG "local"
-
-#define II_NOT_CLUSTER 1
-#define II_CLUSTER 2
-#define II_CLUSTER_LCL 3
-
-static char *cfg_cluster_tag = NULL;
-static CFGFILE *cfg = NULL;
-
-void sigterm(int sig);
-
-#define SD_BIT_CLR(bmap, bit) (bmap &= ~(1 << bit))
-#define SD_BIT_ISSET(bmap, bit) ((bmap & (1 << bit)) != 0)
-
-#define MAX_LINE_SIZE 256 /* maximum characters per line in config file */
-#define MAX_GROUPS 1024 /* maximum number of groups to support */
-#define MAX_CLUSTERS 1024 /* maximum number of resource groups */
-
-unsigned long bm_size; /* size in bytes of bitmap */
-unsigned long bm_actual; /* original number of bits in bitmap */
-int debug = 0;
-
-int dsw_fd;
-
-#define LD_II 0x00000001
-#define LD_DSVOLS 0x00000002
-#define LD_SVOLS 0x00000004
-#define LD_SHADOWS 0x00000008
-
-static int reload_vols = 0;
-static int config_locked = 0;
-static int last_lock;
-
-/*
- * names for do_copy() flags.
- */
-
-enum copy_update {Copy = 0, Update};
-enum copy_direction {ToShadow = 0, ToMaster};
-enum copy_wait {WaitForStart = 0, WaitForEnd};
-
-char *cmdnam;
-
-unsigned char *allocate_bitmap(char *);
-void usage(char *);
-void enable(char *, char *, char *, char *);
-int disable(char *);
-void bitmap_op(char *, int, int, int, int);
-void print_status(dsw_config_t *, int);
-int abort_copy(char *);
-int reset(char *);
-int overflow(char *);
-void iiversion(void);
-int wait_for_copy(char *);
-int export(char *);
-void list_volumes(void);
-void dsw_error(char *, spcs_s_info_t *);
-void InitEnv();
-static void check_dg_is_local(char *dgname);
-static int check_resource_group(char *volume);
-static int check_diskgroup(char *path, char *result);
-static int check_cluster();
-static void unload_ii_vols();
-static void load_ii_vols(CFGFILE *);
-static int perform_autosv();
-static int is_exported(char *);
-static void conform_name(char **);
-static void do_attach(dsw_config_t *);
-static int ii_lock(CFGFILE *, int);
-static void verify_groupname(char *grp, int testDash);
-
-void dsw_list_clusters(char *);
-void dsw_enable(int, char **);
-void dsw_disable(int, char **);
-void dsw_copy_to_shadow(int, char **);
-void dsw_update_shadow(int, char **);
-void dsw_copy_to_master(int, char **);
-void dsw_update_master(int, char **);
-void dsw_abort_copy(int, char **);
-void dsw_display_status(int, char **);
-void dsw_display_bitmap(int, char **);
-void dsw_reset(int, char **);
-void dsw_overflow(int, char **);
-void dsw_version(int, char **);
-void dsw_wait(int, char **);
-void dsw_list_volumes(int, char **);
-void dsw_list_group_volumes();
-void dsw_export(int, char **);
-void dsw_import(int, char **);
-void dsw_join(int, char **);
-void dsw_attach(int, char **);
-void dsw_detach(int, char **);
-void dsw_params(int, char **);
-void dsw_olist(int, char **);
-void dsw_ostat(int, char **);
-void dsw_move_2_group(int, char **);
-void dsw_list_groups();
-void check_iishadow(char *);
-
-extern char *optarg;
-extern int optind, opterr, optopt;
-
-int Aflg;
-int Cflg;
-int CLflg;
-int Dflg;
-int Eflg;
-int Iflg;
-int Jflg;
-int Lflg;
-int Oflg;
-int Pflg;
-int Qflg;
-int Rflg;
-int aflg;
-int bflg;
-int cflg;
-int dflg;
-int eflg;
-int fflg;
-int gflg;
-int gLflg;
-int hflg;
-int iflg;
-int lflg;
-int mflg;
-int nflg;
-int pflg;
-int uflg;
-int vflg;
-int wflg;
-
-int errflg;
-#ifdef DEBUG
-const char single_opts[] =
- "a:b:c:d:e:f:g:hilmnpu:vw:A:C:D:E:I:J:LO:PQ:R:";
-#else
-/* no b or f flags */
-const char single_opts[] = "a:c:d:e:g:hilmnpu:vw:A:C:D:E:I:J:LO:PQ:R:";
-#endif
-const char group_opts[] = "ac:de:ilmnpu:wA:C:DELPR";
-const char *opt_list = single_opts;
-
-char buf[CFG_MAX_BUF];
-char key[CFG_MAX_KEY];
-char last_overflow[DSW_NAMELEN];
-int setnumber;
-char *group_name;
-char **group_volumes;
-enum copy_direction direction;
-char *param_delay, *param_unit;
-char *overflow_file;
-
-#ifdef lint
-int
-iiadm_lintmain(int argc, char *argv[])
-#else
-int
-main(int argc, char *argv[])
-#endif
-{
- int c;
- int actions = 0;
- int ac;
- char *av[1024];
-
- InitEnv();
-
- (void) memset(av, 0, sizeof (av));
- cmdnam = argv[0];
- while ((c = getopt(argc, argv, opt_list)) != EOF)
- switch (c) {
- case 'c':
- cflg++;
- actions++;
- if (strcmp(optarg, "m") == 0) {
- av[0] = "copy_to_master";
- direction = ToMaster;
- } else if (strcmp(optarg, "s") == 0) {
- av[0] = "copy_to_shadow";
- direction = ToShadow;
- } else {
- errflg ++;
- usage(gettext(
- "must specify m or s with -c"));
- }
- ac = 2;
- break;
- case 'd':
- dflg++;
- actions++;
- av[0] = "disable";
- av[1] = optarg;
- ac = 2;
- break;
- case 'e':
- eflg++;
- actions++;
- av[0] = "enable";
- if (strcmp(optarg, "ind") == 0)
- av[4] = "independent";
- else if (strcmp(optarg, "dep") == 0)
- av[4] = "dependent";
- else {
- errflg ++;
- usage(gettext(
- "must specify ind or dep with -e"));
- }
- ac = 1;
- break;
- case 'g':
- gflg++;
- opt_list = group_opts;
- group_name = optarg;
- if (group_name && *group_name == '-') {
- gLflg = (strcmp("-L", group_name) == 0);
- if (gLflg)
- actions++;
- }
- verify_groupname(group_name, !gLflg);
- break;
- case 'h':
- hflg++;
- actions++;
- break;
- case 'u':
- uflg++;
- actions++;
- if (strcmp(optarg, "m") == 0) {
- av[0] = "update_master";
- direction = ToMaster;
- } else if (strcmp(optarg, "s") == 0) {
- av[0] = "update_shadow";
- direction = ToShadow;
- } else {
- errflg ++;
- usage(gettext(
- "must specify m or s with -u"));
- }
- ac = 2;
- break;
- case 'i':
- iflg++;
- actions++;
- av[0] = "display_status";
- break;
- case 'l':
- lflg++;
- actions++;
- av[0] = "list_config";
- ac = 1;
- break;
- case 'm':
- mflg++;
- actions++;
- av[0] = "move_to_group";
- ac = 1;
- break;
- case 'n':
- nflg++;
- break;
- case 'p':
- pflg++;
- break;
- case 'b':
- bflg++;
- actions++;
- av[0] = "display_bitmap";
- av[1] = optarg;
- ac = 2;
- break;
- case 'a':
- aflg++;
- actions++;
- av[0] = "abort_copy";
- av[1] = optarg;
- ac = 2;
- break;
- case 'v':
- vflg++;
- actions++;
- av[1] = "version";
- ac = 1;
- break;
- case 'w':
- wflg++;
- actions++;
- av[0] = "wait";
- av[1] = optarg;
- ac = 2;
- break;
- case 'A':
- Aflg++;
- actions++;
- av[0] = "attach";
- av[1] = optarg;
- ac = 2;
- break;
- case 'C':
- Cflg++;
- cfg_cluster_tag = optarg;
- if (cfg_cluster_tag && *cfg_cluster_tag == '-') {
- CLflg = (strcmp("-L", cfg_cluster_tag) == 0);
- if (CLflg)
- actions++;
- }
- break;
- case 'D':
- Dflg++;
- actions++;
- av[0] = "detach";
- av[1] = optarg;
- ac = 2;
- break;
- case 'O':
- Oflg++;
- actions++;
- av[0] = "overflow";
- av[1] = optarg;
- ac = 2;
- break;
- case 'R':
- Rflg++;
- actions++;
- av[0] = "reset";
- av[1] = optarg;
- ac = 2;
- break;
- case 'E':
- Eflg++;
- actions++;
- av[0] = "export";
- av[1] = optarg;
- ac = 2;
- break;
- case 'I':
- Iflg++;
- actions++;
- av[0] = "import";
- av[1] = optarg;
- ac = 2;
- break;
- case 'J':
- Jflg++;
- actions++;
- av[0] = "join";
- av[1] = optarg;
- ac = 2;
- break;
- case 'P':
- Pflg++;
- actions++;
- av[0] = "parameter";
- ac = 1;
- break;
- case 'L':
- Lflg++;
- actions++;
- /* If -g group -L, force error */
- if (group_name) actions++;
- av[0] = "LIST";
- ac = 1;
- break;
- case 'Q':
- Qflg++;
- actions++;
- av[0] = "query";
- av[1] = optarg;
- ac = 2;
- break;
- case '?':
- errflg++;
- break;
- }
- if (hflg) {
- usage(NULL);
- exit(0);
- }
-
- if (errflg)
- usage(gettext("unrecognized argument"));
- switch (actions) {
- case 0:
- if (argc > 1)
- usage(gettext("must specify an action flag"));
-
- /* default behavior is to list configuration */
- lflg++; av[0] = "list_config"; ac = 1;
- break;
- case 1:
- break;
- default:
- usage(gettext("too many action flags"));
- break;
- }
-
- if (gflg && (Iflg || Jflg || Oflg || Qflg))
- usage(gettext("can't use a group with this option"));
- if (!gflg && (mflg))
- usage(gettext("must use a group with this option"));
-
- /*
- * Open configuration file.
- */
- if ((cfg = cfg_open(NULL)) == NULL) {
- perror("unable to access configuration");
- exit(2);
- }
-
- /*
- * Set write locking (CFG_WRLOCK) for:
- * iiadm -e (enable)
- * iiadm -d (disable)
- * iiadm -A (attach overflow)
- * iiadm -D (detach overflow)
- * iiadm -g grp -m volume (move volume into group)
- * iiadm -E (export shadow [needs to update dsvol section])
- * iiadm -I (import shadow [ditto])
- * iiadm -J (join shadow [ditto])
- * read locking (CFG_RDLOCK) for all other commands
- */
- last_lock = (eflg || dflg || mflg || Aflg || Dflg || Eflg || Iflg ||
- Jflg)? CFG_WRLOCK : CFG_RDLOCK;
- if (!cfg_lock(cfg, last_lock)) {
- perror("unable to lock configuration");
- exit(2);
- }
- config_locked = 1;
-
- /*
- * If we are in a cluster, set or derive a valid disk group
- */
- switch (check_cluster()) {
- case II_CLUSTER:
- /*
- * If in a Sun Cluster, can't Import an II shadow
- * Must be done as -C local
- */
- if (Iflg)
- dsw_error(gettext(
- "-I (import) only allowed as -C local"), NULL);
- /*FALLTHRU*/
- case II_CLUSTER_LCL:
- /*
- * If a cluster tag was specified or derived, set it
- */
- if (CLflg) {
- dsw_list_clusters(argv[optind]);
- cfg_close(cfg);
- exit(0);
- } else {
- cfg_resource(cfg, cfg_cluster_tag);
- }
- break;
- case II_NOT_CLUSTER:
- if (cfg_cluster_tag != NULL)
- dsw_error(gettext(
- "-C is valid only in a Sun Cluster"), NULL);
- break;
- default:
- dsw_error(gettext(
- "Unexpected return from check_cluster()"), NULL);
- }
-
- /* preload the ii config */
- load_ii_vols(cfg);
- reload_vols |= LD_II;
-
- if (eflg) {
- if (argc - optind != 3)
- usage(gettext("must specify 3 volumes with -e"));
- av[1] = argv[optind++];
- av[2] = argv[optind++];
- av[3] = argv[optind++];
- ac = 5;
- dsw_enable(ac, av);
- } else if (dflg) {
- dsw_disable(ac, av);
- } else if (uflg) {
- if (argv[optind] == NULL && group_name == NULL)
- usage(gettext("must specify volume with -u"));
- for (c = 1; argv[optind] != NULL; optind++)
- av[c++] = argv[optind];
- av[c] = NULL;
-
- if (direction == ToMaster)
- dsw_update_master(ac, av);
- else
- dsw_update_shadow(ac, av);
- } else if (iflg) {
- if (argv[optind]) {
- av[1] = argv[optind];
- ac = 2;
- } else
- ac = 1;
- dsw_display_status(ac, av);
- } else if (bflg) {
- dsw_display_bitmap(ac, av);
- } else if (cflg) {
- if (argv[optind] == NULL && group_name == NULL)
- usage(gettext("must specify volume with -c"));
- for (c = 1; argv[optind] != NULL; optind++)
- av[c++] = argv[optind];
- av[c] = NULL;
-
- if (direction == ToMaster)
- dsw_copy_to_master(ac, av);
- else
- dsw_copy_to_shadow(ac, av);
- } else if (aflg) {
- dsw_abort_copy(ac, av);
- } else if (Eflg) {
- dsw_export(ac, av);
- } else if (Iflg) {
- if (argc - optind != 1)
- usage(gettext("must specify 2 volumes with -I"));
- av[2] = argv[optind++];
- ac = 3;
- dsw_import(ac, av);
- } else if (Aflg) {
- if (group_name) {
- if (argc - optind != 0)
- usage(gettext("must specify overflow volume " \
- "when using groups with -A"));
- ac = 2;
- } else {
- if (argc - optind != 1)
- usage(gettext("specify 2 volumes with -A"));
- ac = 3;
- av[2] = argv[optind++];
- }
- dsw_attach(ac, av);
- } else if (Dflg) {
- dsw_detach(ac, av);
- } else if (Jflg) {
- if (argc - optind != 1)
- usage(gettext("must specify 2 volumes with -J"));
- av[2] = argv[optind++];
- ac = 3;
- dsw_join(ac, av);
- } else if (Pflg) {
- if (argc - optind == ((group_name) ? 0 : 1)) {
- av[1] = argv[optind++];
- ac = (group_name) ? 0 : 2;
- } else if (argc - optind == ((group_name) ? 2 : 3)) {
- av[1] = argv[optind++];
- av[2] = argv[optind++];
- av[3] = argv[optind++];
- ac = (group_name) ? 2 : 4;
- } else
- usage(gettext(
- "must specify delay, unit and shadow with -P"));
- dsw_params(ac, av);
- } else if (Oflg) {
- dsw_overflow(ac, av);
- } else if (Rflg) {
- dsw_reset(ac, av);
- } else if (vflg) {
- dsw_version(ac, av);
- } else if (wflg) {
- dsw_wait(ac, av);
- } else if (lflg) {
- if ((gflg) && (!group_name))
- dsw_list_group_volumes();
- else
- dsw_list_volumes(ac, av);
- } else if (Lflg) {
- dsw_olist(ac, av);
- } else if (gLflg) {
- dsw_list_groups();
- } else if (Qflg) {
- dsw_ostat(ac, av);
- } else if (mflg) {
- if (argc - optind < 1)
- usage(gettext("must specify one or more volumes"));
- for (c = 1; argv[optind] != NULL; optind++)
- av[c++] = argv[optind];
- av[c] = NULL;
- dsw_move_2_group(ac, av);
- }
- if (cfg)
- cfg_close(cfg);
-
- exit(0);
- return (0);
-}
-
-static int
-ii_lock(CFGFILE *cfg, int locktype)
-{
- last_lock = locktype;
- return (cfg_lock(cfg, locktype));
-}
-
-static int
-do_ioctl(int fd, int cmd, void *arg)
-{
- int unlocked = 0;
- int rc;
- int save_errno;
-
- if (config_locked) {
- switch (cmd) {
- case DSWIOC_ENABLE:
- case DSWIOC_RESUME:
- case DSWIOC_SUSPEND:
- case DSWIOC_COPY:
- case DSWIOC_BITMAP:
- case DSWIOC_DISABLE:
- case DSWIOC_SHUTDOWN:
- case DSWIOC_ABORT:
- case DSWIOC_RESET:
- case DSWIOC_OFFLINE:
- case DSWIOC_WAIT:
- case DSWIOC_ACOPY:
- case DSWIOC_EXPORT:
- case DSWIOC_IMPORT:
- case DSWIOC_JOIN:
- case DSWIOC_COPYP:
- case DSWIOC_OATTACH:
- case DSWIOC_ODETACH:
- case DSWIOC_SBITSSET:
- case DSWIOC_CBITSSET:
- case DSWIOC_SEGMENT:
- case DSWIOC_MOVEGRP:
- case DSWIOC_CHANGETAG:
- cfg_unlock(cfg);
- unlocked = 1;
- break;
-
- case DSWIOC_STAT:
- case DSWIOC_VERSION:
- case DSWIOC_LIST:
- case DSWIOC_OCREAT:
- case DSWIOC_OLIST:
- case DSWIOC_OSTAT:
- case DSWIOC_OSTAT2:
- case DSWIOC_LISTLEN:
- case DSWIOC_OLISTLEN:
- case DSWIOC_CLIST:
- case DSWIOC_GLIST:
- break;
-
- default:
- (void) fprintf(stderr,
- "cfg locking needs to be set for %08x\n", cmd);
- exit(1);
- break;
- }
- }
- if (unlocked) {
- /* unload vol hashes */
- if (reload_vols & LD_II)
- unload_ii_vols();
- if (reload_vols & LD_SHADOWS)
- cfg_unload_shadows();
- if (reload_vols & LD_DSVOLS)
- cfg_unload_dsvols();
- if (reload_vols & LD_SVOLS)
- cfg_unload_svols();
- }
- rc = ioctl(fd, cmd, arg);
- save_errno = errno;
- if (config_locked && unlocked) {
- (void) cfg_lock(cfg, last_lock);
- }
- if (unlocked) {
- /* reload vol hashes */
- if (reload_vols & LD_SVOLS)
- (void) cfg_load_svols(cfg);
- if (reload_vols & LD_DSVOLS)
- (void) cfg_load_dsvols(cfg);
- if (reload_vols & LD_SHADOWS)
- (void) cfg_load_shadows(cfg);
- if (reload_vols & LD_II)
- load_ii_vols(cfg);
- }
-
- errno = save_errno;
- return (rc);
-}
-
-static int
-get_dsw_config(int setno, dsw_config_t *parms)
-{
- char buf[CFG_MAX_BUF];
- char key[CFG_MAX_KEY];
-
- bzero(parms, sizeof (dsw_config_t));
- (void) snprintf(key, sizeof (key), "ii.set%d.master", setno);
- if (cfg_get_cstring(cfg, key, parms->master_vol, DSW_NAMELEN) < 0)
- return (-1);
-
- (void) snprintf(key, sizeof (key), "ii.set%d.shadow", setno);
- (void) cfg_get_cstring(cfg, key, parms->shadow_vol, DSW_NAMELEN);
-
- (void) snprintf(key, sizeof (key), "ii.set%d.bitmap", setno);
- (void) cfg_get_cstring(cfg, key, parms->bitmap_vol, DSW_NAMELEN);
-
- (void) snprintf(key, sizeof (key), "ii.set%d.mode", setno);
- (void) cfg_get_cstring(cfg, key, buf, sizeof (buf));
- if (strcmp(buf, "I") == 0)
- parms->flag |= DSW_GOLDEN;
-
- (void) snprintf(key, sizeof (key), "ii.set%d.overflow", setno);
- (void) cfg_get_cstring(cfg, key, last_overflow, DSW_NAMELEN);
-
- (void) snprintf(key, sizeof (key), "ii.set%d.group", setno);
- (void) cfg_get_cstring(cfg, key, parms->group_name, DSW_NAMELEN);
-
- (void) snprintf(key, sizeof (key), "ii.set%d.cnode", setno);
- (void) cfg_get_cstring(cfg, key, parms->cluster_tag, DSW_NAMELEN);
- return (0);
-}
-
-static int
-find_next_cf_line(char *volume, int next)
-{
- dsw_config_t cf_line;
-
- for (setnumber = next; get_dsw_config(setnumber, &cf_line) == 0;
- setnumber++) {
- if (strncmp(volume, cf_line.master_vol, DSW_NAMELEN) == 0 ||
- strncmp(volume, cf_line.shadow_vol, DSW_NAMELEN) == 0 ||
- strncmp(volume, cf_line.bitmap_vol, DSW_NAMELEN) == 0)
- return (1);
- }
- return (0);
-}
-int
-find_any_cf_line(char *volume)
-{
- return (find_next_cf_line(volume, 1));
-}
-
-static int
-find_next_shadow_line(char *volume, int next)
-{
- dsw_config_t cf_line;
-
- for (setnumber = next; get_dsw_config(setnumber, &cf_line) == 0;
- setnumber++) {
- if (strncmp(volume, cf_line.shadow_vol, DSW_NAMELEN) == 0)
- return (1);
- }
- return (0);
-}
-int
-find_shadow_line(char *volume)
-{
- return (find_next_shadow_line(volume, 1));
-}
-
-/*
- * this function is designed to be called once, subsequent calls won't
- * free memory allocated by earlier invocations.
- */
-char *
-get_overflow_list()
-{
- dsw_aioctl_t *acopy_args;
- int rc, num;
-
- num = do_ioctl(dsw_fd, DSWIOC_OLISTLEN, NULL);
- if (num < 0)
- dsw_error(gettext("Can't get overflow list length"), NULL);
-
- acopy_args = malloc(sizeof (dsw_aioctl_t) + num * DSW_NAMELEN);
- if (acopy_args == NULL)
- dsw_error(gettext("Can't get memory for list enquiry"), NULL);
-
- acopy_args->count = num;
- acopy_args->flags = 0;
- acopy_args->status = spcs_s_ucreate();
-
- rc = do_ioctl(dsw_fd, DSWIOC_OLIST, acopy_args);
- if (rc == -1)
- dsw_error(gettext("Overflow list access failure"),
- &acopy_args->status);
- else
- acopy_args->shadow_vol[DSW_NAMELEN*acopy_args->count] = NULL;
-
- return (acopy_args->shadow_vol);
-}
-
-/*
- * this function is designed to be called once, subsequent calls won't
- * free memory allocated by earlier invocations.
- */
-
-int
-find_group_members(char *group)
-{
- int nmembers = 0;
- int vector_len = 0;
-
- group_volumes = NULL;
- for (setnumber = 1; /*CSTYLED*/; setnumber++) {
- (void) snprintf(key, sizeof (key), "ii.set%d.group", setnumber);
- if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0)
- break;
-
- if (strcmp(group, buf))
- continue;
-
- (void) snprintf(key, sizeof (key), "ii.set%d.shadow",
- setnumber);
- if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0)
- break;
-
- if (nmembers >= vector_len) {
- vector_len += 10;
- group_volumes = realloc(group_volumes, (1+vector_len) *
- sizeof (char *));
- }
- group_volumes[nmembers] = strdup(buf);
- nmembers++;
- }
- if (group_volumes)
- group_volumes[nmembers] = NULL; /* terminate list */
- return (nmembers);
-}
-
-static int
-find_next_matching_cf_line(
- char *volume, dsw_config_t *conf, dsw_ioctl_t *io, int next)
-{
- dsw_config_t config;
-
- if (!find_next_cf_line(volume, next)) {
- return (0);
- }
-
- if (conf == NULL)
- conf = &config;
- (void) get_dsw_config(setnumber, conf);
- if (io) {
- (void) strlcpy(io->shadow_vol, conf->shadow_vol, DSW_NAMELEN);
- }
- return (1);
-}
-
-int
-find_matching_cf_line(char *volume, dsw_config_t *conf, dsw_ioctl_t *io)
-{
- return (find_next_matching_cf_line(volume, conf, io, 1));
-}
-
-int
-find_shadow_config(char *volume, dsw_config_t *conf, dsw_ioctl_t *io)
-{
- dsw_config_t *c, cf;
-
- if (io) {
- bzero(io, sizeof (dsw_ioctl_t));
- }
- c = conf ? conf : &cf;
- setnumber = 1;
- /* perform action for each line of the stored config file */
- for ((void) snprintf(key, sizeof (key), "ii.set%d.shadow", setnumber);
- cfg_get_cstring(cfg, key, c->shadow_vol, DSW_NAMELEN) >= 0;
- (void) snprintf(key, sizeof (key), "ii.set%d.shadow",
- ++setnumber)) {
- if (strncmp(volume, c->shadow_vol, DSW_NAMELEN) == 0) {
- (void) get_dsw_config(setnumber, c);
-
- if (check_resource_group(c->bitmap_vol)) {
- setnumber = 0;
- continue;
- }
-
- switch (check_cluster()) {
- case II_CLUSTER:
- if ((cfg_cluster_tag) &&
- (strcmp(cfg_cluster_tag, c->cluster_tag)))
- continue;
- break;
- case II_CLUSTER_LCL:
- if (strlen(c->cluster_tag))
- continue;
- break;
- }
-
- if (io) {
- (void) strlcpy(io->shadow_vol, c->shadow_vol,
- DSW_NAMELEN);
- }
- return (1);
- }
- }
- return (0);
-}
-
-void
-add_cfg_entry(dsw_config_t *parms)
-{
- /* insert the well-known fields first */
- (void) snprintf(buf, sizeof (buf), "%s %s %s %s",
- parms->master_vol, parms->shadow_vol, parms->bitmap_vol,
- (parms->flag & DSW_GOLDEN) ? "I" : "D");
-
- if (cfg_put_cstring(cfg, "ii", buf, strlen(buf)) >= 0) {
- /* if we have a group name, add it */
- if (group_name) {
- if (find_any_cf_line(parms->shadow_vol)) {
- (void) sprintf(buf, "ii.set%d.group",
- setnumber);
- if (cfg_put_cstring(cfg, buf,
- group_name, strlen(group_name)) < 0)
- perror("cfg_put_cstring");
- }
- else
- perror("cfg_location");
- }
-
- /* commit the record */
- (void) cfg_commit(cfg);
- }
- else
- perror("cfg_put_string");
-}
-
-void
-remove_iiset(int setno, char *shadow, int shd_exp)
-{
- mstcount_t *mdata;
- shdvol_t *sdata;
- char sn[CFG_MAX_BUF];
-
- if (perform_autosv()) {
- if (volhash) {
- unload_ii_vols();
- }
- load_ii_vols(cfg);
- if (cfg_load_dsvols(cfg) < 0 || cfg_load_svols(cfg) < 0) {
- dsw_error(gettext("Unable to parse config file"), NULL);
- }
-
- sdata = (shdvol_t *)nsc_lookup(volhash, shadow);
- if (sdata) {
- /*
- * Handle the normal cases of disabling a set that is
- * not an imported shadow volume
- */
- if (strcmp(sdata->master, II_IMPORTED_SHADOW)) {
- /*
- * Handle multiple-shadows of single master
- */
- mdata = (mstcount_t *)
- nsc_lookup(volhash, sdata->master);
- if ((mdata) && (mdata->count == 1)) {
- if (cfg_vol_disable(cfg, sdata->master,
- cfg_cluster_tag, "ii") < 0)
- dsw_error(gettext(
- "SV disable of master "
- "failed"),
- NULL);
- }
- }
-
- /*
- * Handle disk group name of different shadow
- */
- if (shd_exp) {
- /*
- * If shadow is exported, then do nothing
- */
- /*EMPTY*/;
- } else if (cfg_cluster_tag &&
- strcmp(cfg_cluster_tag, "") &&
- cfg_dgname(shadow, sn, sizeof (sn)) &&
- strlen(sn) &&
- strcmp(sn, cfg_cluster_tag)) {
- /* reload disk group volumes */
- cfg_resource(cfg, sn);
- cfg_unload_dsvols();
- cfg_unload_svols();
- (void) cfg_load_dsvols(cfg);
- (void) cfg_load_svols(cfg);
- if (cfg_vol_disable(cfg, shadow, sn,
- "ii") < 0) {
- dsw_error(gettext(
- "SV disable of shadow "
- "failed"),
- NULL);
- }
- cfg_resource(cfg, cfg_cluster_tag);
- } else {
- if (cfg_vol_disable(cfg, shadow,
- cfg_cluster_tag, "ii") < 0)
- dsw_error(gettext(
- "SV disable of shadow failed"),
- NULL);
- }
- }
- cfg_unload_svols();
- cfg_unload_dsvols();
- unload_ii_vols();
- reload_vols &= ~(LD_SVOLS | LD_DSVOLS | LD_II);
- }
-
- (void) sprintf(key, "ii.set%d", setno);
- if (cfg_put_cstring(cfg, key, NULL, 0) < 0) {
- perror("cfg_put_cstring");
- }
- (void) cfg_commit(cfg);
-}
-
-/*
- * determine if we are running in a Sun Cluster Environment
- */
-int
-check_cluster()
-{
- static int is_cluster = -1;
- int rc;
-#ifdef DEBUG
- char *cdebug = getenv("II_SET_CLUSTER");
-#endif
-
- /*
- * If this routine was previously called, just return results
- */
- if (is_cluster != -1)
- return (is_cluster);
-
- /*
- * See if Sun Cluster was installed on this node
- */
-#ifdef DEBUG
- if (cdebug) rc = atoi(cdebug);
- else
-#endif
- rc = cfg_iscluster();
- if (rc > 0) {
- /*
- * Determine if user specified -C local
- */
- if ((cfg_cluster_tag == NULL) ||
- (strcmp(cfg_cluster_tag, II_LOCAL_TAG))) {
- /*
- * We're in a Sun Cluster, and no "-C local"
- */
- is_cluster = II_CLUSTER;
- } else {
- /*
- * We're in a Sun Cluster, but "-C local" was specified
- */
- is_cluster = II_CLUSTER_LCL;
- cfg_cluster_tag = "";
- }
- return (is_cluster);
- } else if (rc == 0) {
- /*
- * Not in a Sun Cluster
- */
- is_cluster = II_NOT_CLUSTER;
- return (is_cluster);
- } else {
- dsw_error(gettext("unable to ascertain environment"), NULL);
- /*NOTREACHED*/
- }
-
- /* gcc */
- return (is_cluster);
-}
-
-/*
- * Determine if we need to set a cfg_resource based on this volume
- */
-static int
-check_resource_group(char *volume)
-{
- char diskgroup[CFG_MAX_BUF];
-
- /*
- * If we are in a cluster, attempt to derive a new resource group
- */
-
-#ifdef DEBUG
- if (getenv("II_SET_CLUSTER") || (check_cluster() == II_CLUSTER)) {
-#else
- if (check_cluster() == II_CLUSTER) {
-#endif
- if (check_diskgroup(volume, diskgroup)) {
- if (cfg_cluster_tag == NULL) {
- cfg_cluster_tag = strdup(diskgroup);
- if (cfg_cluster_tag == NULL)
- dsw_error(gettext(
- "Memory allocation failure"), NULL);
- cfg_resource(cfg, cfg_cluster_tag);
- return (1);
- } else {
- /*
- * Check dgname and cluster tag from -C are
- * the same.
- */
- if (strcmp(diskgroup, cfg_cluster_tag) != 0) {
- char error_buffer[128];
- (void) snprintf(error_buffer,
- sizeof (error_buffer),
- gettext("-C (%s) does not match "
- "disk group name (%s) for %s"),
- cfg_cluster_tag, diskgroup, volume);
- spcs_log("ii", NULL, error_buffer);
- dsw_error(error_buffer, NULL);
- }
- }
- } else if (cfg_cluster_tag == NULL)
- dsw_error(gettext(
- "Point-in-Time Copy volumes, that are not "
- "in a device group which has been "
- "registered with SunCluster, "
- "require usage of \"-C\""), NULL);
- }
- return (0);
-}
-
-static void
-check_dg_is_local(char *dgname)
-{
- char error_buffer[128];
- char *othernode;
- int rc;
-
- /*
- * check where this disk service is mastered
- */
- rc = cfg_dgname_islocal(dgname, &othernode);
- if (rc < 0) {
- (void) snprintf(error_buffer, sizeof (error_buffer),
- gettext("Unable to find disk service:%s"), dgname);
- dsw_error(error_buffer, NULL);
- } else if (rc == 0) {
- (void) snprintf(error_buffer, sizeof (error_buffer),
- gettext("disk service, %s, is active on node \"%s\"\n"
- "Please re-issue the command on that node"), dgname,
- othernode);
- dsw_error(error_buffer, NULL);
- }
-}
-
-/*
- * Carry out cluster based checks for a specified volume, or just
- * global options.
- */
-static int
-check_diskgroup(char *path, char *result)
-{
- char dgname[CFG_MAX_BUF];
- char error_buffer[128];
-
-#ifdef DEBUG
- char *override = getenv("II_CLUSTER_TAG");
- if (override) {
- (void) strcpy(result, override);
- return (1);
- }
-#endif
- /*
- * Check on path name, a returned NULL dgname is valid
- */
- if (cfg_dgname(path, dgname, sizeof (dgname)) == NULL) {
- (void) snprintf(error_buffer, sizeof (error_buffer), gettext(
- "unable to determine disk group name for %s"), path);
- dsw_error(error_buffer, NULL);
- }
- if (strcmp(dgname, "") == 0)
- return (0);
-
- /*
- * See if disk group is local to this node
- */
- check_dg_is_local(dgname);
-
- /*
- * Copy dgname into result
- */
- (void) strcpy(result, dgname);
- return (1);
-}
-
-/*
- * sigterm (): traps specified signal , usually termination one
- */
-void
-sigterm(int sig)
-{
- spcs_log("ii", NULL, gettext("%s received signal %d"), cmdnam, sig);
- exit(1);
-}
-
-/*
- * sigchild; reap child and collect status.
- */
-
-volatile pid_t dead_child;
-int dead_stat;
-
-/*ARGSUSED*/
-void
-sigchild(int sig)
-{
- dead_child = wait(&dead_stat);
-}
-
-/*
- * InitEnv(): initializes environment
- */
-void
-InitEnv()
-{
- (void) setlocale(LC_ALL, "");
- (void) textdomain(DSW_TEXT_DOMAIN);
-
-#ifndef DEBUG
- (void) sigset(SIGHUP, sigterm);
- (void) sigset(SIGINT, sigterm);
- (void) sigset(SIGQUIT, sigterm);
- (void) sigset(SIGILL, sigterm);
- (void) sigset(SIGEMT, sigterm);
- (void) sigset(SIGABRT, sigterm);
- (void) sigset(SIGFPE, sigterm);
- (void) sigset(SIGBUS, sigterm);
- (void) sigset(SIGSEGV, sigterm);
- (void) sigset(SIGTERM, sigterm);
- (void) sigset(SIGPWR, sigterm);
- (void) sigset(SIGSTOP, sigterm);
- (void) sigset(SIGTSTP, sigterm);
-#endif
-
- dsw_fd = open(DSWDEV, O_RDONLY);
- if (dsw_fd < 0) {
- perror(DSWDEV);
- exit(1);
- }
-
- (void) setsid();
-}
-
-/*
- * print an error message, followed by decoded errno then exit.
- */
-void
-dsw_error(char *str, spcs_s_info_t *status)
-{
- char *sp;
-
- (void) fprintf(stderr, "%s: %s:\n", cmdnam, str);
- if (status == NULL) {
- /* deflect ESRCH */
- if (ESRCH == errno) {
- sp = "Set/volume not found";
- } else {
- sp = strerror(errno);
- }
- (void) fprintf(stderr, "%s\n", sp ? sp : "");
- } else {
- spcs_s_report(*status, stderr);
- spcs_s_ufree(status);
- }
- if (cfg)
- cfg_close(cfg);
- exit(2);
-}
-
-
-#undef size
-
-void
-free_bitmap(unsigned char *bitmap)
-{
- free(bitmap);
-}
-
-
-int
-get_bitmap(master_volume, shd_bitmap, copy_bitmap, size)
- char *master_volume;
- unsigned char *shd_bitmap;
- unsigned char *copy_bitmap;
- unsigned long size;
-{
- dsw_bitmap_t parms;
-
- (void) strlcpy(parms.shadow_vol, master_volume, DSW_NAMELEN);
- parms.shd_bitmap = shd_bitmap;
- parms.shd_size = size;
- parms.copy_bitmap = copy_bitmap;
- parms.copy_size = size;
-
- return (do_ioctl(dsw_fd, DSWIOC_BITMAP, &parms));
-}
-
-unsigned char *
-allocate_bitmap(char *shadow_volume)
-{
- unsigned char *shd_bitmap;
- unsigned char *copy_bitmap;
- unsigned char *p;
- unsigned char *q;
- int i;
- dsw_stat_t args;
- int stat_flags;
-
- (void) strlcpy(args.shadow_vol, shadow_volume, DSW_NAMELEN);
-
- args.status = spcs_s_ucreate();
- if (do_ioctl(dsw_fd, DSWIOC_STAT, &args) == -1)
- dsw_error(gettext("Stat failed"), &args.status);
-
- stat_flags = args.stat;
- if (stat_flags & DSW_BMPOFFLINE)
- return (NULL);
-
- bm_size = args.size;
- bm_size = (bm_size + DSW_SIZE-1) / DSW_SIZE;
- bm_actual = bm_size;
- bm_size = (bm_size + DSW_BITS-1) / DSW_BITS;
- spcs_s_ufree(&args.status);
-
- p = shd_bitmap = (unsigned char *) malloc(bm_size);
- if (!shd_bitmap) {
- perror(gettext("malloc bitmap"));
- return (NULL);
- }
-
- q = copy_bitmap = (unsigned char *) malloc(bm_size);
- if (!copy_bitmap) {
- perror(gettext("malloc bitmap"));
- free(shd_bitmap);
- return (NULL);
- }
-
- (void) memset(shd_bitmap, 0, bm_size);
- (void) memset(copy_bitmap, 0, bm_size);
-
- if (get_bitmap(shadow_volume, shd_bitmap, copy_bitmap, bm_size) < 0) {
- free(copy_bitmap);
- free(shd_bitmap);
- return (NULL);
- }
-
- /*
- * "or" the copy and shadow bitmaps together to return a composite
- * bitmap that contains the total set of differences between the
- * volumes.
- */
- for (i = bm_size; i-- > 0; /*CSTYLED*/)
- *p++ |= *q++;
-
- free(copy_bitmap);
-
- return (shd_bitmap);
-}
-
-/*
- * print usage message and exit.
- */
-void
-usage(char *why)
-{
- if (why) {
- (void) fprintf(stderr, "%s: %s\n", cmdnam, why);
-
- (void) fprintf(stderr, "%s\n",
- gettext("\nBrief summary:"));
- (void) fprintf(stderr, "%s\n",
- gettext("\t-e {ind|dep} master_vol shadow_vol "
- "bitmap_vol"));
- (void) fprintf(stderr, "%s\n",
- gettext("\t-[cu {s|m}] volume_set"));
- (void) fprintf(stderr, "%s\n",
- gettext("\t-i all"));
- (void) fprintf(stderr, "%s\n",
- gettext("\t-[adDEilPRw] volume_set"));
- (void) fprintf(stderr, "%s\n",
- gettext("\t-g group_name [options]"));
- (void) fprintf(stderr, "%s\n",
- gettext("\t-C cluster_tag [options]"));
- (void) fprintf(stderr, "%s\n",
- gettext("\t-[hilLv]"));
- (void) fprintf(stderr, "%s\n",
- gettext("\t-[IJ] volume_set bitmap"));
- (void) fprintf(stderr, "%s\n",
- gettext("\t-A overflow_vol volume_set"));
- (void) fprintf(stderr, "%s\n",
- gettext("\t-[OQ] overflow_vol"));
- (void) fprintf(stderr, "%s\n",
- gettext("\t-P {delay} {units} volume_set"));
-
- /* assume we came here due to a user mistake */
- exit(1);
- /* NOTREACHED */
- } else {
-
- (void) fprintf(stdout, "%s\n",
- gettext("Point-in-Time Copy Administrator CLI options"));
- (void) fprintf(stdout, "%s\n",
- gettext("Usage summary:"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-e ind m s b\tenable independent master shadow "
- "bitmap"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-e dep m s b\tenable dependent master shadow "
- "bitmap"));
- if (check_cluster() == II_CLUSTER)
- (void) fprintf(stdout, "%s\n",
- gettext("\t-ne ind m s b\tenable exportable master "
- "shadow bitmap"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-d v\t\tdisable volume"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-u s v\t\tupdate shadow volume"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-u m v\t\tupdate master volume"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-c s v\t\tcopy to shadow volume"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-c m v\t\tcopy to master volume"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-a v\t\tabort copy volume"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-w v\t\twait volume"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-i v\t\tdisplay volume status"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-i all\t\tdisplay all volume status"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-l\t\tlist all volumes"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-R v\t\treset volume"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-A o v\t\tattach overflow to volume"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-D v\t\tdetach overflow from volume"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-L\t\tlist all overflow volumes"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-O o\t\tinitialize overflow"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-Q o\t\tquery status of overflow"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-E v\t\texport shadow volume"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-I v b\t\timport volume bitmap"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-J v b\t\tjoin volume bitmap"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-P d u v\tset copy delay/units for volume"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-P v\t\tget copy delay/units for volume"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-C tag\t\tcluster resource tag"));
-#ifdef DEBUG
- (void) fprintf(stdout, "%s\n",
- gettext("\t-b v\t\tdisplay bitmap volume"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-f f\t\tuse private configuration file"));
-#endif
- (void) fprintf(stdout, "%s\n",
- gettext("\t-v\t\tprint software versions"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-n\t\tperform action without question"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-p [-c|-u] {m|s}"
- "enable PID locking on copy or update"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-p -w v\t\tdisable PID locking"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-h\t\tiiadm usage summary"));
- (void) fprintf(stdout, "%s\n",
- gettext("\nUsage summary for options that support "
- "grouping (-g g):"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-g g -e ind m s b group enable independent "
- "master shadow bitmap"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-g g -e dep m s b group enable dependent "
- "master shadow bitmap"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-g g -d\t\tdisable group"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-g g -u s\tupdate shadow for all volumes in "
- "group"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-g g -u m\tupdate master for all volumes in "
- "group"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-g g -c s\tcopy to shadow for all volumes in "
- "group"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-g g -c m\tcopy to master for all volumes in "
- "group"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-g g -a\t\tabort copy for all volumes in "
- "group"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-g g -w\t\twait for all volumes in group"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-g g -i\t\tdisplay status of all volumes in "
- "group"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-g g -l\t\tlist all volumes in group"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-g -L\t\tlist all groups"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-g g -m v v\tmove one or more volumes into "
- "group"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-g \"\" -m v\tremove volume from group"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-g g -R\t\treset all volumes in group"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-g g -A o\tattach overflow to all volumes in "
- "group"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-g g -D\t\tdetach overflow from all volumes in "
- "group"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-g g -E\t\texport shadow volume for all "
- "volumes in group"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-g g -P d u\tset copy delay/units for all "
- "volumes in group"));
- (void) fprintf(stdout, "%s\n",
- gettext("\t-g g -P\t\tget copy delay/units for all "
- "volumes in group"));
- (void) fprintf(stdout, "%s\n",
- gettext("\nLegend summary:"));
- (void) fprintf(stdout, "%s\n",
- gettext("\tind\t\tindependent volume set"));
- (void) fprintf(stdout, "%s\n",
- gettext("\tdep\t\tdependent volume set"));
- (void) fprintf(stdout, "%s\n",
- gettext("\tall\t\tall configured volumes"));
- (void) fprintf(stdout, "%s\n",
- gettext("\tm\t\tmaster volume"));
- (void) fprintf(stdout, "%s\n",
- gettext("\ts\t\tshadow volume"));
- (void) fprintf(stdout, "%s\n",
- gettext("\tv\t\tshadow volume (reference name)"));
- (void) fprintf(stdout, "%s\n",
- gettext("\to\t\toverflow volume"));
- (void) fprintf(stdout, "%s\n",
- gettext("\tb\t\tbitmap volume"));
-#ifdef DEBUG
- (void) fprintf(stdout, "%s\n",
- gettext("\tf\t\tconfiguration file name"));
-#endif
- (void) fprintf(stdout, "%s\n",
- gettext("\td\t\tdelay tick interval"));
- (void) fprintf(stdout, "%s\n",
- gettext("\tu\t\tunit size"));
- (void) fprintf(stdout, "%s\n",
- gettext("\tg\t\tgroup name"));
-
- /* assume we came here because user request help text */
- exit(0);
- /* NOTREACHED */
- }
-
-}
-
-static char yeschr[MAX_LINE_SIZE + 2];
-static char nochr[MAX_LINE_SIZE + 2];
-
-static int
-yes(void)
-{
- int i, b;
- char ans[MAX_LINE_SIZE + 1];
-
- for (i = 0; /*CSTYLED*/; i++) {
- b = getchar();
- if (b == '\n' || b == '\0' || b == EOF) {
- if (i < MAX_LINE_SIZE)
- ans[i] = 0;
- break;
- }
- if (i < MAX_LINE_SIZE)
- ans[i] = b;
- }
- if (i >= MAX_LINE_SIZE) {
- i = MAX_LINE_SIZE;
- ans[MAX_LINE_SIZE] = 0;
- }
- if ((i == 0) || (strncmp(yeschr, ans, i))) {
- if (strncmp(nochr, ans, i) == 0)
- return (0);
- else if (strncmp(yeschr, ans, i) == 0)
- return (1);
- else {
- (void) fprintf(stderr, "%s %s/%s\n",
- gettext("You have to respond with"),
- yeschr, nochr);
- return (2);
- }
- }
- return (1);
-}
-
-static int
-convert_int(char *str)
-{
- int result, rc;
- char *buf;
-
- buf = (char *)calloc(strlen(str) + 256, sizeof (char));
- rc = sscanf(str, "%d%s", &result, buf);
-
- if (rc != 1) {
- (void) sprintf(buf, gettext("'%s' is not a valid number"), str);
- /* dsw_error calls exit which frees 'buf' */
- errno = EINVAL;
- dsw_error(buf, NULL);
- }
- free(buf);
-
- return (result);
-}
-
-void
-check_action(char *will_happen)
-{
- int answer;
-
- if (nflg || !isatty(fileno(stdin)))
- return;
- (void) strncpy(yeschr, nl_langinfo(YESSTR), MAX_LINE_SIZE + 1);
- (void) strncpy(nochr, nl_langinfo(NOSTR), MAX_LINE_SIZE + 1);
-
- /*CONSTCOND*/
- while (1) {
- (void) printf("%s %s/%s ", will_happen, yeschr, nochr);
- answer = yes();
- if (answer == 1 || answer == 0)
- break;
- }
- if (answer == 1)
- return;
- exit(1);
-}
-
-enum child_event {Status, CopyStart};
-
-/*
- * Wait for child process to get to some state, where some state may be:
- *
- * Status Set up the shadow enough so that it responds
- * to status requests.
- * CopyStart Start copy/update operations.
- */
-
-int
-child_wait(pid_t child, enum child_event event, char *volume)
-{
- dsw_stat_t args;
- int rc;
-
- (void) strlcpy(args.shadow_vol, volume, DSW_NAMELEN);
-
- for (; dead_child != child; (void) sleep(1)) {
-
- /* poll shadow group with a status ioctl() */
- args.status = spcs_s_ucreate();
- errno = 0;
- rc = do_ioctl(dsw_fd, DSWIOC_STAT, &args);
-
- spcs_s_ufree(&args.status);
-
- if (event == Status) {
- /* keep polling while we fail with DSW_ENOTFOUND */
- if (rc != -1 || errno != DSW_ENOTFOUND)
- return (0);
- } else {
- /* event == CopyStart */
- if (rc == -1) {
- return (1); /* something wrong */
- }
- if (args.stat & DSW_COPYINGP)
- return (0); /* copying underway */
- }
- }
- /* child died */
- if (WIFEXITED(dead_stat))
- return (WEXITSTATUS(dead_stat));
- else
- return (1);
-}
-
-int
-mounted(char *t)
-{
- int rdsk;
- int i;
- FILE *mntfp;
- struct mnttab mntref;
- struct mnttab mntent;
- char target[DSW_NAMELEN];
- char *s;
-
- rdsk = i = 0;
- for (s = target; i < DSW_NAMELEN && (*s = *t++); i++) {
- if (*s == 'r' && rdsk == 0)
- rdsk = 1;
- else
- s++;
- }
- *s = '\0';
-
- mntref.mnt_special = target;
- mntref.mnt_mountp = NULL;
- mntref.mnt_fstype = NULL;
- mntref.mnt_mntopts = NULL;
- mntref.mnt_time = NULL;
-
- if ((mntfp = fopen("/etc/mnttab", "r")) == NULL) {
- dsw_error(gettext("Can not check volume against mount table"),
- NULL);
- }
- if (getmntany(mntfp, &mntent, &mntref) != -1) {
- /* found something before EOF */
- (void) fclose(mntfp);
- return (1);
- }
- (void) fclose(mntfp);
- return (0);
-}
-
-void
-enable(char *master_volume, char *shadow_volume,
- char *bitmap_volume, char *copy_type)
-{
- dsw_config_t parms;
- dsw_ioctl_t temp;
- char *p;
- int rc;
- pid_t child;
- spcs_s_info_t *sp_info;
- struct stat mstat, sstat, bstat;
- char mst_dg[DSW_NAMELEN] = {0};
- char shd_dg[DSW_NAMELEN] = {0};
- char bmp_dg[DSW_NAMELEN] = {0};
- int mvol_enabled;
- char *altname;
- grptag_t *gdata;
-
- bzero(&parms, sizeof (dsw_config_t));
-
- if (strcmp(copy_type, "independent") == 0 ||
- strcmp(copy_type, gettext("independent")) == 0)
- parms.flag = DSW_GOLDEN;
- else if (strcmp(copy_type, "dependent") == 0 ||
- strcmp(copy_type, gettext("dependent")) == 0)
- parms.flag = 0;
- else
- dsw_error(gettext("don't understand shadow type"), NULL);
-
- /* validate volume names */
- if (perform_autosv()) {
- if (cfg_load_svols(cfg) < 0 || cfg_load_dsvols(cfg) < 0 ||
- cfg_load_shadows(cfg) < 0) {
- dsw_error(gettext("Unable to parse config file"), NULL);
- }
- load_ii_vols(cfg);
- reload_vols = LD_SVOLS | LD_DSVOLS | LD_SHADOWS | LD_II;
-
- /* see if it's been used before under a different name */
- conform_name(&master_volume);
- conform_name(&shadow_volume);
- rc = cfg_get_canonical_name(cfg, bitmap_volume, &altname);
- if (rc < 0) {
- dsw_error(gettext("Unable to parse config file"), NULL);
- }
- if (rc) {
- errno = EBUSY;
- dsw_error(gettext("Bitmap in use"), NULL);
- }
- }
-
- /*
- * If not local, determine disk group names for volumes in II set
- */
- switch (check_cluster()) {
- case II_CLUSTER:
- /*
- * Check if none or all volumes are in a disk group
- */
- rc = 0;
- if (check_diskgroup(master_volume, mst_dg)) rc++;
- if (check_diskgroup(shadow_volume, shd_dg)) rc++;
- if (check_diskgroup(bitmap_volume, bmp_dg)) rc++;
- if ((rc != 0) && (rc != 3))
- dsw_error(gettext(
- "Not all Point-in-Time Copy volumes are "
- "in a disk group"), NULL);
-
- /*
- * If volumes are not in a disk group, but are in a
- * cluster, then "-C <tag>", must be set
- */
- if (rc == 0 && cfg_cluster_tag == NULL)
- dsw_error(gettext(
- "Point-in-Time Copy volumes, that are not "
- "in a device group which has been "
- "registered with SunCluster, "
- "require usage of \"-C\""), NULL);
-
- /*
- * the same disk group
- * If -n, plus mst_dg==bmp_dg, then allow E/I/J in SunCluster
- */
- if ((strcmp(mst_dg, bmp_dg)) ||
- (strcmp(mst_dg, shd_dg) && (!nflg)))
- dsw_error(gettext(
- "Volumes are not in same disk group"), NULL);
-
- /*
- * Can never enable the same shadow twice, regardless of
- * exportable shadow device group movement
- */
- if (find_shadow_line(shadow_volume))
- dsw_error(gettext(
- "Shadow volume is already configured"), NULL);
-
- /*
- * Groups cannot span multiple clusters
- */
- if (group_name && perform_autosv()) {
- gdata = (grptag_t *)nsc_lookup(volhash, group_name);
- if (gdata &&
- strncmp(gdata->ctag, mst_dg, DSW_NAMELEN) != 0) {
- errno = EINVAL;
- dsw_error(gettext("Group contains sets not "
- "in the same cluster resource"), NULL);
- }
- }
-
- /*
- * Check cluster tag and bitmap disk group
- * set latter if different
- */
- if (check_resource_group(bitmap_volume)) {
- /*
- * Unload and reload in the event cluster tag has
- * changed
- */
- if (perform_autosv()) {
- unload_ii_vols();
- cfg_unload_shadows();
- cfg_unload_dsvols();
- cfg_unload_svols();
- if (cfg_load_svols(cfg) < 0 ||
- cfg_load_dsvols(cfg) < 0 ||
- cfg_load_shadows(cfg) < 0) {
- dsw_error(gettext(
- "Unable to parse config "
- "file"), NULL);
- }
- load_ii_vols(cfg);
- }
- }
- /*
- * Copy cluster name into config
- */
- (void) strncpy(parms.cluster_tag, cfg_cluster_tag, DSW_NAMELEN);
- break;
-
- case II_CLUSTER_LCL:
- /* ensure that the -C local won't interfere with the set */
- if (group_name && perform_autosv()) {
- gdata = (grptag_t *)nsc_lookup(volhash, group_name);
- if (gdata) {
- if (strlen(gdata->ctag) != 0) {
- errno = EINVAL;
- dsw_error(gettext("Unable to put set "
- "into -C local and specified "
- "group"), NULL);
- }
- }
- }
- break;
- }
-
- /*
- * If we've got a group name, add it into the config
- */
- if (group_name) {
- (void) strncpy(parms.group_name, group_name, DSW_NAMELEN);
- }
-
- /*
- * Determine accessability of volumes
- */
- if (stat(master_volume, &mstat) != 0)
- dsw_error(gettext(
- "Unable to access master volume"), NULL);
- if (!S_ISCHR(mstat.st_mode))
- dsw_error(gettext(
- "Master volume is not a character device"), NULL);
- /* check the shadow_vol hasn't be used as SNDR secondary vol */
- check_iishadow(shadow_volume);
- if (stat(shadow_volume, &sstat) != 0)
- dsw_error(gettext(
- "Unable to access shadow volume"), NULL);
- if (!S_ISCHR(sstat.st_mode))
- dsw_error(gettext(
- "Shadow volume is not a character device"), NULL);
- if (mounted(shadow_volume)) {
- errno = EBUSY;
- dsw_error(gettext(
- "Shadow volume is mounted, unmount it first"), NULL);
- }
- if (mstat.st_rdev == sstat.st_rdev) {
- errno = EINVAL;
- dsw_error(gettext(
- "Master and shadow are the same device"), NULL);
- }
- if (stat(bitmap_volume, &bstat) != 0) {
- dsw_error(gettext("Unable to access bitmap"), NULL);
- }
- if (!S_ISCHR(bstat.st_mode))
- dsw_error(gettext(
- "Bitmap volume is not a character device"), NULL);
- if (S_ISCHR(bstat.st_mode)) {
- if (mstat.st_rdev == bstat.st_rdev) {
- errno = EINVAL;
- dsw_error(gettext(
- "Master and bitmap are the same device"), NULL);
- } else if (sstat.st_rdev == bstat.st_rdev) {
- errno = EINVAL;
- dsw_error(gettext(
- "Shadow and bitmap are the same device"), NULL);
- }
- }
-
- (void) strncpy(parms.master_vol, master_volume, DSW_NAMELEN);
- (void) strncpy(parms.shadow_vol, shadow_volume, DSW_NAMELEN);
- (void) strncpy(parms.bitmap_vol, bitmap_volume, DSW_NAMELEN);
- errno = 0;
- parms.status = spcs_s_ucreate();
-
- /*
- * Check that none of the member volumes forms part of another
- * InstantImage group.
- *
- * -- this check has been removed; it is done in the kernel instead
- * -- PJW
- */
-
- /*
- * Check against overflow volumes
- */
- for (p = get_overflow_list(); *p != NULL; p += DSW_NAMELEN) {
- if (strncmp(master_volume, p, DSW_NAMELEN) == 0)
- dsw_error(gettext(
- "Master volume is already an overflow volume"),
- NULL);
- else if (strncmp(shadow_volume, p, DSW_NAMELEN) == 0)
- dsw_error(gettext(
- "Shadow volume is already an overflow volume"),
- NULL);
- else if (strncmp(bitmap_volume, p, DSW_NAMELEN) == 0)
- dsw_error(gettext(
- "Bitmap volume is already an overflow volume"),
- NULL);
- }
-
- /*
- * Make sure that the shadow volume is not already configured
- */
- if (find_shadow_config(shadow_volume, NULL, &temp))
- dsw_error(gettext(
- "Shadow volume is already configured"), NULL);
- if (perform_autosv()) {
- /*
- * parse the dsvol entries to see if we need to place
- * the master or shadow under SV control
- */
- if (nsc_lookup(volhash, master_volume) == NULL) {
- if (cfg_vol_enable(cfg, master_volume, cfg_cluster_tag,
- "ii") < 0) {
- dsw_error(
- gettext("Cannot enable master volume"),
- NULL);
- }
- mvol_enabled = 1;
- } else {
- mvol_enabled = 0;
- }
- if (nsc_lookup(volhash, shadow_volume) == NULL) {
- if (nflg) {
- cfg_resource(cfg, shd_dg);
- rc = cfg_vol_enable(cfg, shadow_volume,
- shd_dg, "ii");
- cfg_resource(cfg, cfg_cluster_tag);
- } else {
- rc = cfg_vol_enable(cfg, shadow_volume,
- cfg_cluster_tag, "ii");
- }
- if (rc < 0) {
- if (mvol_enabled) {
- if (cfg_vol_disable(cfg,
- master_volume, cfg_cluster_tag,
- "ii") < 0)
- dsw_error(gettext(
- "SV disable of master "
- "failed"),
- NULL);
- }
- dsw_error(
- gettext("Cannot enable shadow volume"),
- NULL);
- }
- }
- unload_ii_vols();
- cfg_unload_shadows();
- cfg_unload_dsvols();
- cfg_unload_svols();
- reload_vols = 0;
- }
-
- add_cfg_entry(&parms);
- cfg_unlock(cfg);
- config_locked = 0;
-
- (void) sigset(SIGCHLD, sigchild);
- switch (child = fork()) {
-
- case (pid_t)-1:
- dsw_error(gettext("Unable to fork"), NULL);
- break;
-
- case 0:
- rc = do_ioctl(dsw_fd, DSWIOC_ENABLE, &parms);
- if (rc == -1 && errno != DSW_EABORTED && errno != DSW_EIO) {
- /*
- * Failed to enable shadow group, log problem and remove
- * the shadow group from the config file.
- */
- spcs_log("ii", &parms.status,
- gettext("Enable failed %s %s %s (%s)"),
- master_volume, shadow_volume, bitmap_volume,
- parms.flag & DSW_GOLDEN ?
- "independent" : "dependent");
-
- if (!ii_lock(cfg, CFG_WRLOCK) ||
- !find_shadow_config(shadow_volume, NULL, &temp)) {
- dsw_error(gettext(
- "Enable failed, can't tidy up cfg"),
- &parms.status);
- }
- config_locked = 1;
- remove_iiset(setnumber, shadow_volume, 0);
- dsw_error(gettext("Enable failed"), &parms.status);
- }
-
- if (rc == -1)
- sp_info = &parms.status;
- else
- sp_info = NULL;
- spcs_log("ii", sp_info, gettext("Enabled %s %s %s (%s)"),
- master_volume, shadow_volume, bitmap_volume,
- parms.flag & DSW_GOLDEN ? "independent" : "dependent");
- spcs_s_ufree(&parms.status);
- break;
-
- default:
- exit(child_wait(child, Status, shadow_volume));
- break;
- }
-}
-
-int
-reset(char *volume)
-{
- dsw_ioctl_t args;
- dsw_config_t parms;
- int rc;
- int wait_loc;
- pid_t child = (pid_t)0;
- enum copy_wait wait_action;
- spcs_s_info_t *stat;
- dsw_stat_t prev_stat;
- int stat_flags;
- static int unlocked = 0;
- int do_enable = 0;
- char key[CFG_MAX_KEY];
- char optval[CFG_MAX_BUF];
- unsigned int flags;
-
- wait_action = WaitForStart;
-
- if (unlocked && !ii_lock(cfg, CFG_RDLOCK)) {
- dsw_error(gettext("Unable to set locking on the configuration"),
- NULL);
- }
- config_locked = 1;
- if (!find_shadow_config(volume, &parms, &args))
- dsw_error(gettext("Volume is not in a Point-in-Time Copy "
- "group"), NULL);
-
- cfg_unlock(cfg);
- config_locked = 0;
- unlocked = 1;
-
- spcs_log("ii", NULL, gettext("Start reset %s"), volume);
- (void) strlcpy(prev_stat.shadow_vol, volume, DSW_NAMELEN);
- prev_stat.status = spcs_s_ucreate();
- if (do_ioctl(dsw_fd, DSWIOC_STAT, &prev_stat) == -1) {
- /* set is suspended, so we do the enable processing instead */
- do_enable = 1;
-
- /* first check to see whether the set was offline */
- (void) snprintf(key, CFG_MAX_KEY, "ii.set%d.options",
- setnumber);
- if (!ii_lock(cfg, CFG_RDLOCK)) {
- dsw_error(gettext("Unable to set locking on the "
- "configuration"), NULL);
- }
- config_locked = 1;
- unlocked = 0;
- if (cfg_get_single_option(cfg, CFG_SEC_CONF, key,
- NSKERN_II_BMP_OPTION, optval, CFG_MAX_BUF) < 0) {
- dsw_error(gettext("unable to read config file"), NULL);
- }
- cfg_unlock(cfg);
- config_locked = 0;
- unlocked = 1;
- (void) sscanf(optval, "%x", &flags);
- if ((flags & DSW_OFFLINE) == 0) {
- /* set wasn't offline - don't reset */
- dsw_error(gettext("Set not offline, will not reset"),
- NULL);
- }
- parms.status = spcs_s_ucreate();
- stat = &parms.status;
- stat_flags = DSW_BMPOFFLINE;
- } else {
- args.status = spcs_s_ucreate();
- stat = &args.status;
- stat_flags = prev_stat.stat;
- }
- spcs_s_ufree(&prev_stat.status);
-
- if (wait_action == WaitForStart)
- (void) sigset(SIGCHLD, sigchild);
-
- switch (child = fork()) {
-
- case (pid_t)-1:
- dsw_error(gettext("Unable to fork"), NULL);
- break;
-
- case 0:
- if (do_enable) {
- rc = do_ioctl(dsw_fd, DSWIOC_ENABLE, &parms);
- } else {
- rc = do_ioctl(dsw_fd, DSWIOC_RESET, &args);
- }
- if (rc == -1 && errno != DSW_EABORTED && errno != DSW_EIO) {
- spcs_log("ii", stat, gettext("Fail reset %s"), volume);
- dsw_error(gettext("Reset shadow failed"), stat);
- }
- /* last_overflow is set during find_shadow_config */
- if (strlen(last_overflow) > 0 &&
- (stat_flags & (DSW_SHDOFFLINE | DSW_BMPOFFLINE)) != 0) {
- /* reattach it */
- (void) strncpy(parms.bitmap_vol, last_overflow,
- DSW_NAMELEN);
- do_attach(&parms);
- }
- spcs_log("ii", stat, gettext("Finish reset %s"), volume);
- spcs_s_ufree(stat);
-
- exit(0);
- break;
- default:
- if (wait_action == WaitForStart) {
- rc = child_wait(child, CopyStart, args.shadow_vol);
- } else { /* wait_action == WaitForEnd */
- wait_loc = 0;
- (void) wait(&wait_loc);
- if (WIFEXITED(wait_loc) && (WEXITSTATUS(wait_loc) == 0))
- rc = 0;
- else
- rc = -1;
- }
- break;
- }
- /* if successful, remove flags entry from options field */
- if (rc >= 0) {
- if (!ii_lock(cfg, CFG_WRLOCK)) {
- dsw_error(gettext("Unable to set locking on the "
- "configuration"), NULL);
- }
- config_locked = 1;
- if (!find_shadow_config(volume, &parms, &args)) {
- dsw_error(gettext("Volume is not in a Point-in-Time "
- "Copy group"), NULL);
- }
- (void) snprintf(key, CFG_MAX_KEY, "ii.set%d.options",
- setnumber);
- if (cfg_del_option(cfg, CFG_SEC_CONF, key, NSKERN_II_BMP_OPTION)
- < 0) {
- dsw_error(gettext("Update of config failed"), NULL);
- }
- (void) cfg_commit(cfg);
- cfg_unlock(cfg);
- config_locked = 0;
- }
-
- return (rc);
-}
-
-int
-overflow(char *volume)
-{
- dsw_ioctl_t args;
- int rc;
- spcs_s_info_t *stat;
-
- check_action(gettext("Initialize this overflow volume?"));
- if (find_matching_cf_line(volume, NULL, &args))
- dsw_error(gettext("Volume is part of a Point-in-Time Copy "
- "group"), NULL);
- args.status = spcs_s_ucreate();
- (void) strncpy(args.shadow_vol, volume, DSW_NAMELEN);
- rc = do_ioctl(dsw_fd, DSWIOC_OCREAT, &args);
- if (rc == -1) {
- spcs_log("ii", &args.status,
- gettext("Create overflow failed %s"), volume);
- dsw_error(gettext("Create overflow failed"), &args.status);
- }
- if (rc == -1)
- stat = &args.status;
- else
- stat = NULL;
- spcs_log("ii", stat, gettext("Create overflow succeeded %s"), volume);
- spcs_s_ufree(&args.status);
-
- return (0);
-}
-
-void
-bitmap_op(char *master_volume, int print_bitmap, int bitmap_percent, int used,
- int is_compact)
-{
- unsigned char *bitmap;
- char *name;
- int i, x, y;
- unsigned j;
- unsigned long n;
- unsigned long percent;
-
- bitmap = allocate_bitmap(master_volume);
- if (bitmap == NULL)
- return;
-
- if (bitmap_percent) {
- /* count the number of bits set in bitmap */
- for (i = n = 0; i < bm_size; i++)
- for (j = (unsigned)bitmap[i]; j; j &= j -1)
- n++;
- if (is_compact)
- (void) printf(gettext("Chunks in map: %d used: %d\n"),
- used, n);
- if (bm_actual < 100) {
- percent = 0;
- } else {
- percent = (n * 100) / bm_actual;
- }
- (void) printf(gettext("Percent of bitmap set: %u\n"), percent);
- percent = percent/100;
- /* distinguish between 0.0000% and 0.n% of bitmap set */
- if (percent < 1)
- (void) printf("\t(%s)\n", n > 0 ?
- gettext("bitmap dirty") : gettext("bitmap clean"));
- }
-
- if (print_bitmap) {
- name = strrchr(master_volume, '/');
- if (name++ == NULL)
- name = master_volume;
- i = bm_size * 8;
- x = (int)ceil(sqrt((double)i));
- x += (8 - (x % 8)); /* round up to nearest multiple of 8 */
- y = i / x;
- if (y * x < i)
- y++;
- (void) printf("#define bm%s_width %d\n#define bm%s_height %d\n",
- name, x, name, y);
- (void) printf("#define bm%s_x_hot 0\n#define bm%s_y_hot 0\n",
- name, name);
- (void) printf("static char bm%s_bits[] = {\n", name);
- for (i = 0; i < bm_size; i++) {
- if (i % 12 == 0)
- (void) printf("\n");
- (void) printf("0x%02x, ", bitmap[i]);
- }
- y = x * y;
- for (; i < y; i++) {
- if (i % 12 == 0)
- (void) printf("\n");
- (void) printf("0x00, ");
- }
- (void) printf("\n};\n");
- }
-
- free_bitmap(bitmap);
-}
-
-static int
-validate_group_names(char **vol_list, char *group)
-{
- ENTRY item, *found;
- int i, rc, count;
- dsw_aioctl_t *group_list;
- char *ptr;
-
- if (group == NULL || *group == NULL) {
- /* no group set, just count volume list */
- for (i = 0; *vol_list++ != NULL; i++)
- ;
- return (i);
- }
-
- if ((count = do_ioctl(dsw_fd, DSWIOC_LISTLEN, NULL)) < 0)
- dsw_error("DSWIOC_LISTLEN", NULL);
-
- group_list = malloc(sizeof (dsw_aioctl_t) + count * DSW_NAMELEN);
- if (group_list == NULL)
- dsw_error(gettext("Failed to allocate memory"), NULL);
-
- bzero(group_list, sizeof (dsw_aioctl_t) + count * DSW_NAMELEN);
- group_list->count = count;
- group_list->flags = 0;
- group_list->status = spcs_s_ucreate();
- (void) strncpy(group_list->shadow_vol, group, DSW_NAMELEN);
-
- rc = do_ioctl(dsw_fd, DSWIOC_GLIST, group_list);
- if (rc < 0)
- dsw_error(gettext("Group list access failure"),
- &group_list->status);
-
- group_list->shadow_vol[DSW_NAMELEN * group_list->count] = '\0';
-
- /* create hash and enter all volumes into it */
- if (hcreate(group_list->count) == 0)
- dsw_error(gettext("Failed to allocate memory"), NULL);
- ptr = group_list->shadow_vol;
- count = group_list->count;
- i = 0;
- while (i < count) {
- ptr[ DSW_NAMELEN - 1 ] = '\0';
- item.key = ptr;
- item.data = (void *) 0;
- (void) hsearch(item, ENTER);
- ++i;
- ptr += DSW_NAMELEN;
- }
-
- /* now compare the volume list with the hash */
- for (i = 0; vol_list[ i ]; i++) {
- item.key = vol_list[ i ];
- found = hsearch(item, FIND);
- if (!found)
- dsw_error(gettext("Group config does not match kernel"),
- NULL);
- if (found->data != (void *) 0)
- dsw_error(gettext("Duplicate volume specified"), NULL);
- found->data = (void *) 1;
- }
- if (i != count)
- dsw_error(gettext("Group config does not match kernel"), NULL);
-
- /* everything checks out */
- free(group_list);
- hdestroy();
-
- return (count);
-}
-
-int
-do_acopy(char **vol_list, enum copy_update update_mode,
- enum copy_direction direction)
-{
- dsw_aioctl_t *acopy_args;
- dsw_ioctl_t copy_args;
- dsw_config_t parms;
- dsw_stat_t stat_s;
- int i;
- int rc;
- int n_vols;
- char *t;
- char buf[1024];
- char *sp;
- char *ppid;
-
- n_vols = validate_group_names(vol_list, group_name);
-
- acopy_args = calloc(sizeof (dsw_aioctl_t) + n_vols * DSW_NAMELEN, 1);
- if (acopy_args == NULL)
- dsw_error(gettext("Too many volumes given for update"), NULL);
-
- acopy_args->count = n_vols;
-
- acopy_args->flags = 0;
-
- if (update_mode == Update)
- acopy_args->flags |= CV_BMP_ONLY;
- if (direction == ToMaster)
- acopy_args->flags |= CV_SHD2MST;
- if (pflg) {
- acopy_args->flags |= CV_LOCK_PID;
-#ifdef DEBUG
- ppid = getenv("IIADM_PPID");
- if (ppid) {
- acopy_args->pid = atoi(ppid);
- (void) fprintf(stderr, "(using %s for ppid)\n", ppid);
- } else {
- acopy_args->pid = getppid();
- }
-#else
- acopy_args->pid = getppid();
-#endif
- }
-
- for (i = 0; i < n_vols; i++) {
- if (!find_shadow_config(vol_list[i], &parms, &copy_args))
- dsw_error(gettext("Volume is not in a Point-in-Time "
- "group"), NULL);
- if (direction == ToMaster) {
- t = parms.master_vol;
- } else {
- t = parms.shadow_vol;
- }
-
- if (mounted(t)) {
- errno = EBUSY;
- dsw_error(gettext("Target of copy/update is mounted, "
- "unmount it first"), NULL);
- }
-
- (void) strlcpy(stat_s.shadow_vol, parms.shadow_vol,
- DSW_NAMELEN);
- stat_s.status = spcs_s_ucreate();
- rc = do_ioctl(dsw_fd, DSWIOC_STAT, &stat_s);
- spcs_s_ufree(&stat_s.status);
- if (rc == -1) {
- (void) sprintf(buf,
- gettext("Shadow group %s is suspended"),
- vol_list[i]);
- dsw_error(buf, NULL);
- }
-
- if (stat_s.stat & DSW_COPYINGP) {
- (void) fprintf(stderr, "%s: %s\n", cmdnam,
- gettext("Copy already in progress"));
- exit(1);
- }
- }
- acopy_args->status = spcs_s_ucreate();
- for (i = 0; i < n_vols; i++) {
- spcs_log("ii", NULL, gettext("Atomic %s %s %s"),
- update_mode == Update ? gettext("update") : gettext("copy"),
- vol_list[i],
- direction == ToMaster ? gettext("from shadow") :
- gettext("to shadow"));
- }
- if (group_name == NULL || *group_name == NULL) {
- sp = acopy_args->shadow_vol;
- for (i = 0; i < n_vols; i++, sp += DSW_NAMELEN)
- (void) strncpy(sp, vol_list[i], DSW_NAMELEN);
- } else {
- (void) strncpy(acopy_args->shadow_vol, group_name, DSW_NAMELEN);
- acopy_args->flags |= CV_IS_GROUP;
- }
- rc = do_ioctl(dsw_fd, DSWIOC_ACOPY, acopy_args);
- if (rc == -1) {
- i = acopy_args->count;
- if (i < 0 || i >= n_vols) {
- spcs_log("ii", NULL, gettext("Atomic update failed"));
- (void) sprintf(buf, gettext("Update failed"));
- } else {
- spcs_log("ii", NULL,
- gettext("Atomic update of %s failed"),
- vol_list[acopy_args->count]);
- (void) sprintf(buf, gettext("Update of %s failed"),
- vol_list[acopy_args->count]);
- }
- dsw_error(buf, &(acopy_args->status));
- }
- return (rc);
-}
-
-int
-do_copy(char **vol_list, enum copy_update update_mode,
- enum copy_direction direction, enum copy_wait wait_action)
-{
- dsw_ioctl_t copy_args;
- dsw_config_t parms;
- dsw_stat_t stat_s;
- int rc;
- int wait_loc;
- char *t;
- char *volume;
- pid_t child = (pid_t)0;
- char *ppid;
-
- if (vol_list[0] && vol_list[1])
- return (do_acopy(vol_list, update_mode, direction));
-
- volume = vol_list[0];
- if (!find_shadow_config(volume, &parms, &copy_args))
- dsw_error(gettext("Volume is not in a Point-in-Time Copy "
- "group"), NULL);
-
- cfg_unlock(cfg);
- config_locked = 0;
- copy_args.flags = 0;
-
- if (update_mode == Update)
- copy_args.flags |= CV_BMP_ONLY;
- if (direction == ToMaster) {
- copy_args.flags |= CV_SHD2MST;
- t = parms.master_vol;
- } else {
- t = parms.shadow_vol;
- }
- if (pflg) {
- copy_args.flags |= CV_LOCK_PID;
-#ifdef DEBUG
- ppid = getenv("IIADM_PPID");
- if (ppid) {
- copy_args.pid = atoi(ppid);
- (void) fprintf(stderr, "(using %s for ppid)\n", ppid);
- } else {
- copy_args.pid = getppid();
- }
-#else
- copy_args.pid = getppid();
-#endif
- }
-
- if (mounted(t)) {
- errno = EBUSY;
- dsw_error(gettext("Target of copy/update is mounted, "
- "unmount it first"), NULL);
- }
-
- (void) strlcpy(stat_s.shadow_vol, copy_args.shadow_vol, DSW_NAMELEN);
- stat_s.status = spcs_s_ucreate();
- rc = do_ioctl(dsw_fd, DSWIOC_STAT, &stat_s);
- spcs_s_ufree(&stat_s.status);
- if (rc == -1)
- dsw_error(gettext("Shadow group suspended"), NULL);
-
- if (stat_s.stat & DSW_COPYINGP) {
- (void) fprintf(stderr, "%s: %s\n", cmdnam,
- gettext("Copy already in progress"));
- exit(1);
- }
-
- copy_args.status = spcs_s_ucreate();
- spcs_log("ii", NULL, gettext("Start %s %s %s"),
- update_mode == Update ? gettext("update") : gettext("copy"),
- volume,
- direction == ToMaster ? gettext("from shadow") :
- gettext("to shadow"));
-
- if (wait_action == WaitForStart)
- (void) sigset(SIGCHLD, sigchild);
- switch (child = fork()) {
-
- case (pid_t)-1:
- dsw_error(gettext("Unable to fork"),
- NULL);
- break;
-
- case 0:
- rc = do_ioctl(dsw_fd, DSWIOC_COPY, &copy_args);
- if (rc == -1) {
- spcs_log("ii", &copy_args.status,
- gettext("Fail %s %s %s"),
- update_mode == Update ?
- gettext("update") : gettext("copy"),
- volume,
- direction == ToMaster ?
- gettext("from shadow") : gettext("to shadow"));
- dsw_error(gettext("Copy failed"), &copy_args.status);
- }
- spcs_s_ufree(&copy_args.status);
- spcs_log("ii", NULL, gettext("Finish %s %s %s"),
- update_mode == Update ? gettext("update") : gettext("copy"),
- volume,
- direction == ToMaster ? gettext("from shadow") :
- gettext("to shadow"));
-
- exit(0);
- break;
- default:
- if (wait_action == WaitForStart) {
- rc = child_wait(child, CopyStart, copy_args.shadow_vol);
- } else { /* wait_action == WaitForEnd */
- wait_loc = 0;
- (void) wait(&wait_loc);
- if (WIFEXITED(wait_loc) && (WEXITSTATUS(wait_loc) == 0))
- rc = 0;
- else
- rc = 1;
- }
- break;
- }
- return (rc);
-}
-
-void
-print_status(dsw_config_t *conf, int in_config)
-{
- dsw_stat_t args;
- int stat_flags;
- static int need_sep = 0;
- time_t tmp_time;
-
- if (need_sep++ > 0)
- (void) printf("--------------------------------------"
- "----------------------------------------\n");
- (void) strlcpy(args.shadow_vol, conf->shadow_vol, DSW_NAMELEN);
- if (in_config) {
- (void) printf("%s: %s\n",
- conf->master_vol, gettext("(master volume)"));
- (void) printf("%s: %s\n",
- conf->shadow_vol, gettext("(shadow volume)"));
- (void) printf("%s: %s\n",
- conf->bitmap_vol, gettext("(bitmap volume)"));
- }
-
- /*
- * Do special checking on the status of this volume in a Sun Cluster
- */
- if (check_cluster() == II_CLUSTER) {
- char dgname[CFG_MAX_BUF], *other_node;
-
- if (cfg_dgname(conf->bitmap_vol, dgname, sizeof (dgname))) {
- if (strlen(dgname)) {
- int rc = cfg_dgname_islocal(dgname,
- &other_node);
-
- if (rc < 0) {
- (void) printf(gettext(
- "Suspended on this node, "
- "not active elsewhere\n"));
- return;
- } else if (rc == 0) {
- (void) printf(gettext(
- "Suspended on this node, "
- "active on %s\n"), other_node);
- return;
- }
- }
- }
- }
-
- args.status = spcs_s_ucreate();
- if (do_ioctl(dsw_fd, DSWIOC_STAT, &args) == -1) {
-
- /* Handle Not found or not in config */
- if (errno != DSW_ENOTFOUND || !in_config)
- dsw_error(gettext("Stat failed"), &args.status);
-
- /* Just suspend */
- (void) printf(gettext("Suspended.\n"));
- return;
- }
-
- if (args.overflow_vol[0] != '\0')
- (void) printf("%s: %s\n", args.overflow_vol,
- gettext("(overflow volume)"));
-
- if (conf->group_name[0] != '\0')
- (void) printf(gettext("Group name: %s\n"),
- conf->group_name);
-
- if (conf->cluster_tag[0] != '\0')
- (void) printf(gettext("Cluster tag: %s\n"),
- conf->cluster_tag);
-
- stat_flags = args.stat;
- spcs_s_ufree(&args.status);
- if (stat_flags & DSW_GOLDEN)
- (void) printf(gettext("Independent copy"));
- else
- (void) printf(gettext("Dependent copy"));
-
- if (stat_flags & DSW_TREEMAP)
- (void) printf(gettext(", compacted shadow space"));
-
- if (stat_flags & DSW_COPYINGP)
- (void) printf(gettext(", copy in progress"));
- else if (stat_flags & DSW_COPYING)
- (void) printf(gettext(", copy not active"));
-
- if (stat_flags & DSW_COPYINGM)
- (void) printf(gettext(", copying master to shadow"));
-
- if (stat_flags & DSW_COPYINGS)
- (void) printf(gettext(", copying shadow to master"));
-
- if (stat_flags & DSW_COPYINGX)
- (void) printf(gettext(", abort of copy requested"));
-
- if (stat_flags & DSW_MSTOFFLINE)
- (void) printf(gettext(", master volume offline"));
-
- if (stat_flags & DSW_SHDOFFLINE)
- (void) printf(gettext(", shadow volume offline"));
-
- if (stat_flags & DSW_BMPOFFLINE)
- (void) printf(gettext(", bitmap volume offline"));
-
- if (stat_flags & DSW_OVROFFLINE)
- (void) printf(gettext(", overflow volume offline"));
-
- if (stat_flags & DSW_SHDEXPORT)
- (void) printf(gettext(", shadow volume exported"));
-
- if (stat_flags & DSW_SHDIMPORT)
- (void) printf(gettext(", shadow volume imported"));
-
- if (stat_flags & DSW_OVERFLOW)
- (void) printf(gettext(", out of space"));
-
- if (stat_flags & DSW_VOVERFLOW)
- (void) printf(gettext(", spilled into overflow volume"));
- (void) printf("\n");
-
- tmp_time = args.mtime;
- if (tmp_time != 0)
- (void) printf("%s %s", gettext("Latest modified time:"),
- ctime(&tmp_time));
- else
- (void) printf("%s\n", gettext("Latest modified time: unknown"));
-
- (void) printf("%s %8llu\n", gettext("Volume size:"), args.size);
- if (args.shdsize != 0) {
- (void) printf("%s %lld %s %lld\n",
- gettext("Shadow chunks total:"), args.shdsize,
- gettext("Shadow chunks used:"), args.shdused);
- }
- bitmap_op(args.shadow_vol, 0, 1, 0, 0);
-}
-
-int
-abort_copy(char *volume)
-{
- dsw_ioctl_t args;
-
- if (!find_shadow_config(volume, NULL, &args))
- dsw_error(gettext("Volume is not in a Point-in-Time Copy "
- "group"), NULL);
- args.status = spcs_s_ucreate();
- if (do_ioctl(dsw_fd, DSWIOC_ABORT, &args) == -1)
- dsw_error(gettext("Abort failed"), &args.status);
- spcs_log("ii", NULL, gettext("Abort %s"), args.shadow_vol);
- spcs_s_ufree(&args.status);
- return (0);
-}
-
-void
-iiversion()
-{
- dsw_version_t args;
-
- args.status = spcs_s_ucreate();
- if (do_ioctl(dsw_fd, DSWIOC_VERSION, &args) == -1)
- dsw_error(gettext("Version failed"), &args.status);
- spcs_s_ufree(&args.status);
-#ifdef DEBUG
- (void) printf(gettext("Point in Time Copy version %d.%d.%d.%d\n"),
- args.major, args.minor, args.micro, args.baseline);
-#else
- if (args.micro) {
- (void) printf(gettext("Point in Time Copy version %d.%d.%d\n"),
- args.major, args.minor, args.micro);
- } else {
- (void) printf(gettext("Point in Time Copy version %d.%d\n"),
- args.major, args.minor);
- }
-#endif
-}
-
-void
-list_volumes()
-{
- dsw_list_t args;
- int i, set, found;
- dsw_config_t *lp;
- ENTRY item, *ip;
- dsw_config_t parms;
-
- if ((i = do_ioctl(dsw_fd, DSWIOC_LISTLEN, &args)) == -1)
- dsw_error("DSWIOC_LISTLEN", NULL);
-
- args.status = spcs_s_ucreate();
- args.list_used = 0;
- args.list_size = i + 4;
- lp = args.list = (dsw_config_t *)
- malloc(args.list_size * sizeof (dsw_config_t));
-
- if (args.list == NULL)
- dsw_error(gettext("Failed to allocate memory"), NULL);
- if (do_ioctl(dsw_fd, DSWIOC_LIST, &args) == -1)
- dsw_error(gettext("List failed"), &args.status);
- spcs_s_ufree(&args.status);
-
- /* make a hashtable */
- if (args.list_used > 0) {
- if (hcreate(args.list_used) == 0) {
- dsw_error(gettext("Failed to allocate memory"), NULL);
- /*NOTREACHED*/
- }
- }
-
- /* populate the hashtable */
- for (i = 0; i < args.list_used; i++, lp++) {
- item.key = lp->shadow_vol;
- item.data = (char *)lp;
- if (hsearch(item, ENTER) == NULL) {
- dsw_error(gettext("Failed to allocate memory"), NULL);
- /*NOTREACHED*/
- }
- }
-
- /* perform action for each line of the stored config file */
- for (set = 1; get_dsw_config(set, &parms) == 0; set++) {
-
- /* Are there any II sets configured on this node? */
- if (args.list_used > 0) {
- item.key = parms.shadow_vol;
-
- /* Is this volume configured on this node? */
- if (ip = hsearch(item, FIND)) {
-
- /* Handle Imported Shadows */
- /* LINTED alignment of cast ok */
- lp = (dsw_config_t *)ip->data;
- if (strcmp(parms.master_vol,
- II_IMPORTED_SHADOW))
- found = !(lp->flag & DSW_SHDIMPORT);
- else
- found = (lp->flag & DSW_SHDIMPORT);
- }
- else
- found = FALSE;
- }
- else
- found = FALSE;
-
- if ((cfg_cluster_tag) &&
- strcmp(cfg_cluster_tag, parms.cluster_tag))
- continue;
-
- if ((group_name) && strcmp(group_name, parms.group_name))
- continue;
-
- (void) printf("%s %.*s %.*s %.*s%s\n",
- (parms.flag & DSW_GOLDEN) ? "ind" : "dep",
- DSW_NAMELEN, parms.master_vol,
- DSW_NAMELEN, parms.shadow_vol,
- DSW_NAMELEN, parms.bitmap_vol,
- found ? "" : gettext(" (suspended)"));
- }
- hdestroy();
- free(args.list);
-}
-
-int
-wait_for_copy(char *volume)
-{
- dsw_ioctl_t parms;
- int rc;
- static int unlocked = 0;
- char *ppid;
-
- if (unlocked && !ii_lock(cfg, CFG_RDLOCK)) {
- dsw_error(gettext("Unable to set locking on the configuration"),
- NULL);
- }
- config_locked = 1;
- if (!find_shadow_config(volume, NULL, &parms))
- dsw_error(gettext("Volume is not in a Point-in-Time Copy "
- "group"), NULL);
- cfg_unlock(cfg);
- config_locked = 0;
- unlocked = 1;
-
- parms.status = spcs_s_ucreate();
- if (pflg) {
-#ifdef DEBUG
- ppid = getenv("IIADM_PPID");
- if (ppid) {
- parms.pid = atoi(ppid);
- (void) fprintf(stderr, "(using %s for ppid)\n", ppid);
- } else {
- parms.pid = (nflg) ? -1 : getppid();
- }
-#else
- parms.pid = (nflg) ? -1 : getppid();
-#endif
- parms.flags |= CV_LOCK_PID;
- }
-
- rc = do_ioctl(dsw_fd, DSWIOC_WAIT, &parms);
- if (rc == -1)
- dsw_error(gettext("Wait failed"), &parms.status);
- spcs_s_ufree(&parms.status);
- return (0);
-}
-
-int
-export(char *volume)
-{
- dsw_ioctl_t parms;
- dsw_config_t conf;
- char *old_ctag, dgname[DSW_NAMELEN];
- int rc;
-
- if (!find_shadow_config(volume, &conf, &parms))
- dsw_error(gettext("Volume is not in a Point-in-Time Copy "
- "group"), NULL);
- if (mounted(volume))
- dsw_error(gettext("Can't export a mounted volume"), NULL);
-
- /* If this is an exportable shadow in the cluster, change ctag */
- if (strlen(conf.cluster_tag) &&
- (cfg_dgname(volume, dgname, sizeof (dgname)))) {
- old_ctag = cfg_cluster_tag;
- cfg_resource(cfg, cfg_cluster_tag = strdup(dgname));
- } else old_ctag = NULL;
-
- if (cfg_load_dsvols(cfg) < 0 || cfg_load_shadows(cfg) < 0) {
- dsw_error(gettext("Unable to parse config file"), NULL);
- }
- reload_vols = LD_DSVOLS | LD_SHADOWS;
- conform_name(&volume);
-
- spcs_log("ii", NULL, gettext("Export %s"), volume);
- parms.status = spcs_s_ucreate();
- rc = do_ioctl(dsw_fd, DSWIOC_EXPORT, &parms);
- if (rc == -1)
- dsw_error(gettext("Export failed"), &parms.status);
- if (perform_autosv()) {
- if (cfg_vol_disable(cfg, volume, cfg_cluster_tag, "ii") < 0) {
- dsw_error(gettext("SV-disable failed"), NULL);
- }
- (void) cfg_commit(cfg);
- }
-
- /* restore old cluster tag, if changed */
- if (old_ctag != NULL)
- cfg_resource(cfg, cfg_cluster_tag = old_ctag);
-
- spcs_s_ufree(&parms.status);
- return (0);
-}
-
-int
-detach(char *volume)
-{
- dsw_ioctl_t parms;
- int rc;
-
- if (!find_shadow_config(volume, NULL, &parms))
- dsw_error(gettext("Volume is not in a Point-in-Time Copy "
- "group"), NULL);
- parms.status = spcs_s_ucreate();
- rc = do_ioctl(dsw_fd, DSWIOC_ODETACH, &parms);
- if (rc == 0) {
- /* remove overflow from cfg line */
- (void) sprintf(key, "ii.set%d.overflow", setnumber);
- if (cfg_put_cstring(cfg, key, "-", 1) < 0) {
- perror("cfg_put_cstring");
- }
- (void) cfg_commit(cfg);
- } else {
- spcs_log("ii", NULL, gettext("Detach of overflow %s failed"),
- parms.shadow_vol);
- dsw_error(gettext("Failed to detach overflow volume"),
- &parms.status);
- }
- return (rc);
-}
-
-static void
-can_disable(char *vol)
-{
- dsw_stat_t args;
-
- if (mounted(vol)) {
- (void) strlcpy(args.shadow_vol, vol, DSW_NAMELEN);
- args.status = spcs_s_ucreate();
- if (do_ioctl(dsw_fd, DSWIOC_STAT, &args) != -1 &&
- (args.stat & DSW_GOLDEN) == 0) {
- errno = EBUSY;
- dsw_error(gettext("Shadow Volume is currently mounted "
- "and dependent on the master volume"), NULL);
- }
- spcs_s_ufree(&args.status);
- }
-}
-
-static void
-clean_up_after_failed_disable(dsw_ioctl_t *parms)
-{
- char **p;
- dsw_stat_t args;
-
- for (p = group_volumes; *p; p++) {
- (void) strlcpy(args.shadow_vol, *p, DSW_NAMELEN);
- args.status = spcs_s_ucreate();
- if (do_ioctl(dsw_fd, DSWIOC_STAT, &args) == -1) {
- /* set was successfully disabled */
- if (find_shadow_config(*p, NULL, NULL))
- remove_iiset(setnumber, *p, 0);
- }
- spcs_s_ufree(&args.status);
- }
-
- dsw_error(gettext("Some sets in the group failed to disable"),
- &parms->status);
-}
-
-int
-dsw_group_or_single_disable(int argc, char *argv[])
-{
- int rc = 0;
- char **p;
- dsw_ioctl_t parms;
- int flags = 0;
- dsw_config_t conf;
- int shd_exported = 0;
-
- if (argc != 2)
- usage(gettext("Incorrect number of arguments"));
-
- if (group_name) {
- if (find_group_members(group_name) < 1)
- dsw_error(gettext("Group does not exist or "
- "has no members"), NULL);
- for (p = group_volumes; *p; p++) {
- can_disable(*p);
- }
-
- (void) strncpy(parms.shadow_vol, group_name, DSW_NAMELEN);
- if (*group_name)
- flags = CV_IS_GROUP;
- } else {
- if (!find_shadow_config(argv[1], &conf, &parms)) {
- dsw_error(gettext("Volume is not in a Point-in-Time "
- "Copy group"), NULL);
- }
-
- can_disable(argv[1]);
- flags = 0;
- }
-
- if (group_name && !*group_name) {
- /* user typed iiadm -g "" -d */
- for (p = group_volumes; *p; p++) {
- parms.status = spcs_s_ucreate();
- parms.flags = flags;
- (void) strncpy(parms.shadow_vol, *p, DSW_NAMELEN);
- rc = do_ioctl(dsw_fd, DSWIOC_DISABLE, &parms);
- if (rc == -1 && errno != DSW_ENOTFOUND)
- dsw_error(gettext("Disable failed"),
- &parms.status);
- if (!find_shadow_config(*p, NULL, NULL))
- dsw_error(gettext("Volume is not in a Point-in"
- "-Time Copy group"), &parms.status);
- remove_iiset(setnumber, *p, 0);
- spcs_s_ufree(&parms.status);
- spcs_log("ii", NULL, gettext("Disabled %s"),
- parms.shadow_vol);
- }
- } else {
- if (is_exported(conf.shadow_vol)) {
- shd_exported = 1;
- }
- if ((strcmp(conf.master_vol, II_IMPORTED_SHADOW) == 0) &&
- is_exported(conf.shadow_vol)) {
- dsw_error(gettext(
- "Imported shadow not disabled"), NULL);
- }
-
- parms.status = spcs_s_ucreate();
- parms.flags = flags;
- rc = do_ioctl(dsw_fd, DSWIOC_DISABLE, &parms);
- if (rc == -1 && errno != DSW_ENOTFOUND) {
- if (errno == DSW_EDISABLE) {
- /*
- * one or more sets within the group
- * couldn't disable
- */
- clean_up_after_failed_disable(&parms);
- } else {
- dsw_error(gettext("Disable failed"),
- &parms.status);
- }
- }
- spcs_log("ii", NULL, gettext("Disabled %s"), parms.shadow_vol);
- }
-
-
- if (group_name && *group_name) {
- for (p = group_volumes; *p; p++) {
- if (!find_shadow_config(*p, NULL, NULL)) {
- /* argh! */
- (void) fprintf(stderr,
- gettext("Volume '%s' is not "
- "in a Point-in-Time Copy group"), *p);
- } else {
- remove_iiset(setnumber, *p, 0);
- }
- }
- } else if (!group_name) {
- if (!find_shadow_config(argv[1], NULL, NULL)) {
- /* argh! */
- dsw_error(gettext("Volume is not in a Point-in-Time "
- "Copy group"), NULL);
- }
-
- remove_iiset(setnumber, argv[1], shd_exported);
- }
-
- return (0);
-}
-
-int
-dsw_group_or_single_op(int argc, char *argv[], int (*op)(char *))
-{
- int rc = 0;
-
- if (argc != 2)
- usage(gettext("Incorrect number of arguments"));
-
- if (group_name) {
- if (find_group_members(group_name) < 1)
- dsw_error(gettext("Group does not exist or "
- "has no members"), NULL);
- for (; *group_volumes; group_volumes++)
- rc |= (*op)(*group_volumes);
- } else {
- rc = (*op)(argv[1]);
- }
- return (rc);
-}
-
-void
-dsw_list_clusters(char *cluster)
-{
- dsw_aioctl_t *acopy_args;
- int rc, i, count;
- char *ptr;
-
- if ((count = do_ioctl(dsw_fd, DSWIOC_LISTLEN, NULL)) < 0)
- dsw_error("DSWIOC_LISTLEN", NULL);
-
- acopy_args = malloc(sizeof (dsw_aioctl_t) + count * DSW_NAMELEN);
- if (acopy_args == NULL)
- dsw_error(gettext("Can't get memory for list enquiry"), NULL);
-
- bzero(acopy_args, sizeof (dsw_aioctl_t) + count * DSW_NAMELEN);
- acopy_args->count = count;
- acopy_args->flags = 0;
- acopy_args->status = spcs_s_ucreate();
- if (cluster)
- (void) strncpy(acopy_args->shadow_vol, cluster, DSW_NAMELEN);
-
- rc = do_ioctl(dsw_fd, DSWIOC_CLIST, acopy_args);
- if (rc == -1)
- dsw_error(gettext("Cluster list access failure"),
- &acopy_args->status);
-
- acopy_args->shadow_vol[DSW_NAMELEN*acopy_args->count] = NULL;
-
- if (cluster) {
- (void) printf(gettext("Sets in cluster resource group %s:\n"),
- cluster);
- } else {
- (void) printf(
- gettext("Currently configured resource groups\n"));
- }
- for (i = 0, ptr = acopy_args->shadow_vol; *ptr &&
- i < acopy_args->count; i++, ptr += DSW_NAMELEN) {
- (void) printf(" %-64.64s\n", ptr);
- }
-}
-
-void
-dsw_enable(int argc, char *argv[])
-{
- if (argc != 5)
- usage(gettext("Incorrect number of arguments"));
-
- enable(argv[1], argv[2], argv[3], argv[4]);
- exit(0);
-}
-
-
-void
-dsw_disable(int argc, char *argv[])
-{
- (void) dsw_group_or_single_disable(argc, argv);
- exit(0);
-}
-
-
-void
-dsw_copy_to_shadow(int argc, char *argv[])
-{
- char **volume_list;
-
- if (argc != 2)
- usage(gettext("Incorrect number of arguments"));
- if (group_name == NULL)
- volume_list = ++argv;
- else {
- if (find_group_members(group_name) < 1)
- dsw_error(gettext("Group does not exist or "
- "has no members"), NULL);
- volume_list = group_volumes;
- }
-
- exit(do_copy(volume_list, Copy, ToShadow, WaitForStart));
-}
-
-
-void
-dsw_update_shadow(int argc, char *argv[])
-{
- char **volume_list;
-
- if (argc != 2)
- usage(gettext("Incorrect number of arguments"));
- if (group_name == NULL)
- volume_list = ++argv;
- else {
- if (find_group_members(group_name) < 1)
- dsw_error(gettext("Group does not exist or "
- "has no members"), NULL);
- volume_list = group_volumes;
- }
-
- exit(do_copy(volume_list, Update, ToShadow, WaitForStart));
-}
-
-
-void
-dsw_copy_to_master(int argc, char *argv[])
-{
- char **volume_list;
-
- if (argc != 2)
- usage(gettext("Incorrect number of arguments"));
- if (group_name == NULL) {
- volume_list = ++argv;
- check_action(gettext("Overwrite master with shadow volume?"));
- } else {
- check_action(gettext("Overwrite every"
- " master in this group with its shadow volume?"));
- if (find_group_members(group_name) < 1)
- dsw_error(gettext("Group does not exist or "
- "has no members"), NULL);
- volume_list = group_volumes;
- }
-
- exit(do_copy(volume_list, Copy, ToMaster, WaitForStart));
-}
-
-
-void
-dsw_update_master(int argc, char *argv[])
-{
- char **volume_list;
-
- if (argc != 2)
- usage(gettext("Incorrect number of arguments"));
- if (group_name == NULL) {
- volume_list = ++argv;
- check_action(gettext("Overwrite master with shadow volume?"));
- } else {
- check_action(gettext("Overwrite every"
- " master in this group with its shadow volume?"));
- if (find_group_members(group_name) < 1)
- dsw_error(gettext("Group does not exist or "
- "has no members"), NULL);
- volume_list = group_volumes;
- }
-
- exit(do_copy(volume_list, Update, ToMaster, WaitForStart));
-}
-
-
-void
-dsw_abort_copy(int argc, char *argv[])
-{
- exit(dsw_group_or_single_op(argc, argv, abort_copy));
-}
-
-
-void
-dsw_display_status(int argc, char *argv[])
-{
- dsw_config_t parms;
- int in_config;
-
- if (argc != 2 && argc != 1)
- usage(gettext("Incorrect number of arguments"));
-
- /* "iiadm -i" and "iiadm -i all" are equivalent */
- if (argc == 2 && strcmp("all", argv[1]) != 0) {
- in_config = find_shadow_config(argv[1], &parms, NULL);
- if (!in_config) {
- (void) printf(gettext(
- "Volume is not in configuration file\n"), NULL);
- (void) fflush(stdout);
- (void) strlcpy(parms.shadow_vol, argv[1], DSW_NAMELEN);
- }
- print_status(&parms, in_config);
- } else if (group_name) {
- if (find_group_members(group_name) < 1)
- dsw_error(gettext("Group does not exist or "
- "has no members"), NULL);
- for (; *group_volumes; group_volumes++) {
- in_config = find_shadow_config(*group_volumes,
- &parms, NULL);
- if (in_config)
- print_status(&parms, in_config);
- }
- } else {
- /* perform action for each line of the stored config file */
- for (setnumber = 1;
- !get_dsw_config(setnumber, &parms); setnumber++) {
- switch (check_cluster()) {
- case II_CLUSTER:
- if ((cfg_cluster_tag) &&
- (strcmp(cfg_cluster_tag,
- parms.cluster_tag)))
- continue;
- break;
- case II_CLUSTER_LCL:
- if (strlen(parms.cluster_tag))
- continue;
- break;
- }
- print_status(&parms, 1);
- }
- }
- exit(0);
-}
-
-void
-dsw_display_bitmap(int argc, char *argv[])
-{
- dsw_config_t parms;
- int in_config;
-
- if (argc != 2)
- usage(gettext("Incorrect number of arguments"));
-
- in_config = find_shadow_config(argv[1], &parms, NULL);
- if (!in_config) {
- (void) printf(gettext(
- "Volume is not in configuration file\n"), NULL);
- (void) fflush(stdout);
- (void) strlcpy(parms.master_vol, argv[1], DSW_NAMELEN);
- }
-
- bitmap_op(parms.shadow_vol, 1, 0, 0, 0);
- exit(0);
-}
-
-
-/*ARGSUSED*/
-void
-dsw_version(int argc, char *argv[])
-{
- iiversion();
- exit(0);
-}
-
-void
-dsw_reset(int argc, char *argv[])
-{
- exit(dsw_group_or_single_op(argc, argv, reset));
-}
-
-void
-dsw_overflow(int argc, char *argv[])
-{
- if (argc != 2)
- usage(gettext("Incorrect number of arguments"));
-
- exit(overflow(argv[1]));
-}
-
-void
-dsw_wait(int argc, char *argv[])
-{
- exit(dsw_group_or_single_op(argc, argv, wait_for_copy));
-}
-
-/*ARGSUSED*/
-void
-dsw_list_volumes(int argc, char *argv[])
-{
- if (argc != 1)
- usage(gettext("Incorrect number of arguments"));
-
- list_volumes();
- exit(0);
-}
-
-void
-dsw_export(int argc, char *argv[])
-{
- if (argc != 2)
- usage(gettext("Incorrect number of arguments"));
-
- exit(dsw_group_or_single_op(argc, argv, export));
-}
-
-void
-dsw_detach(int argc, char *argv[])
-{
- (void) dsw_group_or_single_op(argc, argv, detach);
- exit(0);
-}
-
-void
-import(char *shadow_volume, char *bitmap_volume)
-{
- dsw_config_t parms = {0};
- int rc = 0;
- char shd_dg[DSW_NAMELEN];
- char bmp_dg[DSW_NAMELEN];
-
- /*
- * If importing a shadow volume and the shadow volume is already
- * configured, we only support this if we are in a Sun Cluster
- * and the current user specified a cluster tag of -C local
- */
- if (find_shadow_config(shadow_volume, &parms, NULL)) {
- dsw_error(gettext("Can't import volume on same node"), NULL);
- }
-
- switch (check_cluster()) {
- case II_CLUSTER:
- case II_CLUSTER_LCL:
- (void) check_resource_group(shadow_volume);
- if (cfg_cluster_tag) { /* check all volumes are in same dg */
- if (cfg_dgname(shadow_volume, shd_dg, DSW_NAMELEN)
- == NULL)
- dsw_error(gettext("Shadow volume not in a"
- " disk group"), NULL);
- if (cfg_dgname(bitmap_volume, bmp_dg, DSW_NAMELEN)
- == NULL)
- dsw_error(gettext("Bitmap volume not in a"
- " disk group"), NULL);
- if (strcmp(bmp_dg, shd_dg) != 0)
- dsw_error(gettext("Bitmap volume not in"
- " same disk group as shadow set members"),
- NULL);
- }
- break;
- case II_NOT_CLUSTER:
- /* do nothing */
- break;
- default:
- dsw_error(gettext(
- "Unexpected return from check_cluster()"), NULL);
- }
-
- /* Local configuration volumes */
- if (cfg_load_dsvols(cfg) < 0 || cfg_load_shadows(cfg) < 0) {
- dsw_error(gettext("Unable to parse config file"), NULL);
- }
-
- reload_vols = LD_DSVOLS | LD_SHADOWS;
- conform_name(&shadow_volume);
- (void) strcpy(parms.master_vol, II_IMPORTED_SHADOW);
- (void) strlcpy(parms.shadow_vol, shadow_volume, DSW_NAMELEN);
- (void) strlcpy(parms.bitmap_vol, bitmap_volume, DSW_NAMELEN);
- parms.flag = DSW_GOLDEN;
-
- spcs_log("ii", NULL, gettext("Import %s %s"),
- parms.shadow_vol, parms.bitmap_vol);
- parms.status = spcs_s_ucreate();
- rc = do_ioctl(dsw_fd, DSWIOC_IMPORT, &parms);
- if (rc == -1) {
- spcs_log("ii", NULL, gettext("Import failed %s %s"),
- parms.shadow_vol, parms.bitmap_vol);
- dsw_error(gettext("Import failed"), &parms.status);
- }
- if (perform_autosv()) {
- if (cfg_vol_enable(cfg, shadow_volume, cfg_cluster_tag, "ii")
- < 0) {
- dsw_error(gettext("SV-enable failed"), NULL);
- }
- /* cfg_commit is called by add_cfg_entry below */
- }
- spcs_s_ufree(&parms.status);
- add_cfg_entry(&parms);
-}
-
-void
-dsw_import(int argc, char *argv[])
-{
- if (argc != 3)
- usage(gettext("Incorrect number of arguments"));
- import(argv[1], argv[2]);
-
- exit(0);
-}
-
-void
-join(char *shadow_volume, char *bitmap_file)
-{
- dsw_ioctl_t shd;
- dsw_config_t conf;
- dsw_bitmap_t parms;
- int rc = 0;
- int size;
- FILE *bmpfp;
- uchar_t *shd_bitmap = 0;
- ii_header_t header;
- char dgname[DSW_NAMELEN];
-
- if (!find_shadow_config(shadow_volume, &conf, &shd))
- dsw_error(gettext("Volume is not in a Point-in-Time Copy "
- "group"), NULL);
-
- /* If this is an exportable shadow in the cluster, change ctag */
- if (strlen(conf.cluster_tag) &&
- (cfg_dgname(shadow_volume, dgname, sizeof (dgname))))
- cfg_resource(cfg, cfg_cluster_tag = strdup(dgname));
-
- if (cfg_load_dsvols(cfg) < 0 || cfg_load_shadows(cfg) < 0) {
- dsw_error(gettext("Unable to parse config file"), NULL);
- }
- reload_vols = LD_DSVOLS | LD_SHADOWS;
- conform_name(&shadow_volume);
-
- if ((bmpfp = fopen(bitmap_file, "r")) == NULL) {
- perror(bitmap_file);
- (void) fprintf(stderr,
- gettext("Can't open imported bitmap volume\n"));
- exit(1);
- }
-
- if (fread(&header, sizeof (header), 1, bmpfp) != 1) {
- (void) fprintf(stderr,
- gettext("Can't read imported bitmap volume\n"));
- exit(1);
- }
-
- /* See if this is a bitmap header */
- switch (header.ii_magic) {
- case DSW_DIRTY: /* A copy of a enable bitmap volume */
- case DSW_CLEAN:
- check_action(gettext("Use the never imported bitmap?"));
- break;
- case DSW_INVALID: /* A valid diskable secondary bitmap */
- break;
- default:
- (void) fprintf(stderr,
- gettext("Secondary bitmap is not a valid bitmap volume\n"));
- exit(1);
- }
-
- size = FBA_SIZE(header.ii_copyfba - header.ii_shdfba);
- if ((shd_bitmap = malloc(size)) == NULL) {
- perror("malloc");
- exit(1);
- }
-
- if (fseek(bmpfp, FBA_SIZE(header.ii_shdfba), SEEK_SET)) {
- perror("fseek");
- exit(1);
- }
-
- if (fread(shd_bitmap, 1, size, bmpfp) != size) {
- (void) fprintf(stderr,
- gettext("Can't read imported bitmap volume\n"));
- exit(1);
- }
-
- (void) fclose(bmpfp);
-
- (void) strlcpy(parms.shadow_vol, shadow_volume, DSW_NAMELEN);
- parms.shd_bitmap = shd_bitmap;
- parms.shd_size = size;
- parms.copy_bitmap = NULL;
- parms.copy_size = 0;
-
- spcs_log("ii", NULL, gettext("Join %s %s"),
- parms.shadow_vol, bitmap_file);
- parms.status = spcs_s_ucreate();
- rc = do_ioctl(dsw_fd, DSWIOC_JOIN, &parms);
- if (rc == -1) {
- spcs_log("ii", NULL, gettext("Join failed %s %s"),
- parms.shadow_vol, bitmap_file);
- dsw_error(gettext("Join failed"), &parms.status);
- }
- if (perform_autosv()) {
- rc = cfg_vol_enable(cfg, shadow_volume, cfg_cluster_tag, "ii");
- if (rc < 0) {
- dsw_error(gettext("SV-enable failed"), NULL);
- }
- (void) cfg_commit(cfg);
- }
- spcs_s_ufree(&parms.status);
-}
-
-int
-params(char *shadow_volume)
-{
- char *delay = param_delay;
- char *unit = param_unit;
- dsw_copyp_t parms;
- int rc = 0;
- int get = 0;
- int new_delay;
- int new_unit;
-
- (void) strlcpy(parms.shadow_vol, shadow_volume, DSW_NAMELEN);
- if (delay == NULL || unit == NULL) {
- get = 1;
- parms.copy_delay = -1;
- parms.copy_unit = -1;
- } else {
- new_delay = parms.copy_delay = convert_int(delay);
- new_unit = parms.copy_unit = convert_int(unit);
- }
-
- parms.status = spcs_s_ucreate();
- rc = do_ioctl(dsw_fd, DSWIOC_COPYP, &parms);
- if (rc == -1) {
- (void) fprintf(stderr,
- gettext("Parameter ranges are delay(%d - %d), "
- "units(%d - %d)\n"), MIN_THROTTLE_DELAY, MAX_THROTTLE_DELAY,
- MIN_THROTTLE_UNIT, MAX_THROTTLE_UNIT);
- dsw_error(gettext("Set Copy Parameters failed"), &parms.status);
- }
- if (!get)
- spcs_log("ii", NULL, gettext("Changed copy parameters %s from "
- "%d %d to %d %d"), parms.shadow_vol, parms.copy_delay,
- parms.copy_unit, new_delay, new_unit);
- else
- (void) printf(gettext("volume: %s\ncopy delay: %d\ncopy unit:"
- " %d\n"), parms.shadow_vol, parms.copy_delay,
- parms.copy_unit);
- spcs_s_ufree(&parms.status);
- return (0);
-}
-
-static void
-do_attach(dsw_config_t *parms)
-{
- dsw_config_t io;
- int rc;
- int check = 0;
-
- spcs_log("ii", NULL, gettext("Attach %s %s"),
- parms->shadow_vol, parms->bitmap_vol);
- parms->status = spcs_s_ucreate();
- rc = do_ioctl(dsw_fd, DSWIOC_OATTACH, parms);
- if (rc == -1) {
- check = 1;
- /* if overflow() fails, it calls dsw_error to exit */
- (void) overflow(parms->bitmap_vol);
- }
- spcs_s_ufree(&parms->status);
- if (check == 1) {
- if (!find_shadow_config(parms->shadow_vol, &io, NULL))
- dsw_error(
- gettext("Volume is not in a Point-in-Time Copy "
- "group"), NULL);
- (void) strlcpy(io.bitmap_vol, parms->bitmap_vol, DSW_NAMELEN);
- io.status = spcs_s_ucreate();
- if (do_ioctl(dsw_fd, DSWIOC_OATTACH, &io) == -1) {
- spcs_log("ii", NULL, gettext("Attach failed %s %s"),
- io.shadow_vol, parms->bitmap_vol);
- dsw_error(gettext("Attach failed"), &io.status);
- }
- spcs_s_ufree(&io.status);
- }
-}
-
-int
-attach(char *shadow_volume)
-{
- dsw_config_t parms;
- dsw_stat_t args;
- char shd_dg[DSW_NAMELEN];
- char ovr_dg[DSW_NAMELEN];
-
- switch (check_cluster()) {
- case II_CLUSTER:
- case II_CLUSTER_LCL:
- (void) check_resource_group(shadow_volume);
- if (cfg_cluster_tag) { /* check all volumes are in same dg */
- if (cfg_dgname(shadow_volume, shd_dg, DSW_NAMELEN)
- == NULL)
- dsw_error(gettext("Shadow volume not in a"
- " disk group"), NULL);
- if (cfg_dgname(overflow_file, ovr_dg, DSW_NAMELEN)
- == NULL)
- dsw_error(gettext("Overflow volume not in a"
- " disk group"), NULL);
- if (strcmp(ovr_dg, shd_dg) != 0)
- dsw_error(gettext("Overflow volume not in"
- " same disk group as shadow set members"),
- NULL);
- }
- break;
- case II_NOT_CLUSTER:
- /* do nothing */
- break;
- default:
- dsw_error(gettext(
- "Unexpected return from check_cluster()"), NULL);
- }
-
- /* assure that the overflow_file is not an II volume */
- if (find_any_cf_line(overflow_file))
- dsw_error(gettext(
- "Overflow volume is already in a Point-in-Time Copy "
- "group"), NULL);
-
- /* use find_shadow_config() to find setnumber */
- if (!find_shadow_config(shadow_volume, &parms, NULL))
- dsw_error(gettext("Volume is not in a Point-in-Time Copy "
- "group"), NULL);
-
- /* can only attach an overflow volume to dependent, compact shadow */
- (void) strlcpy(args.shadow_vol, shadow_volume, DSW_NAMELEN);
-
- args.status = spcs_s_ucreate();
- if ((do_ioctl(dsw_fd, DSWIOC_STAT, &args) == -1) ||
- !(args.stat & DSW_TREEMAP))
- dsw_error(gettext("Not a compact dependent shadow"), NULL);
-
- /* bitmap_vol is overloaded */
- (void) strlcpy(parms.bitmap_vol, overflow_file, DSW_NAMELEN);
-
- do_attach(&parms);
-
- /* add overflow to cfg line */
- (void) sprintf(key, "ii.set%d.overflow", setnumber);
- if (cfg_put_cstring(cfg, key, overflow_file,
- strlen(overflow_file)) < 0) {
- perror("cfg_put_cstring");
- }
- (void) cfg_commit(cfg);
- return (0);
-}
-
-void
-dsw_join(int argc, char *argv[])
-{
- if (argc != 3)
- usage(gettext("Incorrect number of arguments"));
-
- join(argv[1], argv[2]);
- exit(0);
-}
-
-void
-dsw_params(int argc, char *argv[])
-{
- if (argc != 4 && argc != 2 && argc != 0)
- usage(gettext("Incorrect number of arguments"));
-
- if ((argc == 4) || (argc == 2)) {
- param_delay = argv[1];
- param_unit = argv[2];
- if (argc == 4) {
- argv[1] = argv[3];
- argv[2] = NULL;
- }
- }
- exit(dsw_group_or_single_op(2, argv, params));
-}
-
-/*ARGSUSED*/
-void
-dsw_attach(int argc, char *argv[])
-{
- overflow_file = argv[1];
- argv[1] = argv[2];
- (void) dsw_group_or_single_op(2, argv, attach);
- exit(0);
-}
-
-/*ARGSUSED*/
-void
-dsw_olist(int argc, char *argv[])
-{
- char *sp, *overflow_list, **vol;
- int count, i;
- ENTRY item, *found;
- char key[ CFG_MAX_KEY ], buf[ CFG_MAX_BUF ];
-
- overflow_list = get_overflow_list();
-
- /* count entries */
- count = 0;
- for (sp = overflow_list; *sp; sp += DSW_NAMELEN) {
- ++count;
- }
-
- /* create hash (adding room for suspended overflow volumes) */
- if (hcreate(count + 1024) == 0) {
- dsw_error(gettext("Out of memory creating lookup table"), NULL);
- /*NOTREACHED*/
- }
-
- if (count > 0) {
- /* create memory to store copy of list */
- vol = (char **)calloc(count, sizeof (char *));
- if (!vol) {
- dsw_error(
- gettext("Out of memory creating lookup table"),
- NULL);
- /*NOTREACHED*/
- }
-
- /* fill hash */
- for (i = 0, sp = overflow_list; *sp; sp += DSW_NAMELEN, i++) {
-
- /* make copy of string */
- vol[ i ] = (char *)malloc(DSW_NAMELEN + 1);
- (void) strlcpy(vol[ i ], sp, DSW_NAMELEN);
-
- item.key = vol[ i ];
- item.data = (char *)0;
- (void) hsearch(item, ENTER);
- }
- }
-
- /* loop through config file entries */
- i = 0;
- cfg_rewind(cfg, CFG_SEC_CONF);
-
- /*CONSTCOND*/
- while (1) {
- ++i;
- (void) snprintf(key, CFG_MAX_KEY, "ii.set%d.overflow", i);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) {
- break;
- }
-
- /* has this set got an overflow volume? */
- if (!*buf) {
- continue;
- }
-
- /* look up overflow in hash */
- item.key = buf;
- if (count > 0 && (found = hsearch(item, FIND)) != NULL) {
- if (0 == (int)found->data) {
- (void) printf("%s\n", buf);
- found->data = (char *)1;
- (void) hsearch(*found, ENTER);
- }
- } else {
- /* must be part of a suspended set */
- (void) printf("%s (attached to suspended set)\n", buf);
- item.key = buf;
- item.data = (char *)1;
- (void) hsearch(item, ENTER);
- }
- }
-
- exit(0);
-}
-
-void
-dsw_ostat(int argc, char *argv[])
-{
- dsw_ostat_t args;
- int stat_flags;
-
- if (argc != 2)
- usage(gettext("Incorrect number of arguments"));
-
- (void) strlcpy(args.overflow_vol, argv[1], DSW_NAMELEN);
-
- args.status = spcs_s_ucreate();
- if (do_ioctl(dsw_fd, DSWIOC_OSTAT2, &args) == -1)
- dsw_error(gettext("Stat failed"), &args.status);
- spcs_s_ufree(&args.status);
-
- if ((args.hversion >= 1) && (args.hmagic == II_OMAGIC)) {
- stat_flags = args.flags;
- if (stat_flags & IIO_CNTR_INVLD)
- (void) printf(gettext("Clean shutdown of volume "
- "sets associated with overflow volume "
- "did not occur.\n"
- "Overflow counters will be inconsistent "
- "until new point-in-time(s) are taken.\n"));
- }
- (void) printf(gettext("Total number of attached shadows: %d\n"),
- args.drefcnt);
- (void) printf(gettext("Number of currently attached shadows: %d\n"),
- args.crefcnt);
- (void) printf(gettext("Total number of chunks: %lld\n"), args.nchunks);
- (void) printf(gettext("Number of chunks ever allocated: %lld\n"),
- args.used);
- (void) printf(gettext("Number of used chunks: %lld\n"),
- (args.nchunks - args.unused));
- (void) printf(gettext("Number of unused chunks: %lld\n"), args.unused);
- exit(0);
-}
-
-/*ARGSUSED*/
-void
-dsw_move_2_group(int argc, char *argv[])
-{
- dsw_config_t parms;
- dsw_movegrp_t movegrp;
- grptag_t *gdata;
- int waserr = 0;
-
- /* handle move to NULL group, or group of all spaces or tabs */
- (void) strncpy(movegrp.new_group, group_name, DSW_NAMELEN);
- if ((strlen(group_name) == 0) || (strcspn(group_name, " \t") == 0)) {
- group_name = "-";
- bzero(movegrp.new_group, DSW_NAMELEN);
- gdata = NULL;
- } else {
- /* get the ctag for this group (if any) */
- gdata = (grptag_t *)nsc_lookup(volhash, group_name);
- }
-
- movegrp.status = spcs_s_ucreate();
-
- for (++argv; *argv; argv++) {
- if (!find_shadow_config(*argv, &parms, NULL))
- dsw_error(gettext("Volume is not in a Point-in-Time "
- "Copy group"), NULL);
-
- /* ensure the ctag matches the group */
- if (gdata && *gdata->ctag) {
- if (strncmp(parms.cluster_tag, gdata->ctag,
- DSW_NAMELEN) != 0) {
- (void) fprintf(stderr, "%s: %s %s %s\n", cmdnam,
- gettext("unable to move set"), *argv,
- gettext("into new group - cluster "
- "resource mismatch"));
- waserr = 1;
- continue;
- }
- }
-
- /* move the set in the kernel */
- (void) strncpy(movegrp.shadow_vol, parms.shadow_vol,
- DSW_NAMELEN);
- if (do_ioctl(dsw_fd, DSWIOC_MOVEGRP, &movegrp) < 0)
- dsw_error(gettext("Failed to move group in kernel"),
- NULL);
-
- /* now update the config */
- (void) sprintf(key, "ii.set%d.group", setnumber);
- if (cfg_put_cstring(cfg, key, group_name,
- strlen(group_name)) < 0) {
- perror("cfg_put_cstring");
- }
- (void) cfg_commit(cfg);
- }
- spcs_s_ufree(&movegrp.status);
- cfg_close(cfg);
- exit(waserr);
-}
-
-void
-dsw_list_groups()
-{
- FILE *pfp;
-
- if ((pfp = popen("/usr/bin/sort -u", "w")) == NULL) {
- dsw_error(gettext("Can't open sort program"), NULL);
- }
-
- (void) fflush(stdout);
- for (setnumber = 1; /*CSTYLED*/; setnumber++) {
- (void) snprintf(key, sizeof (key), "ii.set%d.group", setnumber);
- if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0)
- break;
-
- /* skip if shadow set is not in any group */
- if (strcmp(buf, "") == 0)
- continue;
- (void) fprintf(pfp, "%s\n", buf);
- }
- (void) pclose(pfp);
-}
-
-void
-dsw_list_group_volumes()
-{
- FILE *pfp;
-
- if (find_group_members(group_name) < 1)
- dsw_error(gettext("Group does not exist or has no members"),
- NULL);
-
- if ((pfp = popen("/usr/bin/sort -u", "w")) == NULL) {
- dsw_error(gettext("Can't open sort program"), NULL);
- }
-
- (void) fflush(stdout);
- for (; *group_volumes; group_volumes++)
- (void) fprintf(pfp, "%s\n", *group_volumes);
- (void) pclose(pfp);
-}
-
-static void
-load_ii_vols(CFGFILE *cfg)
-{
- int set, entries;
- char *mst, *shd, *buf, **entry;
- char *ctag, *group;
- mstcount_t *mdata;
- shdvol_t *sdata;
- grptag_t *gdata;
- static int whinged = 0;
-
- if (volhash) {
- return;
- }
-
- volhash = nsc_create_hash();
- cfg_rewind(cfg, CFG_SEC_CONF);
- entries = cfg_get_section(cfg, &entry, "ii");
- for (set = 1; set <= entries; set++) {
- buf = entry[set - 1];
-
- /* grab master volume name */
- mst = strtok(buf, " ");
- if (!mst) {
- free(buf);
- break;
- }
-
- /* grab shadow, group & cnode fields */
- shd = strtok(NULL, " ");
- (void) strtok(NULL, " "); /* bitmap */
- (void) strtok(NULL, " "); /* mode */
- (void) strtok(NULL, " "); /* overflow */
- ctag = strtok(NULL, " "); /* cnode */
- (void) strtok(NULL, " "); /* options */
- group = strtok(NULL, " "); /* group */
-
- /* Fix optional tags */
- if (ctag)
- ctag += strspn(ctag, "-");
- if (group)
- group += strspn(group, "-");
-
- /* If cluster tags don't match, skip record */
- if ((cfg_cluster_tag && strcmp(ctag, cfg_cluster_tag)) ||
- (!cfg_cluster_tag && strlen(ctag))) {
- free(buf);
- continue;
- }
-
- /* master volume, may be duplicates */
- mdata = (mstcount_t *)nsc_lookup(volhash, mst);
- if (mdata) {
- ++mdata->count;
- } else {
- mdata = (mstcount_t *)malloc(sizeof (mstcount_t));
- mdata->count = 1;
- (void) nsc_insert_node(volhash, mdata, mst);
- }
-
- /* grab shadow volume name */
- sdata = (shdvol_t *)malloc(sizeof (shdvol_t));
- (void) strncpy(sdata->master, mst, DSW_NAMELEN);
- (void) nsc_insert_node(volhash, sdata, shd);
-
- /* No need to continue if no groups or ctags */
- if (!group || !*group || !ctag || !*ctag) {
- free(buf);
- continue;
- }
-
- gdata = (grptag_t *)nsc_lookup(volhash, group);
- if (gdata) {
- /* group already exists - check ctag */
- if (*ctag &&
- (strncmp(ctag, gdata->ctag, DSW_NAMELEN) != 0)) {
- if (!whinged) {
- (void) printf(gettext(
- "Warning: multiple "
- "cluster resource groups "
- "defined within a single "
- "I/O group\n"));
- whinged = 1;
- }
- }
- } else {
- gdata = (grptag_t *)malloc(sizeof (grptag_t));
- (void) strncpy(gdata->ctag, ctag, DSW_NAMELEN);
- (void) nsc_insert_node(volhash, gdata, group);
- }
-
- free(buf);
- }
-
- /* free up any leftovers */
- while (set < entries)
- free(entry[set++]);
- if (entries)
- free(entry);
-}
-
-static void
-unload_ii_vols()
-{
- nsc_remove_all(volhash, free);
- volhash = 0;
-}
-
-static int
-perform_autosv()
-{
- static int result;
- static int calculated = 0;
- int rc;
-
-#ifdef DEBUG
- if (getenv("II_SET_CLUSTER"))
- return (1);
-#endif
-
- if (calculated) {
- return (result);
- }
-
- /*
- * we only perform auto-sv if we're in a sun cluster or if
- * we're on a standalone system. I.e. we don't do auto-sv on Harry
- */
- rc = check_cluster();
-
- if (II_NOT_CLUSTER == rc) {
- result = 1;
- } else {
- result = cfg_issuncluster();
- }
-
- calculated = 1;
- return (result);
-}
-
-/*
- * Returns true if set has had the shadow volume exported.
- * Returns false if shadow volume is not exported, or set is suspended.
- */
-static int
-is_exported(char *set)
-{
- dsw_stat_t args;
- int rc;
-
- (void) strlcpy(args.shadow_vol, set, DSW_NAMELEN);
- args.status = spcs_s_ucreate();
-
- rc = do_ioctl(dsw_fd, DSWIOC_STAT, &args);
- spcs_s_ufree(&args.status);
-
- if (-1 == rc) {
- /* set must be suspended, or being disabled */
- return (0);
- }
-
- return ((args.stat & DSW_SHDEXPORT) == DSW_SHDEXPORT);
-}
-
-static void
-conform_name(char **path)
-{
- char *cfgname;
- int rc = cfg_get_canonical_name(cfg, *path, &cfgname);
-
- if (rc < 0) {
- dsw_error(gettext("Unable to parse config file"), NULL);
- }
- if (rc) {
- (void) printf(" '%s'\n%s\n '%s'\n", *path,
- gettext("is currently configured as"), cfgname);
- check_action(gettext("Perform operation with indicated volume"
- " name?"));
- *path = cfgname;
- /*
- * NOTE: *path ought to be deallocated ('free(*path)') after
- * we're done with it, but since this routine is called just
- * before we exit, it doesn't really matter
- */
- }
-}
-
-/*
- * verify_groupname(char *, int);
- *
- * Check the group name for the following rules:
- * 1. The name does not start with a '-'
- * 2. The name does not contain any space characters as defined by
- * isspace(3C).
- * If either of these rules are broken, error immediately. The check for a
- * leading dash can be skipped if the 'testDash' argument is false. This is to
- * allow for the '-g -L' functionality.
- *
- */
-static void
-verify_groupname(char *grp, int testDash)
-{
- int i;
-
- if (testDash && grp[0] == '-') {
- errno = EINVAL;
- dsw_error(gettext("group name cannot start with a '-'"), NULL);
- }
-
- for (i = 0; grp[i] != '\0'; i++) {
- if (isspace(grp[i])) {
- errno = EINVAL;
- dsw_error(gettext("group name cannot contain a space"),
- NULL);
- }
- }
-}
-
-void
-check_iishadow(char *shadow_vol) {
- int i;
- int entries;
- char **entry;
- char *shost;
- char *svol;
- char *buf;
- void *librdc;
-
- /*
- * See if librdc is around
- * If not, we can just return
- */
- if (librdc = dlopen(RDC_LIB, RTLD_LAZY | RTLD_GLOBAL))
- self_check = (int (*)(char *)) dlsym(librdc, "self_check");
- else {
- return;
- }
-
- entry = NULL;
- entries = cfg_get_section(cfg, &entry, "sndr");
- for (i = 0; i < entries; i++) {
- buf = entry[i];
-
- (void) strtok(buf, " "); /* phost */
- (void) strtok(NULL, " "); /* primary */
- (void) strtok(NULL, " "); /* pbitmap */
- shost = strtok(NULL, " "); /* shost */
- svol = strtok(NULL, " "); /* secondary */
-
- if (self_check(shost) && (strcmp(shadow_vol, svol) == 0)) {
- free(buf);
- if (entries)
- free(entry);
- errno = EINVAL;
- dsw_error(gettext(
- "shadow volume is in use as SNDR secondary volume"),
- NULL);
- }
- free(buf);
- }
-
- (void) dlclose(librdc);
- if (entries)
- free(entry);
-}
diff --git a/usr/src/cmd/avs/dsw/iiboot.c b/usr/src/cmd/avs/dsw/iiboot.c
deleted file mode 100644
index 4886ecfd68..0000000000
--- a/usr/src/cmd/avs/dsw/iiboot.c
+++ /dev/null
@@ -1,684 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <stdio.h>
-#include <sys/param.h>
-#include <errno.h>
-#include <limits.h>
-#include <fcntl.h>
-#include <strings.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <signal.h>
-
-#include <locale.h>
-#include <langinfo.h>
-#include <libintl.h>
-#include <stdarg.h>
-#include <ctype.h>
-
-#include <sys/nsctl/cfg.h>
-
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_u.h>
-#include <sys/unistat/spcs_errors.h>
-
-#include <sys/nsctl/dsw.h>
-#include <sys/nskernd.h>
-
-#define MAX_PROCESSES 64
-
-int parseopts(int, char **, int *);
-int read_resume_cfg();
-int read_suspend_cfg();
-void iiboot_usage(void);
-extern char *basename(char *);
-
-dsw_config_t *resume_list = 0;
-dsw_ioctl_t *suspend_list = 0;
-int n_structs;
-char *program;
-char *cfg_cluster_tag = NULL;
-
-volatile int fork_cnt;
-volatile int fork_rc;
-
-static void
-iiboot_msg(char *prefix, spcs_s_info_t *status, char *string, va_list ap)
-{
- if (status) {
- (void) fprintf(stderr, "II: %s\n", prefix);
- spcs_s_report(*status, stderr);
- spcs_s_ufree(status);
- } else {
- (void) fprintf(stderr, "%s: %s: ", program, prefix);
- }
-
- if (string && *string != '\0') {
- (void) vfprintf(stderr, string, ap);
- }
-
- (void) fprintf(stderr, "\n");
-}
-
-static void
-iiboot_err(spcs_s_info_t *status, char *string, ...)
-{
- va_list ap;
- va_start(ap, string);
-
- iiboot_msg(gettext("Error"), status, string, ap);
-
- va_end(ap);
- exit(1);
-}
-
-static void
-iiboot_warn(spcs_s_info_t *status, char *string, ...)
-{
- va_list ap;
- va_start(ap, string);
-
- iiboot_msg(gettext("warning"), status, string, ap);
-
- va_end(ap);
-}
-
-/* ARGSUSED */
-static void
-sigchld(int sig)
-{
- int wait_loc = 0;
-
- (void) wait(&wait_loc);
- if (WIFEXITED(wait_loc) && (WEXITSTATUS(wait_loc) == 0)) {
- ;
- /*EMPTY*/
- } else {
- fork_rc = WEXITSTATUS(wait_loc);
- }
-
- if (fork_cnt > 0)
- --fork_cnt;
-}
-
-
-int
-#ifdef lint
-iiboot_lintmain(int argc, char *argv[])
-#else
-main(int argc, char *argv[])
-#endif
-{
- int pairs;
- pid_t pid = 0;
- int flag = 0;
- int i, j;
- int rc;
- int ioctl_fd;
- void *ioarg;
- dsw_ioctl_t *ii_iop, ii_suspend;
- dsw_list_t args = {0};
- dsw_config_t *ii_cfgp, *lp = NULL;
- spcs_s_info_t ustatus;
- int max_processes = MAX_PROCESSES;
-
- (void) setlocale(LC_ALL, "");
- (void) textdomain("ii");
-
- program = strdup(basename(argv[0]));
-
- if ((ioctl_fd = open(DSWDEV, O_RDWR, 0)) == -1) {
- spcs_log("ii", NULL, "iiboot open %s failed, errno %d",
- DSWDEV, errno);
- iiboot_err(NULL,
- gettext("Failed to open Point-in-Time Copy control "
- "device"));
- }
-
- if (parseopts(argc, argv, &flag))
- return (1);
-
- if (flag == DSWIOC_RESUME)
- pairs = read_resume_cfg();
- else
- pairs = -1;
-
- if (pairs == 0) {
-#ifdef DEBUG
- iiboot_err(NULL,
- gettext("Config contains no Point-in-Time Copy sets"));
-#endif
- return (0);
- }
-
- if (cfg_cluster_tag == NULL && flag != DSWIOC_RESUME) {
- if (ioctl(ioctl_fd, DSWIOC_SHUTDOWN, 0) < 0) {
- spcs_log("ii", &ustatus, "iiboot shutdown failed");
- iiboot_err(NULL, gettext("SHUTDOWN ioctl error"));
- }
- return (0);
- } else if (cfg_cluster_tag != NULL && flag == DSWIOC_SUSPEND) {
- bzero(&ii_suspend, sizeof (dsw_ioctl_t));
- ii_suspend.status = spcs_s_ucreate();
- ii_suspend.flags = CV_IS_CLUSTER;
- (void) strncpy(ii_suspend.shadow_vol, cfg_cluster_tag,
- DSW_NAMELEN);
- rc = ioctl(ioctl_fd, flag, &ii_suspend);
- if ((rc) && (errno != DSW_ECNOTFOUND)) {
- spcs_log("ii", &ii_suspend.status,
- "iiboot resume cluster %s failed", cfg_cluster_tag);
- iiboot_err(&ii_suspend.status, gettext("ioctl error"));
- spcs_s_ufree(&ii_suspend.status);
- return (-1);
- }
- spcs_s_ufree(&ii_suspend.status);
- return (0);
-
- } else if ((cfg_cluster_tag != NULL) && (flag == DSWIOC_RESUME)) {
- /*
- * If we are running in a Sun Cluster, this is a resume
- * operation, get a list of all shadow volumes, where the
- * shadow volumes match the shadows of the sets being resumed
- */
- rc = ioctl(ioctl_fd, DSWIOC_LISTLEN, &args);
- if (rc == -1) {
- spcs_log("ii", NULL,
- "iiboot get LIST failed, errno %d", errno);
- iiboot_err(NULL,
- gettext("Failed to get LIST of Point-in-Time "
- "sets"));
- return (-1);
- }
-
- args.status = spcs_s_ucreate();
- args.list_used = 0;
- args.list_size = rc + 4;
- lp = args.list = (dsw_config_t *)
- malloc(args.list_size * sizeof (dsw_config_t));
- if (args.list == NULL) {
- iiboot_err(NULL,
- gettext("Failed to allocate memory"));
- }
- if (ioctl(ioctl_fd, DSWIOC_LIST, &args) == -1) {
- spcs_log("ii", &args.status, "Failed to get LIST");
- iiboot_err(&args.status, gettext("ioctl error"));
- }
- spcs_s_ufree(&args.status);
-
- /* Remove all elements that are not in the resume list */
- for (j = args.list_used; j; j--) {
- for (i = 0; i < pairs; i++) {
- if (strcmp(lp->shadow_vol,
- resume_list[i].shadow_vol) == 0) {
- if (strlen(lp->cluster_tag) == 0) {
- lp++;
- break;
- }
- }
- }
- if (i != pairs)
- continue;
- (void) memmove(lp, lp + 1, j * sizeof (dsw_config_t));
- args.list_used--;
- }
- }
-
- (void) sigset(SIGCHLD, sigchld);
- fork_cnt = fork_rc = 0;
- for (i = 0; i < pairs; i++) {
- ustatus = spcs_s_ucreate();
- if (flag == DSWIOC_RESUME) {
- ioarg = (void *) (ii_cfgp = (resume_list + i));
- ii_cfgp->status = ustatus;
- pid = fork();
- } else {
- ioarg = (void *) (ii_iop = (suspend_list + i));
- ii_iop->status = ustatus;
- }
- while (pid == -1) { /* error forking */
- perror("fork");
-
- /* back off on the max processes and try again */
- --max_processes;
- if (fork_cnt > 0) {
- (void) pause();
- }
- pid = fork();
- }
-
- if (pid > 0) { /* this is parent process */
- ++fork_cnt;
- while (fork_cnt > MAX_PROCESSES) {
- (void) pause();
- }
- continue;
- }
-
- rc = ioctl(ioctl_fd, flag, ioarg);
- if (rc == SPCS_S_ERROR) {
- if (flag == DSWIOC_RESUME)
- spcs_log("ii", &ustatus,
- "iiboot resume %s failed",
- ii_cfgp->shadow_vol);
- else
- spcs_log("ii", &ustatus,
- "iiboot suspend %s failed",
- ii_iop->shadow_vol);
- iiboot_err(&ustatus, gettext("ioctl error"));
- }
- /* Resuming child */
- spcs_s_ufree(&ustatus);
- if (flag == DSWIOC_RESUME)
- exit(0);
- }
-
- /*
- * Allow all processes to finish up before exiting
- * Set rc for success
- */
- while (fork_cnt > 0) {
- (void) alarm(60); /* wake up in 60 secs just in case */
- (void) pause();
- }
- (void) alarm(0);
-
- /* Disable duplicate shadows that were part of the implicit join */
- if ((j = args.list_used) != 0) {
- int setno;
- char key[CFG_MAX_KEY], buf[CFG_MAX_BUF], sn[CFG_MAX_BUF];
- CFGFILE *cfg;
- char *mst, *shd, *ctag;
- pid_t pid = fork();
-
- if (pid == -1) {
- iiboot_err(NULL, gettext("Failed to fork"));
- return (errno);
- } else if (pid > 0) {
- return (0); /* Parent, OK exit */
- }
-
- for (j = args.list_used, lp = args.list; j; j--, lp++) {
- setno = 0;
- while (++setno) {
-
- /*
- * Open the configuration database
- */
- if (!(cfg = cfg_open(""))) {
- iiboot_err(NULL, gettext("Failed to open dscfg"));
- return (-1);
- }
-
- /* Sooner or later, this lock will be free */
- while (!cfg_lock(cfg, CFG_WRLOCK))
- (void) sleep(2);
-
- (void) snprintf(key, CFG_MAX_KEY, "ii.set%d", setno);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) {
- cfg_close(cfg);
- break;
- }
-
- /* For imported shadows, master must be special tag */
- mst = strtok(buf, " "); /* master */
- shd = strtok(NULL, " "); /* shadow */
- (void) strtok(NULL, " "); /* bitmap */
- (void) strtok(NULL, " "); /* mode */
- (void) strtok(NULL, " "); /* overflow */
- ctag = strtok(NULL, " "); /* cnode */
-
- /*
- * For this record to be processed, the shadow volume
- * name must match and the cluster tag must be blank
- */
- if (strcmp(lp->shadow_vol, shd) || strcmp(ctag, "-")) {
- cfg_close(cfg);
- continue;
- }
-
- /* Derrive local cluster tag */
- if (cfg_l_dgname(lp->shadow_vol, sn, sizeof (sn)))
- ctag = sn;
- else
- iiboot_err(NULL, gettext(
- "Failed to device group for shadow %s"),
- lp->shadow_vol);
-
- /* disable master volume if not imported */
- if (strcmp(mst, II_IMPORTED_SHADOW))
- if (cfg_vol_disable(cfg, mst, cfg_cluster_tag,
- "ii") < 0)
- iiboot_err(NULL, gettext(
- "SV disable of master failed"));
-
- /*
- * Delete the Imported Shadow set
- */
- if (cfg_put_cstring(cfg, key, NULL, 0) < 0) {
- iiboot_err(NULL, gettext(
- "Failed to delete Imported shadow %s"),
- lp->shadow_vol);
- }
-
- /*
- * SV disable shadow volume
- */
- if (cfg_vol_disable(cfg, shd, NULL, "ii") < 0)
- iiboot_err(NULL, gettext(
- "SV disable of shadow failed"));
-
- /*
- * Commit the delete
- */
- (void) cfg_commit(cfg);
- cfg_close(cfg);
-
- /*
- * Open the configuration database
- */
- if (!(cfg = cfg_open(""))) {
- iiboot_err(NULL, gettext("Failed to open dscfg"));
- return (-1);
- }
-
- /* Sooner or later, this lock will be free */
- while (!cfg_lock(cfg, CFG_WRLOCK))
- (void) sleep(2);
-
- /* Set cluster tag for Shadow volume */
- (void) cfg_vol_enable(cfg, shd, ctag, "ii");
-
-
- /*
- * Commit the delete
- */
- (void) cfg_commit(cfg);
- cfg_close(cfg);
- }
- }
- }
- return (fork_rc);
-}
-
-static int
-set_is_offline(char *cflags)
-{
- unsigned int flags;
- int conv;
-
- if (!cflags || !*cflags)
- return (0);
-
- /* convert flags to an int */
- conv = sscanf(cflags, "%x", &flags);
- return ((conv == 1) && ((flags & DSW_OFFLINE) != 0));
-}
-
-/*
- * read_resume_cfg()
- *
- * DESCRIPTION: Read the relevant config info via libcfg
- *
- * Outputs:
- * int i Number of Point-in-Time Copy sets
- *
- * Side Effects: The 0 to i-1 entries in the resume_list are filled.
- *
- */
-
-int
-read_resume_cfg()
-{
- CFGFILE *cfg;
- int i;
- char *buf, **entry, *mst, *shd, *bmp, *ctag, *opt, *ptr;
- int valid_sets;
- dsw_config_t *p;
- static int offset = sizeof (NSKERN_II_BMP_OPTION);
-
- spcs_log("ii", NULL, "iiboot resume cluster tag %s",
- cfg_cluster_tag ? cfg_cluster_tag : "<none>");
- if ((cfg = cfg_open("")) == NULL) {
- spcs_log("ii", NULL, "iiboot cfg_open failed, errno %d",
- errno);
- iiboot_err(NULL, gettext("Error opening config"));
- }
-
- cfg_resource(cfg, cfg_cluster_tag);
- if (!cfg_lock(cfg, CFG_RDLOCK)) {
- spcs_log("ii", NULL, "iiboot CFG_RDLOCK failed, errno %d",
- errno);
- iiboot_err(NULL, gettext("Error locking config"));
- }
-
- /* Determine number of set, if zero return 0 */
- if ((n_structs = cfg_get_section(cfg, &entry, "ii")) == 0)
- return (0);
-
- resume_list = calloc(n_structs, sizeof (*resume_list));
- if (resume_list == NULL) {
- spcs_log("ii", NULL, "iiboot resume realloc failed, errno %d",
- errno);
- iiboot_err(NULL, gettext("Resume realloc failed"));
- }
-
- valid_sets = 0;
- p = resume_list;
- for (i = 0; i < n_structs; i++) {
- buf = entry[i];
- mst = strtok(buf, " ");
- shd = strtok(NULL, " ");
- bmp = strtok(NULL, " ");
- (void) strtok(NULL, " "); /* mode */
- (void) strtok(NULL, " "); /* overflow */
- ctag = strtok(NULL, " "); /* ctag */
- if (ctag)
- ctag += strspn(ctag, "-");
- opt = strtok(NULL, " ");
-
- if (!mst || !shd || !bmp)
- break;
-
- /* If cluster tags don't match, skip record */
- if ((cfg_cluster_tag && strcmp(ctag, cfg_cluster_tag)) ||
- (!cfg_cluster_tag && strlen(ctag))) {
- free(buf);
- continue;
- }
-
- ptr = strstr(opt, NSKERN_II_BMP_OPTION "=");
- if (ptr && set_is_offline(ptr + offset)) {
- free(buf);
- continue;
- }
-
- (void) strncpy(p->master_vol, mst, DSW_NAMELEN);
- (void) strncpy(p->shadow_vol, shd, DSW_NAMELEN);
- (void) strncpy(p->bitmap_vol, bmp, DSW_NAMELEN);
- if (ctag)
- (void) strncpy(p->cluster_tag, ctag, DSW_NAMELEN);
- free(buf);
- ++p;
- ++valid_sets;
- }
-
- while (i < n_structs)
- free(entry[i++]);
- if (entry)
- free(entry);
-
- cfg_close(cfg);
- return (valid_sets);
-}
-
-/*
- * read_suspend_cfg()
- *
- * DESCRIPTION: Read the relevant config info via libcfg
- *
- * Outputs:
- * int i Number of Point-in-Time Copy sets
- *
- * Side Effects: The 0 to i-1 entries in the suspend_list are filled.
- *
- */
-
-int
-read_suspend_cfg()
-{
- int rc;
- CFGFILE *cfg;
- int i;
- char buf[CFG_MAX_BUF];
- char key[CFG_MAX_KEY];
- int setnumber;
- dsw_ioctl_t *p;
-
- spcs_log("ii", NULL, "iiboot suspend cluster tag %s",
- cfg_cluster_tag ? cfg_cluster_tag : "<none>");
-
- if (cfg_cluster_tag == NULL) {
- return (1);
- }
-
- if ((cfg = cfg_open("")) == NULL) {
- spcs_log("ii", NULL, "iiboot cfg_open failed, errno %d",
- errno);
- iiboot_err(NULL, gettext("Error opening config"));
- }
-
- cfg_resource(cfg, cfg_cluster_tag);
- if (!cfg_lock(cfg, CFG_RDLOCK)) {
- spcs_log("ii", NULL, "iiboot CFG_RDLOCK failed, errno %d",
- errno);
- iiboot_err(NULL, gettext("Error locking config"));
- }
-
-
- /*CSTYLED*/
- for (i = 0; ; i++) {
- setnumber = i + 1;
-
- bzero(buf, CFG_MAX_BUF);
- (void) snprintf(key, sizeof (key), "ii.set%d", setnumber);
- rc = cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF);
- if (rc < 0)
- break;
- if (n_structs < setnumber) {
- n_structs += 2;
- suspend_list = realloc(suspend_list,
- sizeof (*suspend_list) * n_structs);
- if (suspend_list == NULL) {
- spcs_log("ii", NULL,
- "iiboot suspend realloc failed, errno %d",
- errno);
- iiboot_err(NULL, gettext("Suspend realloc failed"));
- }
- }
- p = suspend_list + i;
-
- (void) snprintf(key, sizeof (key), "ii.set%d.shadow",
- setnumber);
- (void) cfg_get_cstring(cfg, key, p->shadow_vol, DSW_NAMELEN);
-
- }
-
- cfg_close(cfg);
- return (i);
-}
-
-
-int
-parseopts(argc, argv, flag)
-int argc;
-char **argv;
-int *flag;
-{
- int errflag = 0;
- int Cflag = 0;
- char c;
- char inval = 0;
-
- while ((c = getopt(argc, argv, "hrsC:")) != -1) {
- switch (c) {
- case 'C':
- if (Cflag) {
- iiboot_warn(NULL,
- gettext("-C specified multiple times"));
- iiboot_usage();
- return (-1);
- }
-
- Cflag++;
- cfg_cluster_tag = (optarg[0] == '-') ? NULL : optarg;
- break;
-
- case 'h':
- iiboot_usage();
- exit(0);
- /* NOTREACHED */
-
- case 'r':
- if (*flag)
- inval = 1;
- *flag = DSWIOC_RESUME;
- break;
- case 's':
- if (*flag)
- inval = 1;
- *flag = DSWIOC_SUSPEND;
- break;
- case '?':
- errflag++;
- }
- }
-
- if (inval) {
- iiboot_warn(NULL, gettext("Invalid argument combination"));
- errflag = 1;
- }
-
- if (!*flag || errflag) {
- iiboot_usage();
- return (-1);
- }
-
- return (0);
-}
-
-void
-iiboot_usage()
-{
- (void) fprintf(stderr, gettext("usage:\n"));
- (void) fprintf(stderr,
- gettext("\t%s -r [-C tag]\t\tresume\n"), program);
- (void) fprintf(stderr,
- gettext("\t%s -s [-C tag]\t\tsuspend\n"), program);
- (void) fprintf(stderr, gettext("\t%s -h\t\t\tthis help message\n"),
- program);
-}
diff --git a/usr/src/cmd/avs/dsw/iicpbmp.c b/usr/src/cmd/avs/dsw/iicpbmp.c
deleted file mode 100644
index 382759b3fa..0000000000
--- a/usr/src/cmd/avs/dsw/iicpbmp.c
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <errno.h>
-#include <signal.h>
-#include <stdio.h>
-#include <string.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <values.h>
-#include <locale.h>
-#include <sys/stat.h>
-#include <strings.h>
-#include <stdarg.h>
-#include <sys/param.h>
-#include <nsctl.h>
-
-#include <sys/nsctl/cfg.h>
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_u.h>
-#include <sys/unistat/spcs_errors.h>
-#include <sys/nsctl/dsw.h>
-#include <sys/nsctl/dsw_dev.h>
-
-#define DSW_TEXT_DOMAIN "II"
-
-void iicpbmp_usage();
-void copybmp(char *, char *);
-int find_bitmap_cfg(char *);
-
-extern int optind;
-
-char *cmdnam;
-
-extern char *optarg;
-extern int optind, opterr, optopt;
-int update_cfg = 1;
-CFGFILE *cfg;
-char shadow[DSW_NAMELEN];
-char buf[CFG_MAX_BUF];
-char key[CFG_MAX_KEY];
-int setnumber;
-
-#ifdef lint
-int
-iicpbmp_lintmain(int argc, char *argv[])
-#else
-int
-main(int argc, char *argv[])
-#endif
-{
- cmdnam = argv[0];
-
- if (argc > 1) {
- if (strcmp(argv[1], "-c") == 0) {
- /* don't update cfg information */
- update_cfg = 0;
- argc--;
- argv++;
- }
- }
-
- if (argc == 1 || (argc%2) == 0) /* must have pairs of filenames */
- iicpbmp_usage();
-
- if (update_cfg) {
- if ((cfg = cfg_open(NULL)) == NULL) {
- (void) fprintf(stderr,
- gettext("Error opening config\n"));
- exit(1);
- }
-
- if (!cfg_lock(cfg, CFG_WRLOCK)) {
- spcs_log("ii", NULL,
- "iicpbmp CFG_WRLOCK failed, errno %d", errno);
- (void) fprintf(stderr,
- gettext("Error locking config\n"));
- exit(1);
- }
- }
-
- for (argv++; *argv != NULL; argv += 2)
- copybmp(argv[0], argv[1]);
- if (update_cfg)
- cfg_close(cfg);
- exit(0);
- return (0);
-}
-
-void
-iicpbmp_usage()
-{
- (void) fprintf(stderr, gettext("Usage:\n"));
- (void) fprintf(stderr,
- gettext("\tiicpbmp [-c] old_bitmap new_bitmap\n"));
- exit(1);
-}
-
-void
-copybmp(char *old_bitmap, char *new_bitmap)
-{
- int i;
- int dsw_fd;
- FILE *ifp, *ofp;
- ii_header_t header;
- char cp_buffer[256];
- dsw_stat_t args;
-
- dsw_fd = open(DSWDEV, O_RDONLY);
- if (dsw_fd < 0) {
- perror(DSWDEV);
- exit(1);
- }
- if (*old_bitmap != '/' || *new_bitmap != '/') {
- (void) fprintf(stderr, gettext("Both old and new bitmap "
- "file names must begin with a /.\n"));
- exit(1);
- }
-
- if (strlen(new_bitmap) > DSW_NAMELEN) {
- (void) fprintf(stderr,
- gettext("New bitmap name is too long.\n"));
- exit(1);
- }
-
- if (update_cfg && find_bitmap_cfg(old_bitmap) == 0) {
- perror(old_bitmap);
- (void) fprintf(stderr,
- gettext("Old bitmap not in existing cfg\n"));
- exit(1);
- }
-
- (void) strncpy(args.shadow_vol, shadow, DSW_NAMELEN);
- args.shadow_vol[DSW_NAMELEN-1] = '\0';
-
- args.status = spcs_s_ucreate();
- if (ioctl(dsw_fd, DSWIOC_STAT, &args) != -1) {
- (void) fprintf(stderr, gettext("Suspend the Point-in-Time Copy "
- "set first\n"));
- (void) close(dsw_fd);
- exit(1);
- }
-
- if ((ifp = fopen(old_bitmap, "r")) == NULL) {
- perror(old_bitmap);
- (void) fprintf(stderr, gettext("Can't open old bitmap file\n"));
- exit(1);
- }
-
- /* Check old header looks like an Point-in-Time Copy bitmap header */
-
- if (fread(&header, sizeof (header), 1, ifp) != 1) {
- (void) fprintf(stderr, gettext("Can't read old bitmap file\n"));
- exit(1);
- }
-
- if (header.ii_magic != DSW_CLEAN && header.ii_magic != DSW_DIRTY) {
- (void) fprintf(stderr, gettext("%s is not a Point-in-Time Copy "
- "bitmap.\n"), old_bitmap);
- exit(1);
- }
-
- if (strncmp(header.bitmap_vol, old_bitmap, DSW_NAMELEN) != 0) {
- (void) fprintf(stderr, gettext(
- "%s has Point-in-Time Copy bitmap magic number,\n"
- "but does not contain correct data.\n"), old_bitmap);
- exit(1);
- }
-
- if ((ofp = fopen(new_bitmap, "w")) == NULL) {
- perror(new_bitmap);
- (void) fprintf(stderr, gettext("Can't open new bitmap file\n"));
- exit(1);
- }
-
- /* Set up new header */
-
- (void) memset(header.bitmap_vol, 0, DSW_NAMELEN);
- (void) strncpy(header.bitmap_vol, new_bitmap, DSW_NAMELEN);
-
- if (fwrite(&header, sizeof (header), 1, ofp) != 1) {
- perror(new_bitmap);
- (void) fprintf(stderr,
- gettext("Can't write new bitmap header\n"));
- exit(1);
- }
-
- /* Copy the bitmap itself */
-
- while ((i = fread(cp_buffer, sizeof (char), sizeof (cp_buffer), ifp))
- > 0) {
- if (fwrite(cp_buffer, sizeof (char), i, ofp) != i) {
- perror(gettext("Write new bitmap failed"));
- break;
- }
- }
- (void) fclose(ofp);
- (void) fclose(ifp);
- (void) close(dsw_fd);
- if (update_cfg) {
- (void) sprintf(key, "ii.set%d.bitmap", setnumber);
- if (cfg_put_cstring(cfg, key, new_bitmap, strlen(new_bitmap))
- < 0) {
- perror("cfg_put_cstring");
- }
- (void) cfg_commit(cfg);
- spcs_log("ii", NULL,
- "iicpbmp copy bit map for %s from %s to %s",
- shadow, old_bitmap, new_bitmap);
- }
-}
-
-/*
- * find_bitmap_cfg()
- *
- */
-
-int
-find_bitmap_cfg(char *bitmap)
-{
- for (setnumber = 1; ; setnumber++) {
- bzero(buf, CFG_MAX_BUF);
- (void) snprintf(key, sizeof (key), "ii.set%d.bitmap",
- setnumber);
-
- if (cfg_get_cstring(cfg, key, buf, DSW_NAMELEN) < 0)
- return (0);
- if (strcmp(buf, bitmap) == 0) {
- (void) snprintf(key, sizeof (key), "ii.set%d.shadow",
- setnumber);
- (void) cfg_get_cstring(cfg, key, shadow, DSW_NAMELEN);
- return (setnumber);
- }
- }
-}
diff --git a/usr/src/cmd/avs/dsw/iicpshd.c b/usr/src/cmd/avs/dsw/iicpshd.c
deleted file mode 100644
index d34b3f41c5..0000000000
--- a/usr/src/cmd/avs/dsw/iicpshd.c
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <errno.h>
-#include <signal.h>
-#include <stdio.h>
-#include <string.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <values.h>
-#include <locale.h>
-#include <sys/stat.h>
-#include <strings.h>
-#include <stdarg.h>
-#include <sys/param.h>
-#include <nsctl.h>
-
-#include <sys/nsctl/cfg.h>
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_u.h>
-#include <sys/unistat/spcs_errors.h>
-#include <sys/nsctl/dsw.h>
-#include <sys/nsctl/dsw_dev.h> /* for bitmap format */
-
-#define DSW_TEXT_DOMAIN "II"
-#define BITMAP_TOKEN "ii.set%d.bitmap"
-#define SHADOW_TOKEN "ii.set%d.shadow"
-#define SV_TOKEN "sv.set%d.vol"
-#define DSVOL_TOKEN "dsvol.set%d.path"
-
-void iicpshd_usage();
-void copyshd(char *, char *);
-int find_cfg_info(char *, char *);
-int copy_shadow_vol(char *, char *);
-void convert_to_blockdevice();
-int update_dscfg(char *);
-
-extern int optind;
-
-extern char *optarg;
-extern int optind, opterr, optopt;
-int copy_shadow = 1;
-CFGFILE *cfg;
-char real_bitmap[DSW_NAMELEN];
-char buf[CFG_MAX_BUF];
-char key[CFG_MAX_KEY];
-int set_number;
-int sv_number;
-int dsvol_number;
-
-#ifdef lint
-int
-iicpshd_lintmain(int argc, char *argv[])
-#else
-int
-main(int argc, char *argv[])
-#endif
-{
- if (argc > 1) {
- if (strcmp(argv[1], "-s") == 0) {
- /* don't copy shadow, only update dscfg and ii header */
- copy_shadow = 0;
- argc--;
- argv++;
- }
- }
-
- if (argc == 1 || (argc%2) == 0) /* must have pairs of filenames */
- iicpshd_usage();
-
- /* open dscfg anyway */
- if ((cfg = cfg_open(NULL)) == NULL) {
- (void) fprintf(stderr, gettext("Error opening config\n"));
- exit(1);
- }
-
- for (argv++; *argv != NULL; argv += 2)
- copyshd(argv[0], argv[1]);
-
- /* close dscfg */
- cfg_close(cfg);
- exit(0);
- return (0);
-}
-
-void
-iicpshd_usage()
-{
- (void) fprintf(stderr, gettext("Usage:\n"));
- (void) fprintf(stderr,
- gettext("\tiicpshd [-s] old_shadow new_shadow\n"));
- exit(1);
-}
-
-void
-copyshd(char *old_vol, char *new_vol)
-{
- int dsw_fd;
- FILE *ifp;
- char header[FBA_SIZE(1) * DSW_CBLK_FBA];
- ii_header_t *hp;
- dsw_stat_t args;
-
- /*LINTED pointer alignment*/
- hp = (ii_header_t *)&header;
-
- dsw_fd = open(DSWDEV, O_RDONLY);
- if (dsw_fd < 0) {
- perror(DSWDEV);
- exit(1);
- }
- if (*old_vol != '/' || *new_vol != '/') {
- (void) fprintf(stderr, gettext("Both old and new shadow "
- "file names must begin with a /.\n"));
- exit(1);
- }
-
- if (strlen(new_vol) > DSW_NAMELEN) {
- (void) fprintf(stderr,
- gettext("New shadow name is to long.\n"));
- exit(1);
- }
-
- /* check old shadow is in dscfg */
- if (find_cfg_info(old_vol, SHADOW_TOKEN) == 0) {
- (void) fprintf(stderr,
- gettext("Old shadow not in existing cfg\n"));
- exit(1);
- }
-
- /* check ii set status, suspend if need */
- (void) strncpy(args.shadow_vol, old_vol, DSW_NAMELEN);
- args.shadow_vol[DSW_NAMELEN-1] = '\0';
- args.status = spcs_s_ucreate();
- if (ioctl(dsw_fd, DSWIOC_STAT, &args) != -1) {
- (void) fprintf(stderr, gettext("Suspend the Point-in-Time Copy "
- "set first\n"));
- (void) close(dsw_fd);
- exit(1);
- }
-
- if (copy_shadow) {
- if (copy_shadow_vol(old_vol, new_vol) == 0) {
- perror(gettext("Write new shadow failed"));
- (void) close(dsw_fd);
- exit(1);
- }
- }
- if (find_cfg_info(old_vol, SV_TOKEN) == 0) {
- (void) fprintf(stderr,
- gettext("Old shadow not in existing cfg\n"));
- exit(1);
- }
- if (find_cfg_info(old_vol, DSVOL_TOKEN) == 0) {
- (void) fprintf(stderr,
- gettext("Old shadow not in existing cfg\n"));
- exit(1);
- }
- if (strstr(real_bitmap, "/rdsk/") == NULL) {
- (void) fprintf(stderr,
- gettext("%s is not a character device\n"), real_bitmap);
- exit(1);
- }
-
- /* use block device /dsk/ to update bitmap header */
- convert_to_blockdevice();
-
- /* open bitmap by using update mode */
- if ((ifp = fopen(real_bitmap, "r+")) == NULL) {
- (void) fprintf(stderr, gettext("Can't open bitmap file\n"));
- exit(1);
- }
-
- /* Check old header looks like an II bitmap header */
- if (fread(&header, DSW_CBLK_FBA, FBA_SIZE(1), ifp) != FBA_SIZE(1)) {
- (void) fprintf(stderr, gettext("Can't read bitmap file\n"));
- exit(1);
- }
-
- if (hp->ii_magic != DSW_CLEAN && hp->ii_magic != DSW_DIRTY) {
- (void) fprintf(stderr,
- gettext("%s is not a Point-in-Time Copy "
- "shadow.\n"), old_vol);
- exit(1);
- }
-
- if (strncmp(hp->shadow_vol, old_vol, DSW_NAMELEN) != 0) {
- (void) fprintf(stderr, gettext("%s has Point-in-Time Copy "
- "shadow magic number,\n"
- "but does not contain correct data.\n"), old_vol);
- exit(1);
- }
-
- (void) memset(hp->shadow_vol, 0, DSW_NAMELEN);
- (void) strncpy(hp->shadow_vol, new_vol, DSW_NAMELEN);
-
- /* reset the pointer position */
- rewind(ifp);
- if (fwrite(&header, DSW_CBLK_FBA, FBA_SIZE(1), ifp) != FBA_SIZE(1)) {
- perror(new_vol);
- (void) fprintf(stderr,
- gettext("Can't write new bitmap header\n"));
- exit(1);
- }
- (void) fclose(ifp);
- (void) close(dsw_fd);
- if (update_dscfg(new_vol) == 0) {
- (void) fprintf(stderr, gettext("Failed to update dscfg.\n"));
- exit(1);
- } else {
- spcs_log("ii", NULL,
- "iicpshd copy shadow from %s to %s",
- old_vol, new_vol);
- }
-}
-
-/*
- * find_cfg_info()
- *
- */
-
-int
-find_cfg_info(char *volume, char *token)
-{
- int i;
- /* get read lock */
- if (!cfg_lock(cfg, CFG_RDLOCK)) {
- spcs_log("ii", NULL,
- "iicpbmp CFG_RDLOCK failed, errno %d", errno);
- (void) fprintf(stderr, gettext("Error locking config\n"));
- exit(1);
- }
- for (i = 1; ; i++) {
- bzero(buf, CFG_MAX_BUF);
- (void) snprintf(key, sizeof (key), token, i);
- if (cfg_get_cstring(cfg, key, buf, DSW_NAMELEN) < 0) {
- cfg_unlock(cfg);
- return (0);
- }
- if (strcmp(buf, volume) == 0) {
- if (strcmp(token, SHADOW_TOKEN) == 0) {
- (void) snprintf(key, sizeof (key),
- BITMAP_TOKEN, i);
- (void) cfg_get_cstring(cfg, key,
- real_bitmap, DSW_NAMELEN);
- set_number = i;
- } else if (strcmp(token, SV_TOKEN) == 0) {
- sv_number = i;
- } else if (strcmp(token, DSVOL_TOKEN) == 0) {
- dsvol_number = i;
- }
- /* release read lock */
- cfg_unlock(cfg);
- return (1);
- }
- }
-}
-
-int
-copy_shadow_vol(char *old_shadow, char *new_shadow) {
- int i;
- char cp_buffer[256];
- FILE *ishdfp, *oshdfp;
- if ((ishdfp = fopen(old_shadow, "r")) == NULL) {
- (void) fprintf(stderr, gettext("Can't open old shadow file\n"));
- return (0);
- }
- if ((oshdfp = fopen(new_shadow, "w")) == NULL) {
- (void) fprintf(stderr, gettext("Can't open new shadow file\n"));
- return (0);
- }
-
- /* Copy the shadow vol */
- while ((i = fread(cp_buffer, sizeof (char), sizeof (cp_buffer), ishdfp))
- > 0) {
- if (fwrite(cp_buffer, sizeof (char), i, oshdfp) != i) {
- (void) fclose(ishdfp);
- (void) fclose(oshdfp);
- return (0);
- }
- }
- (void) fclose(ishdfp);
- (void) fclose(oshdfp);
- return (1);
-}
-
-int
-update_dscfg(char *new_shadow) {
-
- int len = strlen(new_shadow);
- /* get write lock */
- if (!cfg_lock(cfg, CFG_WRLOCK)) {
- spcs_log("ii", NULL,
- "iicpbmp CFG_WRLOCK failed, errno %d", errno);
- (void) fprintf(stderr, gettext("Error locking config\n"));
- return (0);
- }
- (void) sprintf(key, SHADOW_TOKEN, set_number);
- if (cfg_put_cstring(cfg, key, new_shadow, len) < 0) {
- perror("cfg_put_cstring");
- return (0);
- }
- (void) sprintf(key, SV_TOKEN, sv_number);
- if (cfg_put_cstring(cfg, key, new_shadow, len) < 0) {
- perror("cfg_put_cstring");
- return (0);
- }
- (void) sprintf(key, DSVOL_TOKEN, dsvol_number);
- if (cfg_put_cstring(cfg, key, new_shadow, len) < 0) {
- perror("cfg_put_cstring");
- return (0);
- }
- (void) cfg_commit(cfg);
- cfg_unlock(cfg);
- return (1);
-}
-
-void
-convert_to_blockdevice() {
- int len = strlen(real_bitmap);
- int i = 0, j = 0;
- char *temp_string = malloc(len-1);
- while (i < len + 1) {
- if (real_bitmap[i] != 'r') {
- temp_string[j] = real_bitmap[i];
- j++;
- }
- i++;
- }
- (void) strcpy(real_bitmap, temp_string);
- free(temp_string);
-}
diff --git a/usr/src/cmd/avs/errgen/Makefile b/usr/src/cmd/avs/errgen/Makefile
deleted file mode 100644
index afd5db1b7b..0000000000
--- a/usr/src/cmd/avs/errgen/Makefile
+++ /dev/null
@@ -1,55 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-DYNPROG= errgen
-
-include ../../Makefile.cmd
-include ../Makefile.com
-
-PROG= $(DYNPROG)
-
-OBJS= errgen.o
-
-CFLAGS += $(CCVERBOSE)
-CERRWARN += -_gcc=-Wno-switch
-LINTFLAGS += -erroff=E_SEC_SPRINTF_UNBOUNDED_COPY
-CLOBBERFILES += $(DYNPROG)
-
-.KEEP_STATE:
-
-.PARALLEL: $(OBJS)
-
-all: $(PROG)
-
-install: all
-
-lint: lint_PROG
-
-clean:
- $(RM) $(OBJS)
-
-$(PROG): $(OBJS)
- $(NATIVECC) $(CFLAGS) $(OBJS) -o $@
- $(POST_PROCESS)
-
-include ../../Makefile.targ
diff --git a/usr/src/cmd/avs/errgen/errgen.c b/usr/src/cmd/avs/errgen/errgen.c
deleted file mode 100644
index ea7eb756b6..0000000000
--- a/usr/src/cmd/avs/errgen/errgen.c
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * Read an errgen status resource file (*.err) from standard input and
- * write an SPCS error code C header file (-c), Java resource file (-j),
- * libspcs Java exception class file(-e), error text file (-m) or JNI
- * exception trinket table to standard output. Lines starting with "#"
- * are ignored.
- *
- * Use "errgen -h" to get usage info including module codes and example
- * input and output.
- */
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <libgen.h>
-#include <limits.h>
-#include <sys/param.h>
-
-/* The public error info header file. */
-
-#include <sys/unistat/spcs_s.h>
-
-/* The private error info header file */
-
-#include <sys/unistat/spcs_s_impl.h>
-
-
-/* locals */
-
-static enum {C_MODE, J_MODE, M_MODE, E_MODE, T_MODE, X_MODE} mode = E_MODE;
-static char key[SPCS_S_MAXKEY];
-static char text[SPCS_S_MAXTEXT];
-static int mod_number;
-
-static char help_path[PATH_MAX];
-
-static int count = 1;
-
-static char key[SPCS_S_MAXKEY];
-static char text[SPCS_S_MAXTEXT];
-static char modname[SPCS_S_MAXMODNAME];
-
-/*
- * Display help info
- */
-
-static void
-help()
-{
- char line[SPCS_S_MAXLINE];
- FILE *h = fopen(help_path, "r");
-
- if (h) {
- while (! feof(h)) {
- (void) fgets(line, SPCS_S_MAXLINE, h);
- if (! feof(h))
- (void) fputs(line, stderr);
- }
- } else {
- perror(strcat("could not open: ", help_path));
- exit(1);
- }
-}
-
-/*
- * Put out a message with terse instructions and err out
- */
-
-static void
-fatal(char *msg)
-{
- (void) fprintf(stderr, "%s\n\n", msg);
- (void) fprintf(stderr, "use errgen -h for help\n");
- exit(1);
-}
-
-/*
- * Put out the output file preamble
- */
-
-static void
-do_preamble()
-{
- switch (mode) {
- case M_MODE:
- (void) fprintf(stdout,
- "static\nchar *SPCS_MSG_%s[] = {\n", modname);
- (void) fprintf(stdout, "\t\"\",\n");
- break;
- case T_MODE:
- (void) fprintf(stdout,
- "static\nchar *SPCS_TRNK_%s[] = {\n", modname);
- (void) fprintf(stdout, "\t\"\",\n");
- break;
- }
-}
-
-/*
- * Put out the output file trailer
- */
-
-static void
-do_trailer()
-{
- switch (mode) {
- case M_MODE:
- (void) fprintf(stdout, "};\n");
- (void) fprintf(stdout,
- "#define\tSPCS_MSGLEN_%s %d\t/* total codes */\n",
- modname, count-1);
- break;
- case T_MODE:
- (void) fprintf(stdout, "};\n");
- (void) fprintf(stdout,
- "#define\tSPCS_TRNKLEN_%s %d\t/* total codes */\n",
- modname, count-1);
- break;
- }
-}
-
-/*
- * Process a single input line
- */
-
-static void
-do_line()
-{
- spcs_s_udata_t c;
- int fc = 0;
- int len = 0;
- char ptext[SPCS_S_MAXTEXT];
- char keystring[SPCS_S_MAXKEY+SPCS_S_MAXPRE];
- char *p = text;
- int tlen;
- char *pt = ptext;
- char havebytestream = 0;
-
- c.i = 0;
- (void) sprintf(keystring, "%s_E%s", modname, key);
- while (*p) {
- if (*p == '%') {
- if (*(p + 1) != 's') {
- (void) fprintf(stderr,
- "ERRGEN: Error in .err file\n");
- (void) fprintf(stderr,
- "%c is an illegal format spec after %%",
- *p);
- (void) fprintf(stderr,
- " at line: %d pos: %d\n", count,
- /* LINTED possible ptrdiff_t overflow */
- (int)(p - text));
- fatal("");
- }
- len = sprintf(pt, "{%d}", fc);
- pt += len;
- p++;
- fc += 1;
- if (fc > SPCS_S_MAXSUPP) {
- (void) fprintf(stderr,
- "ERRGEN: Error in .err file\n");
- (void) fprintf(stderr,
- "SPCS_S_MAXSUPP exceeeded\n");
- fatal("Too many %%s specifiers");
- }
- } else
- *pt++ = *p;
- p++;
- }
-
- /* look for a bytestream indicator */
-
- tlen = strlen(text);
-
- if ((tlen > 2) && (text[tlen - 1] == '@') && (text[tlen - 2] == '@')) {
- if (fc)
- fatal("ERRGEN: cannot have %%s and @@ ending too");
-
- /* bump the item count and set the bytestream flag */
- fc += 1;
- havebytestream = 1;
- }
-
- *pt = 0;
-
- switch (mode) {
- case C_MODE:
- c.f.bytestream = havebytestream;
- c.f.sup_count = fc;
- c.f.module = mod_number;
- c.f.code = count;
- (void) fprintf(stdout, "#define\t%s 0x%x /* %s */\n",
- keystring, c.i, text);
- break;
- case J_MODE:
- (void) fprintf(stdout, "`%s` = %s\n", keystring, ptext);
- break;
- case X_MODE:
- (void) fprintf(stdout,
- "#define\tT_%s \"`%s`\"\n", keystring, keystring);
- break;
- case T_MODE:
- (void) fprintf(stdout, "\t\"`%s`\",\n", keystring);
- break;
- case M_MODE:
- (void) fprintf(stdout, "\t\"%s\",\n", text);
- break;
- case E_MODE:
- (void) fprintf(stdout, " /**\n * %s\n **/\n",
- text);
- (void) fprintf(stdout, " public static final String %s",
- keystring);
- (void) fprintf(stdout, " = `%s`;\n\n", keystring);
- break;
- }
-}
-
-int
-main(int argc, char **argv)
-{
- int i;
- int searching = 1;
- char searchname[SPCS_S_MAXMODNAME];
- char line[SPCS_S_MAXLINE];
- char tline[SPCS_S_MAXLINE];
- char *p, *p2;
-
- (void) strcpy(help_path, dirname(argv[0]));
- (void) strcat(help_path, "/errgen.help");
- if ((argc == 1) || ((argc == 2) && (strcmp(argv[1], "-h") == 0))) {
- help();
- exit(0);
- }
-
- if (argc != 3)
- fatal("Bad number of arguments");
-
- p = argv[2];
- p2 = modname;
-
- while (*p)
- *p2++ = toupper(*p++);
- *p2 = 0;
-
- switch (argv[1][1]) {
- case 'c':
- mode = C_MODE;
- break;
- case 'j':
- mode = J_MODE;
- break;
- case 'e':
- mode = E_MODE;
- break;
- case 'm':
- mode = M_MODE;
- break;
- case 't':
- mode = T_MODE;
- break;
- case 'x':
- mode = X_MODE;
- break;
- default:
- fatal("Unknown option switch");
- }
-
- if (strcmp(modname, "DSW") == 0) {
- (void) strcpy(searchname, "II");
- } else if (strcmp(modname, "RDC") == 0) {
- (void) strcpy(searchname, "SNDR");
- } else if (strcmp(modname, "SDCTL") == 0) {
- (void) strcpy(searchname, "NSCTL");
- } else {
- (void) strcpy(searchname, modname);
- }
-
- i = 0;
- do {
- if (strcmp(module_names[i++], searchname) == 0) {
- searching = 0;
- mod_number = i - 1;
- break;
- }
- } while (module_names[i]);
-
- if (searching) {
- if (i != SPCS_M_MAX)
- (void) fprintf(stderr,
- "NULL in module_names before SPCS_M_MAX\n");
- fatal("Undefined module name");
- }
-
- do_preamble();
-
- while (!feof(stdin)) {
- (void) fgets(line, SPCS_S_MAXLINE, stdin);
- if (feof(stdin)) {
- if (count == 0)
- fatal("errgen file empty");
-
- do_trailer();
- exit(0);
- }
- line[strlen(line)-1] = 0;
- if ((strlen(line) != 0) && (line[0] != '#')) {
- (void) strcpy(tline, line);
- p = strchr(tline, ' ');
- if (p == NULL) {
- (void) fprintf(stderr,
- "blank separator missing at line: %d\n",
- count);
- fatal("");
- }
- *p = 0;
- if (strlen(p) > SPCS_S_MAXKEY) {
- (void) fprintf(stderr,
- "message label too long at line: %d\n", count);
- fatal("");
- }
- (void) strcpy(key, tline);
- if (strlen(key) == 0) {
- (void) fprintf(stderr,
- "leading blank at line: %d\n", count);
- fatal("");
- }
- p++;
- if (*p != '=') {
- (void) fprintf(stderr,
- "= separator missing at line: %d\n", count);
- fatal("");
- }
- p++;
- if (*p != ' ') {
- (void) fprintf(stderr,
- "blank separator missing at line: %d\n", count);
- fatal("");
- }
- p++;
- if (! *p) {
- (void) fprintf(stderr,
- "msg text missing at line:%d\n", count);
- fatal("");
- }
- (void) strcpy(text, p);
-
- do_line();
- count++;
- }
- }
-
- return (0);
-}
diff --git a/usr/src/cmd/avs/errgen/errgen.help.txt b/usr/src/cmd/avs/errgen/errgen.help.txt
deleted file mode 100644
index 33600d3bd1..0000000000
--- a/usr/src/cmd/avs/errgen/errgen.help.txt
+++ /dev/null
@@ -1,118 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-Usage: errgen [-c | -j | -e | -m | -t] <module_code>
-Options:
- -c Generate C header file
- -j Generate Java resource file
- -e Generate libspcs exception class body
- -m Generate error message text header file
- -t Genrate libspcs JNI exception trinket string table
- -x Genrate libspcs JNI exception trinket defines
-The module_code values are case insensitive:
-
- SPCS Storage Product Controller Software (general errors)
- DSW DataShadow Module
- SV Storage Volume Module
- RDC Remote Dual Copy Module
- SDBC Storage Device Block Cache Module
- STE SCSI Target Emulation Module
- SDCTL Storage Device Control Module
- MC Memory Channel Module
- SIMCKD CKD Simulation (SIMCKD) Module
-
-The format of the resource file is as follows:
-
-<message_key> = <message text>
-
-The message_key will become the #define or static final name of the message
-definition with a module error prefix. The message_text will become a
-inline comment depending on usage
-
-EXAMPLE resource input file. NOTE that only the %s format spec is supported
-for supplying supplemental data for ioctl status. If a line ends with "@@" it
-it indicates that a byte address and length will be supplied with the status
-code to provide arbitrary data for shipment to userspace (a "bytestream").
-Bytestreams are intended for asynchronous status output from coresw and are
-not supported for ioctl status.
-
-NOMINOR = No more minor numbers available
-ARRBOUNDS = Array bounds check exceeded %s size limit
-INTERNALDUMP = Internal state dump @@
-
-EXAMPLE C header file generated with "errgen -c SV":
-
-#define SV_ENOMINOR 0x00030001 /* No more minor numbers available */
-#define SV_EARRBOUNDS 0x01030002 /*Array bounds over %s size limit */
-#define SV_EINTERNALDUMP 0x09030003 /* Internal state dump */
-
-EXAMPLE Java resource file generated by "errgen -j SV":
-
-`SV_ENOMINOR` = No more minor numbers available
-`SV_EARRBOUNDS` = Array bounds check exceeded {0} size limit
-`SV_EINTERNALDUMP` = Internal state dump
-
-EXAMPLE libspcs exception class body generated by "errgen -e SV":
-
- /**
- * No more minor numbers available
- **/
- public static final String SV_ENOMINOR = `SV_ENOMINOR`;
-
- /**
- * Array bounds check exceeded %s size limit
- **/
- public static final String SV_EARRBOUND = `SV_EARRBOUND`;
-
- /**
- * Internal state dump
- **/
- public static final String SV_EINTERNALDUMP = `SV_EINTERNALDUMP`;
-
-EXAMPLE msg text data generated by "errgen -m SV":
-
- static char *SPCS_L_NTOM_SV[]={
- "",
- "No more minor numbers available",
- "Array bounds check exceeded %s size limit",
- "Internal State dump",
- };
- #define SPCS_M_CNT_SV 3 /* total codes */
-
-EXAMPLE libspcs JNI exception "trinket" table generated by "errgen -t SV":
-
- static char *SPCS_TRINKET_SV[]={
- "",
- "`SV_ENOMINOR`",
- "`SV_EARRBOUNDS`",
- "`SV_EINTERNALDUMP`",
- }
-
-EXAMPLE libspcs JNI exception "trinket" defines generated by "errgen -x SV":
-
-#define T_SV_ENOMINOR "`SV_ENOMINOR`"
-#define T_SV_EARRBOUNDS "`SV_EARRBOUNDS`"
-#define T_SV_EARRBOUNDS "`SV_EINTERNALDUMP`"
diff --git a/usr/src/cmd/avs/ncall/Makefile b/usr/src/cmd/avs/ncall/Makefile
deleted file mode 100644
index 30bffc0513..0000000000
--- a/usr/src/cmd/avs/ncall/Makefile
+++ /dev/null
@@ -1,84 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#
-
-DYNPROG = \
- ncalladm
-
-include ../../Makefile.cmd
-
-SUBDIRS=
-PROG= $(DYNPROG)
-
-ncalladm := POBJS = ncalladm.o
-
-OBJS= ncalladm.o
-SRCS= $(OBJS:%.o=%.c)
-POFILE= $(OBJS:%.o=%.po)
-
-LDLIBS += -ldscfg
-LINTFLAGS += -D_SYSCALL32 -D__NCALL__
-LINTFLAGS += -erroff=E_NAME_DEF_NOT_USED2
-LINTFLAGS += -erroff=E_SEC_PRINTF_VAR_FMT
-LINTFLAGS += -erroff=E_FUNC_RET_MAYBE_IGNORED2
-LINTFLAGS += -erroff=E_NAME_USED_NOT_DEF2
-LINTFLAGS += -erroff=E_BAD_FORMAT_ARG_TYPE2
-LINTFLAGS += -erroff=E_FUNC_RET_ALWAYS_IGNOR2
-LINTDIR = $(KBASE)/lintdir
-CFLAGS += $(CCVERBOSE) -D_SYSCALL32 -D__NCALL__
-CERRWARN += -_gcc=-Wno-uninitialized
-ROOTLINK = $(ROOTLIB)/$(PROG)
-
-all := TARGET= all
-install := TARGET= install
-clean := TARGET= clean
-clobber := TARGET= clobber
-lint := TARGET= lint
-
-.KEEP_STATE:
-
-.PARALLEL: $(OBJS)
-
-all: $(SUBDIRS)$(PROG) $(POFILE)
-
-install: $(SUBDIRS) all $(ROOTPROG) $(ROOTLINK)
-
-lint: $(SUBDIRS) lint_SRCS
-
-clean: $(SUBDIRS)
- $(RM) *.o $(POFILE)
-
-$(PROG): $$(POBJS)
- $(LINK.c) $(POBJS) -o $@ $(LDLIBS)
- $(POST_PROCESS)
-
-$(SUBDIRS): FRC
- @cd $@; pwd; $(MAKE) $(TARGET)
-
-$(ROOTLINK): $(ROOTLIB) $(ROOTPROG)
- -$(RM) $@; $(LN) $(ROOTPROG) $@
-
-FRC:
-
-include ../../Makefile.targ
diff --git a/usr/src/cmd/avs/ncall/ncalladm.c b/usr/src/cmd/avs/ncall/ncalladm.c
deleted file mode 100644
index 1214b39c1a..0000000000
--- a/usr/src/cmd/avs/ncall/ncalladm.c
+++ /dev/null
@@ -1,558 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <strings.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <stdio.h>
-#include <locale.h>
-#include <fcntl.h>
-#include <libgen.h>
-
-#include <sys/nsctl/cfg.h>
-#include <sys/ncall/ncall.h>
-
-static CFGFILE *cfg;
-static int cfg_changed;
-static char *progname;
-static ncall_node_t *getnodelist(int, int *, int *);
-
-
-static void
-usage(int exitstat)
-{
- (void) fprintf(stderr, gettext("usage:\n"));
- (void) fprintf(stderr, gettext(" %s -d\n"), progname);
- (void) fprintf(stderr, gettext(" %s -e\n"), progname);
- (void) fprintf(stderr, gettext(" %s -h\n"), progname);
-#ifdef DEBUG
- (void) fprintf(stderr, gettext(" %s -c [nodeid <nodeid>]\n"),
- progname);
- (void) fprintf(stderr, gettext(" %s -i\n"), progname);
- (void) fprintf(stderr, gettext(" %s -p <host>\n"), progname);
-#endif
-
- (void) fprintf(stderr, gettext("where:\n"));
- (void) fprintf(stderr, gettext(" -d disable ncall\n"));
- (void) fprintf(stderr, gettext(" -e enable ncall core\n"));
- (void) fprintf(stderr, gettext(" -h this help message\n"));
-#ifdef DEBUG
- (void) fprintf(stderr,
- gettext(" -c set or print ncall configuration\n"));
- (void) fprintf(stderr, gettext(" -i ncall information\n"));
- (void) fprintf(stderr, gettext(" -p ncall ping <host>\n"));
-#endif
-
- exit(exitstat);
-}
-
-
-static void
-ncall_cfg_open(CFGLOCK lk)
-{
- char hostid[32];
-
- if (cfg != NULL) {
- return;
- }
-
- if (snprintf(hostid, sizeof (hostid), "%lx", gethostid()) >=
- sizeof (hostid)) {
- (void) fprintf(stderr, gettext("%s: hostid %lx too large\n"),
- progname, gethostid());
- exit(1);
- }
-
- if ((cfg = cfg_open(NULL)) == NULL) {
- (void) fprintf(stderr,
- gettext("%s: unable to access the configuration: %s\n"),
- progname, cfg_error(NULL));
- exit(1);
- }
-
- if (!cfg_lock(cfg, lk)) {
- (void) fprintf(stderr,
- gettext("%s: unable to lock the configuration: %s\n"),
- progname, cfg_error(NULL));
- exit(1);
- }
-
- cfg_resource(cfg, hostid);
-}
-
-
-static void
-ncall_cfg_close(void)
-{
- if (cfg_changed && cfg_commit(cfg) < 0) {
- (void) fprintf(stderr,
- gettext("%s: unable to update the configuration: %s\n"),
- progname, cfg_error(NULL));
- exit(1);
- }
-
- cfg_close(cfg);
- cfg = NULL;
-}
-
-
-/*
- * Get config from dscfg.
- */
-static int
-get_nodeid_from_cfg(int *nodeid)
-{
- char buf[CFG_MAX_BUF];
- int ret = -1;
- int rc;
-
- ncall_cfg_open(CFG_RDLOCK);
-
- if (cfg_get_cstring(cfg, "ncallcore.set1", buf, sizeof (buf)) >= 0) {
- rc = sscanf(buf, "%d", nodeid);
- if (rc == 1) {
- ret = 0;
- }
- }
-
- ncall_cfg_close();
-
- return (ret);
-}
-
-
-static void
-ncall_print(void)
-{
- int cfnodeid, clnodeid, rc;
-
- clnodeid = cfg_issuncluster();
-
- rc = get_nodeid_from_cfg(&cfnodeid);
-
- if (rc < 0 && clnodeid > 0) {
- (void) printf(gettext("%s: ncall is using the SunCluster "
- "nodeid: %d\n"), progname, clnodeid);
- } else if (rc < 0) {
- (void) printf(gettext("%s: ncall is using the default "
- "nodeid: %d\n"), progname, 0);
- } else {
- (void) printf(gettext("%s: current configuration:\n"),
- progname);
- /* deliberately not i18n'd - "nodeid" is a keyword */
- (void) printf("nodeid %d\n", cfnodeid);
- }
-}
-
-
-static void
-ncall_config(const int nodeid)
-{
- char buf[CFG_MAX_BUF];
-
- ncall_cfg_open(CFG_WRLOCK);
-
- if (cfg_get_cstring(cfg, "ncallcore.set1", buf, sizeof (buf)) >= 0) {
- /* remove old config */
- if (cfg_put_cstring(cfg, "ncallcore.set1", NULL, 0) < 0) {
- (void) fprintf(stderr,
- gettext("%s: unable to update the configuration: "
- "%s\n"), cfg_error(NULL));
- exit(1);
- }
- }
-
- if (snprintf(buf, sizeof (buf), "%d", nodeid) >= sizeof (buf)) {
- (void) fprintf(stderr,
- gettext("%s: unable to update configuration: "
- "data too long\n"), progname);
- exit(1);
- }
-
- if (cfg_put_cstring(cfg, "ncallcore", buf, sizeof (buf)) < 0) {
- (void) fprintf(stderr,
- gettext("%s: unable to update the configuration: %s\n"),
- cfg_error(NULL));
- exit(1);
- }
-
- cfg_changed = 1;
- ncall_cfg_close();
-
- (void) printf(gettext("%s: configuration set to:\n"), progname);
- /* deliberately not i18n'd - "nodeid" is a keyword */
- (void) printf("nodeid %d\n", nodeid);
-}
-
-#ifdef lint
-int
-ncalladm_lintmain(int argc, char *argv[])
-#else
-int
-main(int argc, char *argv[])
-#endif
-{
- const char *dev = "/dev/ncall";
- extern int optind, opterr;
- ncall_node_t nodeinfo, *nodes;
- int nsize;
- int i;
- int cflag, dflag, eflag, iflag, pflag;
- int rc, fd, opt;
- int clnodeid, cfnodeid;
- int up;
- char *cp, *ping;
- int mnode; /* mirror nodeid */
-
- (void) setlocale(LC_ALL, "");
- (void) textdomain("ncalladm");
-
- opterr = 0;
- cflag = dflag = eflag = iflag = pflag = 0;
- ping = NULL;
-
- progname = basename(argv[0]);
-
- while ((opt = getopt(argc, argv,
-#ifdef DEBUG
- "cip:"
-#endif
- "deh")) != -1) {
- switch (opt) {
- case 'c':
- cflag = 1;
- break;
-
- case 'd':
- dflag = 1;
- break;
-
- case 'e':
- eflag = 1;
- break;
-
- case 'h':
- usage(0);
- break;
-
- case 'i':
- iflag = 1;
- break;
-
- case 'p':
- ping = optarg;
- pflag = 1;
- break;
-
- default:
- (void) fprintf(stderr, gettext("%s: unknown option\n"),
- progname);
- usage(1);
- break;
- }
- }
-
- if (!(cflag || dflag || eflag || iflag || pflag)) {
- usage(1);
- }
-
- if (argc != optind) {
- if (!cflag ||
- (argc - optind) != 2 ||
- strcmp(argv[optind], "nodeid") != 0) {
- usage(1);
- }
- }
-
- if ((cflag + dflag + eflag + iflag + pflag) > 1) {
- (void) fprintf(stderr,
- gettext("%s: multiple options are not supported\n"),
- progname);
- usage(1);
- }
-
- if (!cflag) {
- fd = open(dev, O_RDONLY);
- if (fd < 0) {
- (void) fprintf(stderr,
- gettext("%s: unable to open %s: %s\n"),
- progname, dev, strerror(errno));
- exit(1);
- }
- }
-
- if (dflag) {
- /* ioctl stop into kernel */
- if (ioctl(fd, NC_IOC_STOP, 0) < 0) {
- (void) fprintf(stderr,
- gettext("%s: unable to disable ncall: %s\n"),
- progname, strerror(errno));
- exit(1);
- }
- } else if (eflag) {
- bzero(&nodeinfo, sizeof (nodeinfo));
-
- clnodeid = cfg_issuncluster();
- cfnodeid = 0;
-
- /* get node info */
- rc = gethostname(nodeinfo.nc_nodename,
- sizeof (nodeinfo.nc_nodename));
- if (rc < 0) {
- (void) fprintf(stderr,
- gettext("%s: unable to determine hostname: %s\n"),
- progname, strerror(errno));
- exit(1);
- }
-
- rc = get_nodeid_from_cfg(&cfnodeid);
-
- if (clnodeid > 0 && rc == 0) {
- /*
- * check that the nodeids from the cf file and
- * cluster match.
- */
- if (clnodeid != cfnodeid) {
- (void) fprintf(stderr,
- gettext("%s: nodeid from configuration "
- "(%d) != cluster nodeid (%d)\n"),
- progname, cfnodeid, clnodeid);
- exit(1);
- }
- }
-
- if (rc == 0) {
- nodeinfo.nc_nodeid = cfnodeid;
- } else if (clnodeid > 0) {
- nodeinfo.nc_nodeid = clnodeid;
- } else {
- nodeinfo.nc_nodeid = 0;
- }
-
- /* ioctl node info into kernel and start ncall */
- rc = ioctl(fd, NC_IOC_START, &nodeinfo);
- if (rc < 0) {
- (void) fprintf(stderr,
- gettext("%s: unable to enable ncall: %s\n"),
- progname, strerror(errno));
- exit(1);
- }
- }
-
- if (iflag || pflag) {
- nodes = getnodelist(fd, &nsize, &mnode);
-
- if (nodes == NULL) {
- (void) fprintf(stderr,
- gettext("%s: unable to get node info\n"),
- progname);
- exit(1);
- }
- }
-
- if (iflag) {
- char *mname;
- char *pnodestr;
-
- (void) printf(gettext("Self Node Name: %s\n"),
- nodes[0].nc_nodename);
- (void) printf(gettext("Self Node ID: %d\n"),
- nodes[0].nc_nodeid);
- /*
- * determine which slot is the mirror node.
- */
- if (mnode != -1) {
- for (i = 1; i < nsize; i++) {
- if (nodes[i].nc_nodeid == mnode) {
- mname = nodes[i].nc_nodename;
- break;
- }
- }
- }
- if ((mnode == -1) || (i >= nsize)) {
- mname = gettext("unknown");
- mnode = -1;
- }
-
- (void) printf(gettext("Mirror Node Name: %s\n"), mname);
- (void) printf(gettext("Mirror Node ID: %d\n"), mnode);
- /*
- * See if we need to translate the node strings.
- */
- if (nsize > 1) {
- pnodestr = gettext("Node Name: %s\nNode ID: %d\n");
- for (i = 1; i < nsize; i++) {
- /*
- * Don't print the mirror twice.
- */
- if (nodes[i].nc_nodeid != mnode) {
- (void) printf(pnodestr,
- nodes[i].nc_nodename,
- nodes[i].nc_nodeid);
- }
- }
- }
- }
-
- if (pflag) {
- if (strlen(ping) >= sizeof (nodeinfo.nc_nodename)) {
- (void) fprintf(stderr,
- gettext("%s: hostname '%s' is too long\n"),
- progname, ping);
- exit(1);
- }
- up = 0;
- if (strcmp(nodes[0].nc_nodename, ping) == 0) {
- up = 1; /* self */
- } else {
- /* not self, so ask kernel */
- bzero(&nodeinfo, sizeof (nodeinfo));
- /* strlen(ping) checked above */
- (void) strcpy(nodeinfo.nc_nodename, ping);
- up = ioctl(fd, NC_IOC_PING, nodeinfo);
- }
-
- /* model the ping messages on ping(1m) */
-
- if (up < 0) {
- (void) fprintf(stderr,
- gettext("%s: unable to ping host '%s': %s\n"),
- progname, ping, strerror(errno));
- exit(1);
- } else if (up > 0) {
- (void) printf(gettext("%s is alive\n"), ping);
- } else {
- (void) printf(gettext("no answer from %s\n"), ping);
- exit(1);
- }
- }
-
- if (iflag || pflag) {
- free(nodes);
- }
-
- if (cflag) {
- if (argc == optind) {
- ncall_print();
- return (0);
- }
-
- cp = NULL;
- cfnodeid = (int)strtol(argv[optind+1], &cp, 0);
- if (cp != NULL && *cp != '\0') {
- (void) fprintf(stderr,
- gettext("%s: nodeid \"%s\" is not an "
- "integer number\n"), progname, argv[optind+1]);
- exit(1);
- }
-
- clnodeid = cfg_issuncluster();
- if (clnodeid > 0 && cfnodeid != clnodeid) {
- (void) fprintf(stderr,
- gettext("%s: nodeid from command line "
- "(%d) != cluster nodeid (%d)\n"),
- progname, cfnodeid, clnodeid);
- exit(1);
- }
-
- ncall_config(cfnodeid);
- }
-
- if (!cflag) {
- (void) close(fd);
- }
-
- return (0);
-}
-
-
-/*
- * return a pointer to a list of currently configured
- * nodes.
- * Return the number of nodes via the nodesizep pointer.
- * Return the mirror nodeid via the mirrorp pointer.
- * Return NULL on errors.
- */
-static ncall_node_t *
-getnodelist(int ifd, int *nodesizep, int *mirrorp)
-{
- int maxsize;
- int cnt;
- ncall_node_t *noderet = NULL;
- ncall_node_t *nodelist;
- ncall_node_t thisnode;
- int mirror;
- int nonet;
-
- /*
- * Get this host info and mirror nodeid.
- */
- mirror = ioctl(ifd, NC_IOC_GETNODE, &thisnode);
-
- if (mirror < 0) {
- return (NULL);
- }
-
- /*
- * See if we need to allocate the buffer.
- */
- nonet = 0;
- maxsize = ioctl(ifd, NC_IOC_GETNETNODES, 0);
- if (maxsize < 1) {
- maxsize = 1;
- nonet = 1;
- }
- nodelist = malloc(sizeof (*nodelist) * maxsize);
- if (nodelist) {
- if (nonet == 0) {
- /*
- * fetch the node data.
- */
- cnt = ioctl(ifd, NC_IOC_GETNETNODES, nodelist);
- if (cnt > 0) {
- *nodesizep = cnt;
- noderet = nodelist;
- *mirrorp = mirror;
- } else {
- *nodesizep = 0;
- free(nodelist);
- }
- } else {
- (void) memcpy(nodelist, &thisnode, sizeof (*nodelist));
- *nodesizep = 1;
- noderet = nodelist;
- /*
- * Although we know the mirror nodeid, there
- * is no point in returning it as we have
- * no information about any other hosts.
- */
- *mirrorp = -1;
- }
- }
- return (noderet);
-}
diff --git a/usr/src/cmd/avs/nsctl/Makefile b/usr/src/cmd/avs/nsctl/Makefile
deleted file mode 100644
index f5b19dc7b2..0000000000
--- a/usr/src/cmd/avs/nsctl/Makefile
+++ /dev/null
@@ -1,87 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-# must be before include of Makefile.cmd
-DYNPROG = nscadm nskernd
-
-include ../../Makefile.cmd
-include ../Makefile.com
-
-PROG = $(DYNPROG)
-
-OBJS= nscadm.o nskernd.o
-SRCS= $(OBJS:%.o=%.c)
-POFILES= $(OBJS:%.o=%.po)
-
-nscadm := POBJS = nscadm.o
-nskernd := POBJS = nskernd.o
-
-CFLAGS += -v
-CPPFLAGS += -DBUILD_REV_STR='"5.11"'
-NSCADM_LDLIBS = -lnsctl
-NSKERND_LDLIBS = -lnsctl -ldscfg
-LINTFLAGS += -Xa -n -s -x -m -u -Dlint -errhdr=%user -DDEBUG
-LINTDIR = $(KBASE)/lintdir
-POFILE = nsctl_all.po
-LFILE = $(LINTDIR)/nsctl.ln
-ROOTLIBLINK = $(ROOTLIB)/nskernd
-ROOTSBINLINK = $(ROOTUSRSBIN)/nscadm
-
-all := TARGET= all
-install := TARGET= install
-clean := TARGET= clean
-clobber := TARGET= clobber
-lint := TARGET= lint
-
-nscadm := LDLIBS += $(NSCADM_LDLIBS)
-nskernd := LDLIBS += $(NSKERND_LDLIBS)
-
-.KEEP_STATE:
-
-.PARALLEL: $(OBJS)
-
-all: $(PROG) $(POFILES)
-
-install: all $(ROOTPROG) $(ROOTBIN)/nskernd $(ROOTLIBLINK) $(ROOTSBINLINK)
-
-lint: lint_SRCS
-
-clean:
- $(RM) *.o $(POFILES)
-
-$(PROG): $$(POBJS)
- $(LINK.c) $(POBJS) -o $@ $(LDLIBS)
- $(POST_PROCESS)
-
-$(POFILE): $(POFILES)
- $(RM) $@
- $(CAT) $(POFILES) > $@
-
-$(ROOTLIBLINK): $(ROOTLIB) $(ROOTBIN)/nskernd
- -$(RM) $@; $(LN) $(ROOTBIN)/nskernd $@
-
-$(ROOTSBINLINK): $(ROOTUSRSBIN) $(ROOTPROG)
- -$(RM) $@; $(LN) $(ROOTBIN)/nscadm $@
-
-include ../../Makefile.targ
diff --git a/usr/src/cmd/avs/nsctl/nscadm.c b/usr/src/cmd/avs/nsctl/nscadm.c
deleted file mode 100644
index 5096dd5b73..0000000000
--- a/usr/src/cmd/avs/nsctl/nscadm.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <strings.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <stdio.h>
-#include <locale.h>
-
-#include <nsctl.h>
-#define __NSC_GEN__
-#include <sys/nsctl/nsc_gen.h>
-#include <sys/nsctl/nsc_mem.h>
-
-
-/*
- * Private functions from libsd.
- */
-extern int nsc_nvclean(int);
-extern int nsc_gmem_data(char *);
-extern int nsc_gmem_sizes(int *);
-
-/*
- * Local functions.
- */
-static int _nsc_gmem(void);
-static void show_maps(char *, int);
-
-
-static void
-usage(void)
-{
- (void) fprintf(stderr, gettext("usage: nscadm [-h] command\n"));
- (void) fprintf(stderr, gettext("valid commands:\n"));
- (void) fprintf(stderr, gettext(" freeze <device>\n"));
- (void) fprintf(stderr, gettext(" unfreeze <device>\n"));
- (void) fprintf(stderr, gettext(" isfrozen <device>\n"));
-}
-
-static void
-is_chr_dev(char *dev, char *op)
-{
- struct stat sbuf;
- if (stat(dev, &sbuf) < 0) {
- (void) fprintf(stderr, gettext("nscadm: "));
- perror(op);
- exit(255);
- }
- if (!S_ISCHR(sbuf.st_mode)) {
- (void) fprintf(stderr, gettext("nscadm: %s: not a valid device "
- "<%s>\n"), op, dev);
- exit(255);
- }
-}
-
-int
-main(int argc, char *argv[])
-{
- extern int optind, opterr;
- int opt, rc;
-
- (void) setlocale(LC_ALL, "");
- (void) textdomain("nscadm");
-
- rc = 0;
- opterr = 0;
-
- while ((opt = getopt(argc, argv, "h")) != -1) {
- switch (opt) {
- case 'h':
- usage();
- exit(0);
- break;
- default:
- usage();
- exit(255);
- break;
- }
- }
-
- if (optind == argc) {
- usage();
- exit(255);
- }
-
- if (strcoll(argv[optind], gettext("freeze")) == 0 ||
- strcmp(argv[optind], "freeze") == 0) {
- if (argc - optind != 2) {
- usage();
- exit(255);
- }
-
- is_chr_dev(argv[optind+1], "freeze");
- rc = nsc_isfrozen(argv[optind+1]);
- if (rc < 0) {
- perror(gettext("nscadm: freeze"));
- exit(255);
- } else if (rc != 0) {
- rc = nsc_freeze(argv[optind+1]);
- if (rc < 0) {
- perror(gettext("nscadm: freeze"));
- exit(255);
- }
- } else {
- (void) fprintf(stderr, gettext("nscadm: device <%s> is "
- "already frozen\n"), argv[optind+1]);
- exit(255);
- }
-
- (void) printf(gettext("nscadm: device <%s> frozen\n"),
- argv[optind+1]);
- } else if (strcoll(argv[optind], gettext("unfreeze")) == 0 ||
- strcmp(argv[optind], "unfreeze") == 0) {
- if (argc - optind != 2) {
- usage();
- exit(255);
- }
-
- is_chr_dev(argv[optind+1], "unfreeze");
- rc = nsc_isfrozen(argv[optind+1]);
- if (rc < 0) {
- perror(gettext("nscadm: unfreeze"));
- exit(255);
- } else if (rc == 0) {
- rc = nsc_unfreeze(argv[optind+1]);
- if (rc < 0) {
- perror(gettext("nscadm: unfreeze"));
- exit(255);
- }
- } else {
- (void) fprintf(stderr,
- gettext("nscadm: device <%s> is not "
- "frozen\n"), argv[optind+1]);
- exit(255);
- }
-
- (void) printf(gettext("nscadm: device <%s> unfrozen\n"),
- argv[optind+1]);
- } else if (strcoll(argv[optind], gettext("isfrozen")) == 0 ||
- strcmp(argv[optind], "isfrozen") == 0) {
- if (argc - optind != 2) {
- usage();
- exit(255);
- }
-
- is_chr_dev(argv[optind+1], "isfrozen");
- rc = nsc_isfrozen(argv[optind+1]);
- if (rc < 0) {
- perror(gettext("nscadm: isfrozen"));
- exit(255);
- }
-
- (void) printf(gettext("nscadm: device <%s> is %sfrozen\n"),
- argv[optind+1], rc ? gettext("not ") : "");
-#ifdef DEBUG
- } else if (strcoll(argv[optind], gettext("nvclean")) == 0 ||
- strcmp(argv[optind], "nvclean") == 0) {
- rc = nsc_nvclean(0);
- if (rc < 0) {
- perror(gettext("nscadm: nvclean"));
- exit(255);
- }
- } else if (strcoll(argv[optind], gettext("nvclean_force")) == 0 ||
- strcmp(argv[optind], "nvclean_force") == 0) {
- rc = nsc_nvclean(1);
- if (rc < 0) {
- perror(gettext("nscadm: nvclean_force"));
- exit(255);
- }
-#endif /* DEBUG */
- } else if (strcoll(argv[optind], gettext("gmem")) == 0 ||
- strcmp(argv[optind], "gmem") == 0) {
- rc = _nsc_gmem();
- if (rc < 0) {
- perror(gettext("nscadm: gmem"));
- exit(255);
- }
- } else {
- usage();
- exit(255);
- }
-
- return (rc);
-}
-
-
-static int
-_nsc_gmem(void)
-{
- char *addr;
- int size;
- int rc = 0;
-
- rc = nsc_gmem_sizes(&size);
-
- if (rc < 0)
- return (rc);
-
- (void) printf(gettext("size %d\n"), size);
-
- if ((addr = (char *)malloc(size * 2)) == NULL) {
- errno = ENOMEM;
- return (-1);
- }
-
- rc = nsc_gmem_data(addr);
-
- if (rc < 0) {
- free(addr);
- return (rc);
- }
-
- (void) printf(gettext("Global map entries:\n"));
- show_maps(addr, size);
-
- (void) printf(gettext("\nGlobal NVMEM map entries:\n"));
- show_maps(addr + size, size);
-
- free(addr);
- return (0);
-}
-
-
-static void
-show_maps(char *addr, int len)
-{
- /* LINTED alignment of cast ok */
- nsc_rmhdr_t *rhp = (nsc_rmhdr_t *)addr;
- nsc_rmmap_t *rmap;
- char tname[_NSC_MAXNAME + 1];
- int i;
-
- (void) printf(
- gettext("magic 0x%x ver %d size %d dirty (nvmem systems): %d\n"),
- rhp->magic, rhp->ver, rhp->size, rhp->rh_dirty);
-
- for (i = 0, rmap = rhp->map;
- /* LINTED alignment of cast ok */
- rmap < (nsc_rmmap_t *)(addr + len); ++i, ++rmap) {
- if (!rmap->name[0])
- continue;
- (void) strncpy(tname, rmap->name, _NSC_MAXNAME);
- (void) strcpy(&tname[strlen(tname)], " ");
- tname[_NSC_MAXNAME] = '\0';
- (void) printf(gettext(
- "%d:\tname %s\toffset 0x%x size 0x%x inuse 0x%x\n"),
- i, tname, rmap->offset, rmap->size, rmap->inuse);
- }
-}
diff --git a/usr/src/cmd/avs/nsctl/nskernd.c b/usr/src/cmd/avs/nsctl/nskernd.c
deleted file mode 100644
index 1a205979d5..0000000000
--- a/usr/src/cmd/avs/nsctl/nskernd.c
+++ /dev/null
@@ -1,1000 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/resource.h>
-#include <sys/priocntl.h>
-#include <sys/rtpriocntl.h>
-#include <sys/tspriocntl.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-
-#include <strings.h>
-#include <thread.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <errno.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <locale.h>
-#include <unistd.h>
-#include <syslog.h>
-
-#include <sys/nsctl/cfg.h>
-#include <sys/nsctl/nsctl.h>
-#include <sys/nsctl/nsc_ioctl.h>
-#include <sys/nskernd.h>
-#include <nsctl.h>
-
-#include <sys/mkdev.h>
-#include <sys/nsctl/sv_efi.h>
-
-static const char *rdev = "/dev/nsctl";
-
-/*
- * Define a minimal user stack size in bytes over and above the
- * libthread THR_STACK_MIN minimum value.
- *
- * This stack size needs to be sufficient to run _newlwp() and then
- * ioctl() down into the kernel.
- */
-#define NSK_STACK_SIZE 512
-
-/*
- * LWP scheduling control switches.
- *
- * allow_pri - set to non-zero to enable priocntl() manipulations of
- * created LWPs.
- * allow_rt - set to non-zero to use the RT rather than the TS
- * scheduling class when manipulating the schduling
- * parameters for an LWP. Only used if allow_pri is
- * non-zero.
- */
-static int allow_pri = 1;
-static int allow_rt = 0; /* disallow - bad interactions with timeout() */
-
-static int nsctl_fd = -1;
-static int sigterm;
-
-static int nthreads; /* number of threads in the kernel */
-static int exiting; /* shutdown in progress flag */
-static mutex_t thr_mutex = DEFAULTMUTEX;
-static mutex_t cfg_mutex = DEFAULTMUTEX;
-
-static int cl_nodeid = -1;
-
-static int display_msg = 0;
-static int delay_time = 30;
-
-static void
-usage(void)
-{
- (void) fprintf(stderr, gettext("usage: nskernd\n"));
- exit(255);
-}
-
-
-static void
-sighand(int sig)
-{
- if (sig == SIGTERM) {
- sigterm++;
- }
-}
-
-
-/*
- * Returns: 1 - can enter kernel; 0 - shutdown in progress, do not enter kernel
- */
-int
-nthread_inc(void)
-{
- (void) mutex_lock(&thr_mutex);
- if (exiting) {
- /* cannot enter kernel as nskernd is being shutdown - exit */
- (void) mutex_unlock(&thr_mutex);
- return (0);
- }
- nthreads++;
- (void) mutex_unlock(&thr_mutex);
- return (1);
-}
-
-
-void
-nthread_dec(void)
-{
- (void) mutex_lock(&thr_mutex);
- nthreads--;
- (void) mutex_unlock(&thr_mutex);
-}
-
-
-/*
- * returns: 1 - can shutdown; 0 - unable to shutdown
- */
-int
-canshutdown(void)
-{
- int rc = 1;
- time_t start_delay;
-
- (void) mutex_lock(&thr_mutex);
- if (nthreads > 0) {
- if (display_msg) {
- (void) fprintf(stderr,
- gettext("nskernd: unable to shutdown: "
- "%d kernel threads in use\n"), nthreads);
- }
- start_delay = time(0);
- while (nthreads > 0 && (time(0) - start_delay) < delay_time) {
- (void) mutex_unlock(&thr_mutex);
- (void) sleep(1);
- (void) mutex_lock(&thr_mutex);
- (void) fprintf(stderr,
- gettext("nskernd: delay shutdown: "
- "%d kernel threads in use\n"), nthreads);
- }
- if (nthreads > 0) {
- rc = 0;
- } else {
- exiting = 1;
- }
- } else {
- /* flag shutdown in progress */
- exiting = 1;
- }
- (void) mutex_unlock(&thr_mutex);
-
- return (rc);
-}
-
-
-/*
- * returns: 1 - shutdown successful; 0 - unable to shutdown
- */
-int
-shutdown(void)
-{
- struct nskernd data;
- int rc;
-
- if (nsctl_fd < 0)
- return (1);
-
- bzero(&data, sizeof (data));
- data.command = NSKERND_STOP;
-
- if (!canshutdown()) {
- return (0);
- }
-
- rc = ioctl(nsctl_fd, NSCIOC_NSKERND, &data);
- if (rc < 0) {
- if (errno != EINTR || !sigterm) {
- (void) fprintf(stderr,
- gettext("nskernd: NSKERND_STOP failed\n"));
- }
- }
-
- return (1);
-}
-
-
-/*
- * First function run by a NSKERND_NEWLWP thread.
- *
- * Determines if it needs to change the scheduling priority of the LWP,
- * and then calls back into the kernel.
- */
-static void *
-_newlwp(void *arg)
-{
- struct nskernd nsk;
- pcparms_t pcparms;
- pcinfo_t pcinfo;
-
- /* copy arguments onto stack and free heap memory */
- bcopy(arg, &nsk, sizeof (nsk));
- free(arg);
-
- if (nsk.data2 && allow_pri) {
- /* increase the scheduling priority of this LWP */
-
- bzero(&pcinfo, sizeof (pcinfo));
- (void) strcpy(pcinfo.pc_clname, allow_rt ? "RT" : "TS");
-
- if (priocntl(0, 0, PC_GETCID, (char *)&pcinfo) < 0) {
- (void) fprintf(stderr,
- gettext(
- "nskernd: priocntl(PC_GETCID) failed: %s\n"),
- strerror(errno));
- goto pri_done;
- }
-
- bzero(&pcparms, sizeof (pcparms));
- pcparms.pc_cid = pcinfo.pc_cid;
-
- if (allow_rt) {
- ((rtparms_t *)pcparms.pc_clparms)->rt_pri =
- (pri_t)0; /* minimum RT priority */
- ((rtparms_t *)pcparms.pc_clparms)->rt_tqsecs =
- (uint_t)RT_TQDEF;
- ((rtparms_t *)pcparms.pc_clparms)->rt_tqnsecs =
- RT_TQDEF;
- } else {
- ((tsparms_t *)pcparms.pc_clparms)->ts_uprilim =
- ((tsinfo_t *)&pcinfo.pc_clinfo)->ts_maxupri;
- ((tsparms_t *)pcparms.pc_clparms)->ts_upri =
- ((tsinfo_t *)&pcinfo.pc_clinfo)->ts_maxupri;
- }
-
- if (priocntl(P_LWPID, P_MYID,
- PC_SETPARMS, (char *)&pcparms) < 0) {
- (void) fprintf(stderr,
- gettext(
- "nskernd: priocntl(PC_SETPARMS) failed: %s\n"),
- strerror(errno));
- }
- }
-
-pri_done:
- if (nthread_inc()) {
- (void) ioctl(nsctl_fd, NSCIOC_NSKERND, &nsk);
- nthread_dec();
- }
- return (NULL);
-}
-
-
-/*
- * Start a new thread bound to an LWP.
- *
- * This is the user level side of nsc_create_process().
- */
-static void
-newlwp(struct nskernd *req)
-{
- struct nskernd *nskp;
- thread_t tid;
- int rc;
-
- nskp = malloc(sizeof (*nskp));
- if (!nskp) {
-#ifdef DEBUG
- (void) fprintf(stderr, gettext("nskernd: malloc(%d) failed\n"),
- sizeof (*nskp));
-#endif
- req->data1 = (uint64_t)ENOMEM;
- return;
- }
-
- /* copy args for child */
- bcopy(req, nskp, sizeof (*nskp));
-
- rc = thr_create(NULL, (THR_MIN_STACK + NSK_STACK_SIZE),
- _newlwp, nskp, THR_BOUND|THR_DETACHED, &tid);
-
- if (rc != 0) {
- /* thr_create failed */
-#ifdef DEBUG
- (void) fprintf(stderr,
- gettext("nskernd: thr_create failed: %s\n"),
- strerror(errno));
-#endif
- req->data1 = (uint64_t)errno;
- free(nskp);
- } else {
- /* success - _newlwp() will free nskp */
- req->data1 = (uint64_t)0;
- }
-}
-
-static int
-log_iibmp_err(char *set, int flags)
-{
- CFGFILE *cfg;
- char key[CFG_MAX_KEY];
- char buf[CFG_MAX_BUF];
- char newflags[CFG_MAX_BUF];
- char outbuf[CFG_MAX_BUF];
- char *mst, *shd, *bmp, *mode, *ovr, *cnode, *opt, *grp;
- int setno, found = 0;
- int setlen;
- int rc = 0;
- pid_t pid = -1;
-
- if (set && *set) {
- setlen = strlen(set);
- } else {
- return (EINVAL);
- }
-
- (void) mutex_lock(&cfg_mutex);
- cfg = cfg_open("");
- if (!cfg) {
- (void) mutex_unlock(&cfg_mutex);
- return (ENXIO);
- }
-
- if (!cfg_lock(cfg, CFG_WRLOCK)) {
-
- (void) mutex_unlock(&cfg_mutex);
- cfg_close(cfg);
-
- pid = fork();
-
- if (pid == -1) {
- (void) fprintf(stderr, gettext(
- "nskernd: Error forking\n"));
- return (errno);
- } else if (pid > 0) {
- (void) fprintf(stdout, gettext(
- "nskernd: Attempting deferred bitmap error\n"));
- return (0);
- }
-
- (void) mutex_lock(&cfg_mutex);
- cfg = cfg_open("");
- if (!cfg) {
- (void) mutex_unlock(&cfg_mutex);
- (void) fprintf(stderr, gettext(
- "nskernd: Failed cfg_open, deferred bitmap\n"));
- return (ENXIO);
- }
-
- /* Sooner or later, this lock will be free */
- while (!cfg_lock(cfg, CFG_WRLOCK))
- (void) sleep(2);
- }
-
- /* find the proper set number */
- for (setno = 1; !found; setno++) {
- (void) snprintf(key, CFG_MAX_KEY, "ii.set%d", setno);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) {
- break;
- }
-
- mst = strtok(buf, " ");
- shd = strtok(NULL, " ");
- if (strncmp(shd, set, setlen) == 0) {
- found = 1;
-
- bmp = strtok(NULL, " ");
- mode = strtok(NULL, " ");
- ovr = strtok(NULL, " ");
- cnode = strtok(NULL, " ");
- opt = strtok(NULL, " ");
- grp = strtok(NULL, " ");
- break;
- }
- }
-
- if (found) {
- /* were there flags in the options field already? */
- (void) snprintf(newflags, CFG_MAX_BUF, "%s=0x%x",
- NSKERN_II_BMP_OPTION, flags);
- if (opt && strcmp(opt, "-") != 0) {
- bzero(newflags, CFG_MAX_BUF);
- opt = strtok(opt, ";");
- while (opt) {
- if (strncmp(opt, NSKERN_II_BMP_OPTION,
- strlen(NSKERN_II_BMP_OPTION)) != 0) {
- (void) strcat(newflags, ";");
- (void) strcat(newflags, opt);
- }
- }
- }
- (void) snprintf(key, CFG_MAX_KEY, "ii.set%d", setno);
- (void) snprintf(outbuf, CFG_MAX_BUF, "%s %s %s %s %s %s %s %s",
- mst, shd, bmp, mode, ovr, cnode, newflags, grp);
- if (cfg_put_cstring(cfg, key, outbuf, CFG_MAX_BUF) < 0) {
- (void) printf("Failed to put [%s]\n", outbuf);
- rc = ENXIO;
- } else {
- (void) cfg_commit(cfg);
- rc = 0;
- }
- } else {
- (void) fprintf(stderr, gettext(
- "nskernd: Failed deferred bitmap [%s]\n"), set);
- rc = EINVAL;
- }
- cfg_unlock(cfg);
- cfg_close(cfg);
- (void) mutex_unlock(&cfg_mutex);
-
- /*
- * if we are the fork'ed client, just exit, if parent just return
- */
- if (pid == 0) {
- exit(rc);
- /*NOTREACHED*/
- } else {
- return (rc);
- }
-}
-
-/*
- * First function run by a NSKERND_LOCK thread.
- *
- * Opens dscfg and locks it,
- * and then calls back into the kernel.
- *
- * Incoming:
- * data1 is the kernel address of the sync structure.
- * data2 is read(0)/write(1) lock mode.
- *
- * Returns:
- * data1 as incoming.
- * data2 errno.
- */
-static void *
-_dolock(void *arg)
-{
- struct nskernd nsk;
- CFGFILE *cfg;
- int locked;
- int mode;
- int rc = 0;
-
- /* copy arguments onto stack and free heap memory */
- bcopy(arg, &nsk, sizeof (nsk));
- free(arg);
-
- (void) mutex_lock(&cfg_mutex);
- cfg = cfg_open("");
- if (cfg == NULL) {
-#ifdef DEBUG
- (void) fprintf(stderr,
- gettext("nskernd: cfg_open failed: %s\n"),
- strerror(errno));
-#endif
- rc = ENXIO;
- }
-
- if (nsk.data2 == 0) {
- mode = CFG_RDLOCK;
- } else {
- mode = CFG_WRLOCK;
- }
-
- locked = 0;
- if (rc == 0) {
- if (cfg_lock(cfg, mode)) {
- locked = 1;
- } else {
-#ifdef DEBUG
- (void) fprintf(stderr,
- gettext("nskernd: cfg_lock failed: %s\n"),
- strerror(errno));
-#endif
- rc = EINVAL;
- }
- }
-
- /* return to kernel */
-
- nsk.data2 = (uint64_t)rc;
- if (nthread_inc()) {
- (void) ioctl(nsctl_fd, NSCIOC_NSKERND, &nsk);
- nthread_dec();
- }
-
- /* cleanup */
-
- if (locked) {
- cfg_unlock(cfg);
- locked = 0;
- }
-
- if (cfg != NULL) {
- cfg_close(cfg);
- cfg = NULL;
- }
- (void) mutex_unlock(&cfg_mutex);
-
- return (NULL);
-}
-
-
-/*
- * Inter-node lock thread.
- *
- * This is the user level side of nsc_rmlock().
- */
-static void
-dolock(struct nskernd *req)
-{
- struct nskernd *nskp;
- thread_t tid;
- int rc;
-
- /* create a new thread to do the lock and return to kernel */
-
- nskp = malloc(sizeof (*nskp));
- if (!nskp) {
-#ifdef DEBUG
- (void) fprintf(stderr,
- gettext("nskernd:dolock: malloc(%d) failed\n"),
- sizeof (*nskp));
-#endif
- req->data1 = (uint64_t)ENOMEM;
- return;
- }
-
- /* copy args for child */
- bcopy(req, nskp, sizeof (*nskp));
-
- rc = thr_create(NULL, (THR_MIN_STACK + NSK_STACK_SIZE),
- _dolock, nskp, THR_BOUND|THR_DETACHED, &tid);
-
- if (rc != 0) {
- /* thr_create failed */
-#ifdef DEBUG
- (void) fprintf(stderr,
- gettext("nskernd: thr_create failed: %s\n"),
- strerror(errno));
-#endif
- req->data1 = (uint64_t)errno;
- free(nskp);
- } else {
- /* success - _dolock() will free nskp */
- req->data1 = (uint64_t)0;
- }
-}
-
-
-/*
- * Convenience code for engineering test of multi-terabyte volumes.
- *
- * zvol (part of zfs) does not support DKIOCPARTITION but does use EFI
- * labels. This code allocates a simple efi label structure and ioctls
- * to extract the size of a zvol. It only handles the minimal EFI ioctl
- * implementation in zvol.
- */
-
-static void
-zvol_bsize(char *path, uint64_t *size, const int pnum)
-{
- struct stat64 stb1, stb2;
- struct dk_minfo dkm;
- int fd = -1;
- int rc;
-
- if (cl_nodeid || pnum != 0)
- return;
-
- if ((fd = open(path, O_RDONLY)) < 0) {
- return;
- }
-
- if (stat64("/devices/pseudo/zfs@0:zfs", &stb1) != 0 ||
- fstat64(fd, &stb2) != 0 ||
- !S_ISCHR(stb1.st_mode) ||
- !S_ISCHR(stb2.st_mode) ||
- major(stb1.st_rdev) != major(stb2.st_rdev)) {
- (void) close(fd);
- return;
- }
-
- rc = ioctl(fd, DKIOCGMEDIAINFO, (void *)&dkm);
- if (rc >= 0) {
- *size = LE_64(dkm.dki_capacity) *
- (dkm.dki_lbsize) / 512;
- }
-
- (void) close(fd);
-}
-
-/* ARGSUSED */
-static void
-get_bsize(uint64_t raw_fd, uint64_t *size, int *partitionp, char *path)
-{
- struct nscioc_bsize bsize;
-#ifdef DKIOCPARTITION
- struct partition64 p64;
-#endif
- struct dk_cinfo dki_info;
- struct vtoc vtoc;
- int fd;
-
- *partitionp = -1;
- *size = (uint64_t)0;
-
- dki_info.dki_partition = (ushort_t)-1;
- bsize.dki_info = (uint64_t)(unsigned long)&dki_info;
- bsize.vtoc = (uint64_t)(unsigned long)&vtoc;
- bsize.raw_fd = raw_fd;
- bsize.efi = 0;
-
- fd = open(rdev, O_RDONLY);
- if (fd < 0)
- return;
-
- if (ioctl(fd, NSCIOC_BSIZE, &bsize) < 0) {
- if (dki_info.dki_partition != (ushort_t)-1) {
- /* assume part# is ok and just the size failed */
- *partitionp = (int)dki_info.dki_partition;
-
-#ifdef DKIOCPARTITION
- /* see if this is an EFI label */
- bzero(&p64, sizeof (p64));
- p64.p_partno = (uint_t)*partitionp;
- if ((ioctl(fd, DKIOCPARTITION, &p64)) > 0) {
- *size = (uint64_t)p64.p_size;
- } else {
- bsize.p64 = (uint64_t)(unsigned long)&p64;
- bsize.efi = 1;
-
- if (ioctl(fd, NSCIOC_BSIZE, &bsize) < 0) {
- /* see if this is a zvol */
- zvol_bsize(path, size, *partitionp);
- } else {
- *size = (uint64_t)p64.p_size;
- }
- }
-#endif /* DKIOCPARTITION */
- }
-
- (void) close(fd);
- return;
- }
-
- (void) close(fd);
-
- *partitionp = (int)dki_info.dki_partition;
-
- if (vtoc.v_sanity != VTOC_SANE)
- return;
-
- if (vtoc.v_version != V_VERSION && vtoc.v_version != 0)
- return;
-
- if (dki_info.dki_partition > V_NUMPAR)
- return;
-
- *size = (uint64_t)vtoc.v_part[(int)dki_info.dki_partition].p_size;
-}
-
-
-static int
-iscluster(void)
-{
- /*
- * Find out if we are running in a cluster
- */
- cl_nodeid = cfg_iscluster();
- if (cl_nodeid > 0) {
- return (TRUE);
- } else if (cl_nodeid == 0) {
- return (FALSE);
- }
-
- (void) fprintf(stderr, "%s\n",
- gettext("nskernd: unable to ascertain environment"));
- exit(1);
- /* NOTREACHED */
-}
-
-/*
- * Runtime Solaris release checking - build release == runtime release
- * is always considered success, so only keep entries in the map for
- * the special cases.
- */
-static nsc_release_t nskernd_rel_map[] = {
-/* { "5.10", "5.10" }, */
- { "5.11", "5.10" },
- { NULL, NULL }
-};
-
-
-#ifdef lint
-#define main nskernd_main
-#endif
-/* ARGSUSED1 */
-int
-main(int argc, char *argv[])
-{
- const char *dir = "/";
- struct nskernd data;
- struct rlimit rl;
- int i, run, rc;
- int partition;
- char *reqd;
- int syncpipe[2];
- int startup;
-
- (void) setlocale(LC_ALL, "");
- (void) textdomain("nskernd");
-
- rc = nsc_check_release(BUILD_REV_STR, nskernd_rel_map, &reqd);
- if (rc < 0) {
- (void) fprintf(stderr,
- gettext("nskernd: unable to determine the current "
- "Solaris release: %s\n"), strerror(errno));
- exit(1);
- } else if (rc == FALSE) {
- (void) fprintf(stderr,
- gettext("nskernd: incorrect Solaris release "
- "(requires %s)\n"), reqd);
- exit(1);
- }
-
- rc = 0;
-
- if (argc != 1)
- usage();
-
- /*
- * Usage: <progname> [-g] [-d <seconds to delay>]
- */
- while ((i = getopt(argc, argv, "gd:")) != EOF) {
- switch (i) {
- case 'g':
- display_msg = 1;
- break;
- case 'd':
- delay_time = atoi(optarg);
- if (delay_time <= 0) {
- delay_time = 30;
- }
- break;
- default:
- syslog(LOG_ERR,
- "Usage: nskernd [-g] [-d <seconds to delay>]");
- exit(1);
- break;
- }
- }
-
- if (chroot(dir) < 0) {
- (void) fprintf(stderr, gettext("nskernd: chroot failed: %s\n"),
- strerror(errno));
- exit(1);
- }
-
- if (chdir(dir) < 0) {
- (void) fprintf(stderr, gettext("nskernd: chdir failed: %s\n"),
- strerror(errno));
- exit(1);
- }
-
- /*
- * Determine if we are in a Sun Cluster or not, before fork'ing
- */
- (void) iscluster();
-
- /*
- * create a pipe to synchronise the parent with the
- * child just before it enters its service loop.
- */
- if (pipe(syncpipe) < 0) {
- (void) fprintf(stderr,
- gettext("nskernd: cannot create pipe: %s\n"),
- strerror(errno));
- exit(1);
- }
- /*
- * Fork off a child that becomes the daemon.
- */
-
- if ((rc = fork()) > 0) {
- char c;
- int n;
- (void) close(syncpipe[1]);
- /*
- * wait for the close of the pipe.
- * If we get a char back, indicates good
- * status from child, so exit 0.
- * If we get a zero length read, then the
- * child has failed, so we do too.
- */
- n = read(syncpipe[0], &c, 1);
- exit((n <= 0) ? 1 : 0);
- } else if (rc < 0) {
- (void) fprintf(stderr, gettext("nskernd: cannot fork: %s\n"),
- strerror(errno));
- exit(1);
- }
-
- /*
- * In child - become daemon.
- */
-
- /* use closefrom(3C) from PSARC/2000/193 when possible */
- for (i = 0; i < syncpipe[1]; i++) {
- (void) close(i);
- }
- closefrom(syncpipe[1] + 1);
-
- (void) open("/dev/console", O_WRONLY|O_APPEND);
- (void) dup(0);
- (void) dup(0);
- (void) close(0);
-
- (void) setpgrp();
-
- /*
- * Ignore all signals apart from SIGTERM.
- */
-
- for (i = 1; i < _sys_nsig; i++)
- (void) sigset(i, SIG_IGN);
-
- (void) sigset(SIGTERM, sighand);
-
- /*
- * Increase the number of fd's that can be open.
- */
-
- rl.rlim_cur = RLIM_INFINITY;
- rl.rlim_max = RLIM_INFINITY;
- if (setrlimit(RLIMIT_NOFILE, &rl) < 0) {
- (void) fprintf(stderr,
- gettext("nskernd: could not increase RLIMIT_NOFILE: %s\n"),
- strerror(errno));
- (void) fprintf(stderr,
- gettext("nskernd: the maximum number of nsctl open "
- "devices may be reduced\n"));
- }
-
- /*
- * Open /dev/nsctl and startup.
- */
-
- nsctl_fd = open(rdev, O_RDONLY);
- if (nsctl_fd < 0) {
- (void) fprintf(stderr, gettext("nskernd: unable to open %s\n"),
- rdev);
- exit(1);
- }
-
- bzero(&data, sizeof (data));
-
- data.command = NSKERND_START;
- data.data1 = (uint64_t)cl_nodeid;
- run = 1;
-
- startup = 1;
- while (run) {
- rc = ioctl(nsctl_fd, NSCIOC_NSKERND, &data);
- if (rc < 0) {
- /* try and do kernel cleanup and exit */
- if (shutdown()) {
- run = 0;
- } else {
- sigterm = 0;
- }
-
- (void) fprintf(stderr,
- gettext("nskernd: NSCIOC_NSKERND failed: %s\n"),
- strerror(errno));
- continue;
- } else if (sigterm) {
- /* SIGTERM received - terminate */
- if (data.command != NSKERND_START &&
- (data.command != NSKERND_STOP ||
- data.data1 != (uint64_t)1)) {
- /* need to do kernel cleanup */
- if (shutdown()) {
- run = 0;
- } else {
- sigterm = 0;
- data.command = NSKERND_START;
- data.data1 = (uint64_t)cl_nodeid;
- }
- } else {
- /* just quit */
- if (canshutdown()) {
- run = 0;
- } else {
- /* cannot shutdown - threads active */
- sigterm = 0;
- data.command = NSKERND_START;
- data.data1 = (uint64_t)cl_nodeid;
- }
- }
- continue;
- }
- if (startup) {
- char c = 0;
- (void) write(syncpipe[1], &c, 1);
- (void) close(syncpipe[1]);
- startup = 0;
- }
- switch (data.command) {
- case NSKERND_START: /* (re)start completion */
- if (rc == 1) {
- (void) fprintf(stderr,
- gettext("nskernd: already started\n"));
- run = 0;
- } else if (rc == 2) {
- (void) fprintf(stderr,
- gettext("nskernd: stopped by kernel\n"));
- run = 0;
- }
- data.command = NSKERND_WAIT;
- break;
-
- case NSKERND_STOP: /* kernel telling daemon to stop */
- if (data.data1 != (uint64_t)1) {
- (void) shutdown();
- run = 0;
- }
- break;
-
- case NSKERND_BSIZE:
- /*
- * kernel requesting partsize
- * data1 - size return
- * data2 - raw_fd (entry)
- * - partition number (return)
- */
- partition = -1;
- get_bsize(data.data2, &data.data1,
- &partition, data.char1);
- data.data2 = (uint64_t)partition;
- data.command = NSKERND_WAIT;
- break;
-
- case NSKERND_NEWLWP: /* kernel requesting a new LWP */
- newlwp(&data);
- data.command = NSKERND_WAIT;
- break;
-
- case NSKERND_LOCK: /* kernel requesting lock */
- dolock(&data);
- data.command = NSKERND_WAIT;
- break;
-
- case NSKERND_WAIT: /* kernel retrying wait */
- /*
- * the kernel thread can be woken by the dr config
- * utilities (ie cfgadm) therefore we just reissue
- * the wait.
- */
- break;
-
- case NSKERND_IIBITMAP:
- rc = log_iibmp_err(data.char1, (int)data.data1);
- data.data1 = (uint64_t)rc;
- data.command = NSKERND_WAIT;
- break;
-
- default:
- (void) fprintf(stderr,
- gettext("nskernd: unknown command %d"),
- data.command);
- data.command = NSKERND_WAIT;
- break;
- }
- }
-
- (void) close(nsctl_fd);
-
- return (rc);
-}
diff --git a/usr/src/cmd/avs/rdc/Makefile b/usr/src/cmd/avs/rdc/Makefile
deleted file mode 100644
index 1148884422..0000000000
--- a/usr/src/cmd/avs/rdc/Makefile
+++ /dev/null
@@ -1,118 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#
-
-DYNPROG = sndrd sndradm sndrboot sndrsyncd
-
-include ../../Makefile.cmd
-include ../Makefile.com
-
-PROG = $(DYNPROG)
-
-SUBDIRS= etc
-
-sndradm := POBJS = sndradm.o rdc_ioctl.o sndrsubr.o
-sndrboot := POBJS = sndrboot.o rdc_ioctl.o sndrsubr.o
-sndrd := POBJS = sndrd.o
-sndrsyncd := POBJS = sndrsyncd.o rdc_ioctl.o sndrsubr.o
-
-OBJS= \
- sndrboot.o \
- sndradm.o \
- sndrd.o \
- sndrsyncd.o \
- rdc_ioctl.o \
- sndrsubr.o
-
-XTRA_OBJS= \
- sdbc_ioctl.o
-
-SRCS= $(OBJS:%.o=%.c) ../sdbc/sdbc_ioctl.c
-
-sndradm := LDLIBS += -lrdc -lunistat -ldscfg -lnsctl -lnsl
-sndrboot := LDLIBS += -lrdc -lunistat -ldscfg
-sndrd := LDLIBS += -lrdc -lnsl
-sndrsyncd := LDLIBS += -lrdc -ldscfg -lunistat
-
-CFLAGS += $(CCVERBOSE) -D_RDC_ -D_SYSCALL32
-LINTFLAGS += -Xa -n -s -x -m -u -Dlint -errhdr=%user -D_RDC_ -D_SYSCALL32
-LINTFLAGS += -DDEBUG
-LINTFLAGS += -erroff=E_SEC_SPRINTF_UNBOUNDED_COPY
-LINTFLAGS += -erroff=E_SEC_SCANF_UNBOUNDED_COPY
-LINTFLAGS += -erroff=E_SEC_PRINTF_VAR_FMT
-LINTFLAGS += -erroff=E_FUNC_SET_NOT_USED
-CERRWARN += -_gcc=-Wno-unused-label
-CERRWARN += -_gcc=-Wno-parentheses
-CERRWARN += -_gcc=-Wno-uninitialized
-POFILE = rdc_all.po
-POFILES = sndradm.po sndrboot.po
-ROOTLIBLINKS = $(ROOTLIB)/sndrd $(ROOTLIB)/sndrsyncd
-ROOTUSRSBINLINKS = $(ROOTUSRSBIN)/sndradm $(ROOTUSRSBIN)/sndrboot
-
-all := TARGET= all
-install := TARGET= install
-clean := TARGET= clean
-clobber := TARGET= clobber
-lint := TARGET= lint
-
-.KEEP_STATE:
-
-.PARALLEL: $(OBJS) $(XTRA_OBJS)
-
-all: $(SUBDIRS) $(PROG) $(POFILES)
-
-install: $(SUBDIRS) all $(ROOTPROG) $(ROOTLIBLINKS) $(ROOTUSRSBINLINKS)
-
-lint: $(SUBDIRS) lint_SRCS
-
-clean: $(SUBDIRS)
- $(RM) *.o $(POFILES)
-
-$(PROG): $$(POBJS)
- $(LINK.c) $(POBJS) -o $@ $(LDLIBS)
- $(POST_PROCESS)
-
-$(POFILE): $(POFILES)
- $(RM) $@
- $(CAT) $(POFILES) > $@
-
-sdbc_ioctl.o: ../sdbc/sdbc_ioctl.c
- $(COMPILE.c) ../sdbc/sdbc_ioctl.c
-
-$(SUBDIRS): FRC
- @cd $@; pwd; $(MAKE) $(TARGET)
-
-$(ROOTLIBLINKS): $(ROOTLIB) $(ROOTPROG)
- -$(RM) $(ROOTLIBLINKS);
- $(LN) $(ROOTBIN)/sndrd $(ROOTLIB)/sndrd;
- $(LN) $(ROOTBIN)/sndrsyncd $(ROOTLIB)/sndrsyncd
-
-$(ROOTUSRSBINLINKS): $(ROOTUSRSBIN) $(ROOTPROG)
- -$(RM) $(ROOTUSRSBINLINKS);
- $(LN) $(ROOTBIN)/sndradm $(ROOTUSRSBIN)/sndradm;
- $(LN) $(ROOTBIN)/sndrboot $(ROOTUSRSBIN)/sndrboot
-
-FRC:
-
-include ../../Makefile.targ
diff --git a/usr/src/cmd/avs/rdc/etc/Makefile b/usr/src/cmd/avs/rdc/etc/Makefile
deleted file mode 100644
index cbe78b12a2..0000000000
--- a/usr/src/cmd/avs/rdc/etc/Makefile
+++ /dev/null
@@ -1,71 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-include ../../../Makefile.cmd
-include ../../Makefile.com
-
-PROG1 = rdc
-PROG2 = rdcfinish
-PROG3 = rdc.cluster
-SHFILES = $(PROG1) $(PROG2) $(PROG3)
-ROOTINIT_D = $(ROOTETC)/init.d
-
-FILEMODE = 0744
-
-ROOTETCFILES= $(ETCFILES:%=$(ROOTETC)/%)
-
-ROOTINIT_DPROG1 = $(ROOTINIT_D)/$(PROG1)
-ROOTINIT_DPROG2 = $(ROOTINIT_D)/$(PROG2)
-ROOTINIT_DPROG3 = $(ROOTINIT_D)/$(PROG3)
-
-.KEEP_STATE:
-
-all: $(SHFILES) $(ETCFILES) $(INITFILES)
-
-install: $(ROOTINIT_DPROG1) $(ROOTINIT_DPROG2) $(ROOTINIT_DPROG3) $(ROOTLIBSVCMETHOD) $(CLUSTERSBINDIR)
- -$(RM) $(CLUSTERLIBDSCFGSTOPDIR)/15rdc
- -$(RM) $(CLUSTERLIBDSCFGSTARTDIR)/10rdc
- -$(RM) $(ROOTLIBSVCMETHOD)/svc-rdc
- -$(RM) $(ROOTLIBSVCMETHOD)/svc-rdcsyncd
- -$(RM) $(CLUSTERSBINDIR)/rdc
- -$(SYMLINK) ../../../sbin/rdc $(CLUSTERLIBDSCFGSTOPDIR)/15rdc
- -$(SYMLINK) ../../../sbin/rdc $(CLUSTERLIBDSCFGSTARTDIR)/10rdc
- $(LN) $(ROOTINIT_D)/rdc $(ROOTLIBSVCMETHOD)/svc-rdc
- $(LN) $(ROOTINIT_D)/rdcfinish $(ROOTLIBSVCMETHOD)/svc-rdcsyncd
- $(CP) $(ROOTINIT_D)/rdc.cluster $(CLUSTERSBINDIR)/rdc
-
-$(ROOTINIT_DPROG1): $(PROG1)
- $(INS.file) $(PROG1)
-
-$(ROOTINIT_DPROG2): $(PROG2)
- $(INS.file) $(PROG2)
-
-$(ROOTINIT_DPROG3): $(PROG3)
- $(INS.file) $(PROG3)
-
-clean:
- $(RM) $(SHFILES)
-
-clobber: clean
-
-lint:
diff --git a/usr/src/cmd/avs/rdc/etc/rdc.cluster.sh b/usr/src/cmd/avs/rdc/etc/rdc.cluster.sh
deleted file mode 100644
index 2d6d0621df..0000000000
--- a/usr/src/cmd/avs/rdc/etc/rdc.cluster.sh
+++ /dev/null
@@ -1,74 +0,0 @@
-#!/usr/bin/ksh
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-# SNDR start script
-#
-# Description: This is the SNDR switchover script.
-# It is used to start or stop a specified cluster
-# resource group when invoked from the data service cluster
-# failover script.
-#
-
-PATH=/etc:/bin
-RDCBOOT="/usr/sbin/sndrboot"
-RDCSYNCD="/usr/lib/sndrsyncd"
-USAGE="Usage: $0 {start|stop} cluster_resource"
-
-SVCS=/usr/bin/svcs
-SVCS_NAME=system/nws_rdc
-
-# Determine if SMF service is online
-#
-ONLINE=`$SVCS -D $SVCS_NAME 2>>/dev/null | grep "^online"`
-if [ -z $ONLINE ]
-then
- echo "$SVCS_NAME not online"
- exit 1
-fi
-
-if [[ -z "$2" ]]
-then
- echo "$USAGE"
- exit 1
-fi
-
-case "$1" in
-'start')
- if [[ -x $RDCBOOT ]]
- then
- $RDCBOOT -r -C "$2"
- fi
- ;;
-
-'stop')
- if [[ -x $RDCBOOT ]]
- then
- $RDCBOOT -s -C "$2"
- fi
- ;;
-
-*)
- echo $USAGE
- exit 1
- ;;
-esac
diff --git a/usr/src/cmd/avs/rdc/etc/rdc.sh b/usr/src/cmd/avs/rdc/etc/rdc.sh
deleted file mode 100644
index 198d1186b2..0000000000
--- a/usr/src/cmd/avs/rdc/etc/rdc.sh
+++ /dev/null
@@ -1,186 +0,0 @@
-#!/bin/sh
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# SNDR start script
-#
-# Description: This is the SNDR start script. It must be located
-# in /etc/init.d with links to the appropriate rc2.d and
-# rc0.d files.
-# It can also be used to start or stop a specified cluster
-# resource group when invoked from the data service cluster
-# failover script.
-#
-#
-#
-PATH=/etc:/bin
-RDCBOOT="/usr/sbin/sndrboot"
-USAGE="Usage: $0 {start|stop} [cluster_resource]"
-SVCS=/usr/bin/svcs
-DSCFG_DEPEND_NOCHK="/tmp/.dscfgadm_pid"
-OS_MINOR=`/usr/bin/uname -r | /usr/bin/cut -d '.' -f2`
-
-. /lib/svc/share/smf_include.sh
-
-# Make sure prior SMF dependents are not 'online'
-# $1 = name of SMF service to validate dependents
-#
-do_smf_depends ()
-{
- times=0
- count=1
-
- if [ $OS_MINOR -ge 11 ]
- then
- return 0
- elif [ -f $DSCFG_DEPEND_NOCHK ]
- then
- for pid in `pgrep dscfgadm`
- do
- if [ `grep -c $pid $DSCFG_DEPEND_NOCHK` -gt 0 ]
- then
- return 0
- fi
- done
- elif [ `ps -ef | grep preremove | grep -c SUNWrdcu` -gt 0 ]
- then
- return 0
-
- fi
-
- while [ $count -ne 0 ]
- do
- count=`$SVCS -o STATE -D $1 2>>/dev/null | grep "^online" | wc -l`
- if [ $count -ne 0 ]
- then
- # Output banner after waiting first 5 seconds
- #
- if [ $times -eq 1 ]
- then
- echo "Waiting for $1 dependents to be 'offline'"
- $SVCS -D $1 2>>/dev/null | grep "^online"
- fi
-
- # Has it been longer then 5 minutes? (60 * 5 secs.)
- #
- if [ $times -eq 60 ]
- then
- echo "Error: Failed waiting for $1 dependents to be 'offline'"
- $SVCS -D $1 2>>/dev/null | grep "^online"
- exit $SMF_EXIT_ERR_FATAL
- fi
-
- # Now sleep, giving other services time to stop
- #
- sleep 5
- times=`expr $times + 1`
- fi
- done
- return 0
-}
-
-CLINFO=/usr/sbin/clinfo
-
-killproc() { # kill the named process(es)
- pid=`/usr/bin/ps -e |
- /usr/bin/grep -w $1 |
- /usr/bin/sed -e 's/^ *//' -e 's/ .*//'`
- [ "$pid" != "" ] && kill $pid
-}
-
-
-case "$1" in
-'start')
- COPT=
-
- if [ -x ${RDCBOOT} ]
- then
- if ${CLINFO}
- then
- if [ "$2" != "" ]
- then
- ${RDCBOOT} -r -C $2
- else
- # SNDR 3.2 SetIDs fixup
- ${RDCBOOT} -C post-patch-setids -r -s
-
- COPT="-C -"
- ${RDCBOOT} ${COPT} -r
- fi
- else
- # non-clustered start
- ${RDCBOOT} -r
- fi
- fi
- ;;
-
-'stop')
- COPT=
-
- if [ ! -r /dev/rdc ]
- then
- RDCBOOT=/usr/bin/true
- fi
-
- do_smf_depends "system/nws_rdc"
-
- if [ -x ${RDCBOOT} ]
- then
- if ${CLINFO}
- then
- if [ "$2" != "" ]
- then
- ${RDCBOOT} -s -C $2
- else
- COPT="-C -"
- ${RDCBOOT} ${COPT} -s
-
- echo "killing SNDR daemons"
- killproc sndrd
- killproc sndrsync
- fi
- else
- # non-clustered stop
-
- ${RDCBOOT} -s
-
- echo "killing SNDR daemons"
- killproc sndrd
- killproc sndrsync
- fi
- else
- # no sndr boot command, kill daemon anyway
-
- echo "killing SNDR daemons"
- killproc sndrd
- killproc sndrsync
- fi
-
- ;;
-
-*)
- echo $USAGE
- exit 1
- ;;
-esac
-exit $SMF_EXIT_OK
diff --git a/usr/src/cmd/avs/rdc/etc/rdcfinish.sh b/usr/src/cmd/avs/rdc/etc/rdcfinish.sh
deleted file mode 100644
index f0cc2f1b8e..0000000000
--- a/usr/src/cmd/avs/rdc/etc/rdcfinish.sh
+++ /dev/null
@@ -1,90 +0,0 @@
-#!/bin/sh
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# Second SNDR start script
-# - called after the TCP/IP stack has been initialised,
-# and networking enabled.
-#
-# - should be linked to /etc/rc2.d/S72rdcfinish as follows:
-#
-# ln /etc/init.d/rdc /etc/rc2.d/S72rdcfinish
-#
-PATH=/etc:/bin
-RDCD="/usr/lib/sndrd"
-RDCSYNCD="/usr/lib/sndrsyncd"
-USAGE="Usage: $0 start"
-
-. /lib/svc/share/smf_include.sh
-
-case "$1" in
-'start')
- echo "Completing SNDR startup:\c"
-
- ##
- ## Start sndrd
- ##
-
- if [ ! -f ${RDCD} ]
- then
- echo "Cannot find ${RDCD}.\nSNDR services unavailable." > /dev/console
- exit $SMF_EXIT_MON_OFFLINE
- fi
-
- ps -e | grep sndrd > /dev/null 2>&1
- if [ $? -ne 0 ]; then
- ${RDCD}
- echo " sndrd\c"
- else
- echo " sndrd already enabled\c"
- fi
-
- ##
- ## Start sndrsyncd
- ##
-
- if [ ! -f ${RDCSYNCD} ]
- then
- echo "\nCannot find ${RDCSYNCD}.\nSNDR start aborted." > /dev/console
- exit $SMF_EXIT_MON_OFFLINE
- fi
-
- ps -e | grep sndrsyn > /dev/null 2>&1
- if [ $? -ne 0 ]; then
- ${RDCSYNCD}
- echo " sndrsyncd\c"
- else
- echo " sndrsyncd already running\c"
- fi
-
- echo " done"
- ;;
-'stop')
- # Inserted for symmetry
- ;;
-*)
- echo $USAGE
- exit 1
- ;;
-esac
-exit $SMF_EXIT_OK
diff --git a/usr/src/cmd/avs/rdc/rdc_ioctl.c b/usr/src/cmd/avs/rdc/rdc_ioctl.c
deleted file mode 100644
index 1fcd85669d..0000000000
--- a/usr/src/cmd/avs/rdc/rdc_ioctl.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * RDC user level ioctl interface
- */
-
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <fcntl.h>
-
-#include <sys/nsctl/sd_cache.h>
-#include <sys/nsctl/sd_conf.h>
-#include <sys/nsctl/rdc_ioctl.h>
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_u.h>
-
-const char *__rdc_dev = "/dev/rdc";
-static int __rdc_fd;
-
-
-static int
-__rdc_open(void)
-{
- int fd = open(__rdc_dev, O_RDONLY);
-
- if (fd < 0)
- return (-1);
-
- return (__rdc_fd = fd);
-}
-
-
-int
-rdc_ioctl(long cmd, long a0, long a1, long a2, long a3, long a4,
- spcs_s_info_t ustatus)
-{
- _rdc_ioctl_t args;
-
- if (!__rdc_fd && __rdc_open() < 0)
- return (-1);
-
- args.arg0 = a0;
- args.arg1 = a1;
- args.arg2 = a2;
- args.arg3 = a3;
- args.arg4 = a4;
- args.magic = RDC_MAGIC; /* for versioning */
- args.ustatus = ustatus;
-
- return (ioctl(__rdc_fd, cmd, &args));
-}
-
-/*
- * Simple form of the ioctl, just pass the command and buffer address
- * to the kernel.
- */
-int
-rdc_ioctl_simple(long cmd, void *addr)
-{
- if (!__rdc_fd && __rdc_open() < 0)
- return (-1);
- return (ioctl(__rdc_fd, cmd, addr));
-}
diff --git a/usr/src/cmd/avs/rdc/rdcadm.h b/usr/src/cmd/avs/rdc/rdcadm.h
deleted file mode 100644
index 6ad0c05731..0000000000
--- a/usr/src/cmd/avs/rdc/rdcadm.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _RDCADM_H
-#define _RDCADM_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-#define MAXQFBAS 0
-#define MAXQITEMS 0
-#define ASYNCTHR 0
-#define AUTOSYNC -1
-#define AUTOSYNC_OFF 0
-#define AUTOSYNC_ON 1
-#define QBLOCK 0
-
-extern int maxqfbas;
-extern int maxqitems;
-extern int autosync;
-extern int asyncthr;
-extern int qblock;
-
-extern char *rdc_decode_flag(int, int);
-extern void rdc_err(spcs_s_info_t *status, char *string, ...);
-extern void rdc_warn(spcs_s_info_t *status, char *string, ...);
-extern int rdc_get_maxsets();
-extern int mounted(char *device);
-extern int get_cfg_setid(CFGFILE *cfg, char *ctag, char *tohost, char *tofile);
-extern int get_new_cfg_setid(CFGFILE *cfg);
-extern void get_group_diskq(CFGFILE *cfg, char *group, char *diskq);
-extern int find_setnumber_in_libcfg(CFGFILE *, char *, char *, char *);
-extern int sv_enable(char *, CFGFILE *, char *);
-extern void block_sigs(void);
-extern void unblock_sigs(void);
-
-extern char *program;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _RDCADM_H */
diff --git a/usr/src/cmd/avs/rdc/sndradm.c b/usr/src/cmd/avs/rdc/sndradm.c
deleted file mode 100644
index 4bcb3008dd..0000000000
--- a/usr/src/cmd/avs/rdc/sndradm.c
+++ /dev/null
@@ -1,5715 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/utsname.h>
-#include <sys/wait.h>
-#include <stdio.h>
-#include <errno.h>
-#include <values.h>
-#include <limits.h>
-#include <fcntl.h>
-#include <strings.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/stat.h>
-
-#include <locale.h>
-#include <langinfo.h>
-#include <libintl.h>
-#include <stdarg.h>
-#include <netdb.h>
-#include <ctype.h>
-
-#include <sys/nsctl/rdc_io.h>
-#include <sys/nsctl/rdc_ioctl.h>
-#include <sys/nsctl/rdc_prot.h>
-
-#include <sys/nsctl/cfg.h>
-
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_u.h>
-#include <sys/unistat/spcs_errors.h>
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netinet/tcp.h>
-#include <rpc/rpc_com.h>
-#include <rpc/rpc.h>
-
-#include <sys/nsctl/librdc.h>
-#include <sys/nsctl/nsc_hash.h>
-
-#include "rdcadm.h"
-
-/*
- * support for the special cluster tag "local" to be used with -C in a
- * cluster for local volumes.
- */
-
-#define RDC_LOCAL_TAG "local"
-
-typedef struct volcount_s {
- int count;
-} volcount_t;
-hash_node_t **volhash = NULL;
-
-/*
- * rdc_islocal is only pertinent while creating the pairs array.
- * after all the pairs are set, its value is useless, retaining
- * the last value it was set to.
- * its only reason in life is to suppress an error message in 2
- * places where the inappropriate becomes appropriate (a supplied
- * ctag which does not match an implied one cfg_dgame()). This
- * happens when C "local" is supplied. It is then used to make an
- * error message clearer. A
- * gettext("set %s does not match", rdc_islocal < 1?dga:dgb) situation
- */
-static int rdc_islocal = 0;
-
-char *program;
-
-#define min(a, b) ((a) > (b) ? (b) : (a))
-
-static char place_holder[] = "-"; /* cfg place holder value */
-
-/*
- * config file user level Dual copy pair structure
- */
-typedef struct _sd_dual_pair {
- char fhost[MAX_RDC_HOST_SIZE]; /* Hostname for primary device */
- char fnetaddr[RDC_MAXADDR]; /* Host netaddr for primary device */
- char ffile[NSC_MAXPATH]; /* Primary device */
- char fbitmap[NSC_MAXPATH]; /* Primary bitmap device */
- char thost[MAX_RDC_HOST_SIZE]; /* Hostname for secondary device */
- char tnetaddr[RDC_MAXADDR]; /* Host netaddr for secondary device */
- char tfile[NSC_MAXPATH]; /* Secondary device */
- char tbitmap[NSC_MAXPATH]; /* Secondary bitmap device */
- char directfile[NSC_MAXPATH]; /* Local FCAL direct IO volume */
- char group[NSC_MAXPATH]; /* Group name */
- char ctag[MAX_RDC_HOST_SIZE]; /* Cluster resource name tag */
- char diskqueue[NSC_MAXPATH]; /* Disk Queue volume */
- int doasync; /* Device is in sync/async mode */
-} _sd_dual_pair_t;
-
-#define EXTRA_ARGS 6 /* g grp C ctag q diskqueue */
-
-static int rdc_operation(
- CFGFILE *, char *, char *, char *, char *, char *, char *,
- int, int, char *, char *, char *, char *, int *, int);
-int read_config(int, char *, char *, char *);
-static int read_libcfg(int, char *, char *);
-int prompt_user(int, int);
-static void rdc_check_dgislocal(char *);
-void process_clocal(char *);
-static void usage(void);
-void q_usage(int);
-static void load_rdc_vols(CFGFILE *);
-static void unload_rdc_vols();
-static int perform_autosv();
-static void different_devs(char *, char *);
-static void validate_name(CFGFILE *, char *);
-static void set_autosync(int, char *, char *, char *);
-static int autosync_is_on(char *tohost, char *tofile);
-static void enable_autosync(char *fhost, char *ffile, char *thost, char *tfile);
-static void checkgfields(CFGFILE *, int, char *, char *, char *, char *,
- char *, char *, char *, char *, char *);
-static void checkgfield(CFGFILE *, int, char *, char *, char *);
-static int rdc_bitmapset(char *, char *, char *, int, nsc_off_t);
-static int parse_cfg_buf(char *, _sd_dual_pair_t *, char *);
-static void verify_groupname(char *grp);
-extern char *basename(char *);
-
-int rdc_maxsets;
-static _sd_dual_pair_t *pair_list;
-
-struct netbuf svaddr;
-struct netbuf *svp;
-struct netconfig nconf;
-struct netconfig *conf;
-struct knetconfig knconf;
-
-static char *reconfig_pbitmap = NULL;
-static char *reconfig_sbitmap = NULL;
-#ifdef _RDC_CAMPUS
-static char *reconfig_direct = NULL;
-#endif
-static char *reconfig_group = NULL;
-static char reconfig_ctag[MAX_RDC_HOST_SIZE];
-static int reconfig_doasync = -1;
-
-static int clustered = 0;
-static int proto_test = 0;
-int allow_role = 0;
-
-
-static char *
-rdc_print_state(rdc_set_t *urdc)
-{
- if (!urdc)
- return ("");
-
- if (urdc->sync_flags & RDC_VOL_FAILED)
- return (gettext("volume failed"));
- else if (urdc->sync_flags & RDC_FCAL_FAILED)
- return (gettext("fcal failed"));
- else if (urdc->bmap_flags & RDC_BMP_FAILED)
- return (gettext("bitmap failed"));
- else if (urdc->flags & RDC_DISKQ_FAILED)
- return (gettext("disk queue failed"));
- else if (urdc->flags & RDC_LOGGING) {
- if (urdc->sync_flags & RDC_SYNC_NEEDED)
- return (gettext("need sync"));
- else if (urdc->sync_flags & RDC_RSYNC_NEEDED)
- return (gettext("need reverse sync"));
- else if (urdc->flags & RDC_QUEUING)
- return (gettext("queuing"));
- else
- return (gettext("logging"));
- } else if ((urdc->flags & RDC_SLAVE) && (urdc->flags & RDC_SYNCING)) {
- if (urdc->flags & RDC_PRIMARY)
- return (gettext("reverse syncing"));
- else
- return (gettext("syncing"));
- } else if (urdc->flags & RDC_SYNCING) {
- if (urdc->flags & RDC_PRIMARY)
- return (gettext("syncing"));
- else
- return (gettext("reverse syncing"));
- }
-
- return (gettext("replicating"));
-}
-
-
-static int
-rdc_print(int file_format, int verbose, char *group_arg, char *ctag_arg,
- char *user_shost, char *user_sdev, CFGFILE *cfgp)
-{
- rdc_status_t *rdc_status;
- spcs_s_info_t ustatus;
- rdc_set_t *urdc;
- size_t size;
- int i, rc, max;
- char *tohost, *tofile;
- _sd_dual_pair_t pair;
- char *tmptohost = pair.thost;
- char *tmptofile = pair.tfile;
- char *fromhost = pair.fhost;
- char *fromfile = pair.ffile;
- char *frombitmap = pair.fbitmap;
- char *tobitmap = pair.tbitmap;
- char *directfile = pair.directfile;
- char *group = pair.group;
- char *diskqueue = pair.diskqueue;
- char *ctag = pair.ctag;
- CFGFILE *cfg;
- int j;
- int setnumber;
- char key[CFG_MAX_KEY];
- char buf[CFG_MAX_BUF];
- char sync[16];
- int match, found;
-
- size = sizeof (rdc_status_t) + (sizeof (rdc_set_t) * (rdc_maxsets - 1));
- match = (user_shost != NULL || user_sdev != NULL);
- found = 0;
-
- if (user_shost == NULL && user_sdev != NULL)
- user_shost = "";
- else if (user_shost != NULL && user_sdev == NULL)
- user_sdev = "";
-
- rdc_status = malloc(size);
- if (!rdc_status) {
- rdc_err(NULL,
- gettext("unable to allocate %ld bytes"), size);
- }
-
- rdc_status->nset = rdc_maxsets;
- ustatus = spcs_s_ucreate();
-
- rc = RDC_IOCTL(RDC_STATUS, rdc_status, 0, 0, 0, 0, ustatus);
- if (rc == SPCS_S_ERROR) {
- rdc_err(&ustatus, gettext("statistics error"));
- }
-
- spcs_s_ufree(&ustatus);
-
- max = min(rdc_status->nset, rdc_maxsets);
-
- if (cfgp != NULL) {
- cfg = cfgp;
- cfg_rewind(cfg, CFG_SEC_CONF);
- } else {
- if ((cfg = cfg_open(NULL)) == NULL)
- rdc_err(NULL,
- gettext("unable to access configuration"));
-
- if (!cfg_lock(cfg, CFG_RDLOCK))
- rdc_err(NULL, gettext("unable to lock configuration"));
- }
-
- for (i = 0; i < max; i++) {
- urdc = &rdc_status->rdc_set[i];
-
- if (!(urdc->flags & RDC_ENABLED))
- continue;
-
- if (match &&
- (strcmp(user_shost, urdc->secondary.intf) != 0 ||
- strcmp(user_sdev, urdc->secondary.file) != 0))
- continue;
-
- tohost = urdc->secondary.intf;
- tofile = urdc->secondary.file;
- found = 1;
-
- /* get sndr entries until shost, sfile match */
- for (j = 0; j < rdc_maxsets; j++) {
- setnumber = j + 1;
- (void) snprintf(key, sizeof (key),
- "sndr.set%d", setnumber);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) {
- break;
- }
-
- if (parse_cfg_buf(buf, &pair, NULL))
- rdc_err(NULL, gettext("cfg input error"));
-
- if (strcmp(tmptofile, tofile) != 0)
- continue;
- if (strcmp(tmptohost, tohost) != 0)
- continue;
-
- if (pair.doasync == 0)
- (void) strcpy(sync, "sync");
- else
- (void) strcpy(sync, "async");
-
- /* Got the matching entry */
-
- break;
- }
-
- if (j == rdc_maxsets)
- continue; /* not found in config */
-
- if (strcmp(group_arg, "") != 0 &&
- strncmp(group_arg, group, NSC_MAXPATH) != 0)
- continue;
-
- if (strcmp(ctag_arg, "") != 0 &&
- strncmp(ctag_arg, ctag, MAX_RDC_HOST_SIZE) != 0)
- continue;
-
- if (file_format) {
- (void) printf("%s %s %s %s %s %s %s %s",
- fromhost, fromfile, frombitmap,
- tohost, tofile, tobitmap,
- directfile, sync);
- if (strlen(group) != 0)
- (void) printf(" g %s", group);
- if ((strlen(ctag) != 0) && (ctag[0] != '-'))
- (void) printf(" C %s", ctag);
- if (strlen(diskqueue) != 0)
- (void) printf(" q %s", diskqueue);
- (void) printf("\n");
- continue;
- }
-
- if (strcmp(group_arg, "") != 0 &&
- strncmp(group_arg, urdc->group_name, NSC_MAXPATH) != 0)
- continue;
-
- if (!(urdc->flags & RDC_PRIMARY)) {
- (void) printf(gettext("%s\t<-\t%s:%s\n"),
- urdc->secondary.file, urdc->primary.intf,
- urdc->primary.file);
- } else {
- (void) printf(gettext("%s\t->\t%s:%s\n"),
- urdc->primary.file, urdc->secondary.intf,
- urdc->secondary.file);
- }
- if (!verbose)
- continue;
-
- if (urdc->autosync)
- (void) printf(gettext("autosync: on"));
- else
- (void) printf(gettext("autosync: off"));
-
- (void) printf(gettext(", max q writes: %lld"), urdc->maxqitems);
- (void) printf(gettext(", max q fbas: %lld"), urdc->maxqfbas);
- (void) printf(gettext(", async threads: %d"),
- urdc->asyncthr);
- (void) printf(gettext(", mode: %s"),
- pair.doasync ? "async" : "sync");
-
- if (strlen(urdc->group_name) != 0)
- (void) printf(gettext(", group: %s"), urdc->group_name);
- if ((strlen(ctag) != 0) && (ctag[0] != '-'))
- (void) printf(gettext(", ctag: %s"), ctag);
- if (strlen(urdc->disk_queue) != 0) {
- (void) printf(gettext(", %s diskqueue: %s"),
- (urdc->flags & RDC_QNOBLOCK) ? gettext("non blocking") :
- gettext("blocking"), urdc->disk_queue);
- }
-
- (void) printf(gettext(", state: %s"), rdc_print_state(urdc));
- (void) printf(gettext("\n"));
-
- }
-
- if (!cfgp)
- cfg_close(cfg);
-
- free(rdc_status);
-
- if (match && !found) {
- rdc_warn(NULL, gettext("unable to find set %s:%s"),
- user_shost, user_sdev);
- }
-
- return (0);
-}
-
-
-int
-parse_extras(int argc, char *args[], int i)
-{
- int gflag = 0;
- int Cflag = 0;
- int qflag = 0;
- int j;
-
- (void) strcpy(pair_list[i].ctag, "");
- (void) strcpy(pair_list[i].group, "");
- (void) strcpy(pair_list[i].diskqueue, "");
-
- if (argc == 0)
- return (0);
-
- if (argc != 2 && argc != 4 && argc != 6)
- return (-1);
-
- for (j = 0; j < argc; j += 2) {
- if (strcmp(args[j], "g") == 0) {
- if (gflag)
- return (-1);
- (void) strncpy(pair_list[i].group, args[j + 1],
- NSC_MAXPATH);
- gflag = 1;
- }
- if (strcmp(args[j], "C") == 0) {
- if (!clustered)
- return (-1);
- if (Cflag)
- return (-1);
- (void) strncpy(pair_list[i].ctag, args[j + 1],
- MAX_RDC_HOST_SIZE);
- process_clocal(pair_list[i].ctag);
- Cflag = 1;
- }
- if (strcmp(args[j], "q") == 0) {
- if (qflag)
- return (-1);
- (void) strncpy(pair_list[i].diskqueue, args[j + 1],
- NSC_MAXPATH);
- qflag = 1;
- }
- }
-
- return (0);
-}
-
-static int
-parse_cfg_buf(char *buf, _sd_dual_pair_t *pair, char *lghn)
-{
- int rc = 0;
- char sync[16];
- char options[64], *p, *q;
- int len;
-
- rc = sscanf(buf, "%s %s %s %s %s %s %s %s %s %s %s %s", pair->fhost,
- pair->ffile, pair->fbitmap, pair->thost, pair->tfile,
- pair->tbitmap, pair->directfile, sync, pair->group,
- pair->ctag, options, pair->diskqueue);
-
- if (rc != 12)
- rdc_err(NULL, gettext("cfg input error"));
-
- if (strcmp(pair->diskqueue, place_holder) == 0)
- (void) strcpy(pair->diskqueue, "");
-
- if (strcmp(pair->group, place_holder) == 0)
- (void) strcpy(pair->group, "");
-
- if (strcmp(sync, "sync") == 0)
- pair->doasync = 0;
- else if (strcmp(sync, "async") == 0)
- pair->doasync = 1;
- else {
- rdc_err(NULL,
- gettext("set %s:%s neither sync nor async"),
- pair->thost, pair->tfile);
- }
-
- if (lghn && (p = strstr(options, "lghn="))) {
- p += 5;
- q = strchr(p, ';');
- if (q) {
- /* LINTED p & q limited to options[64] */
- len = q - p;
- } else {
- len = strlen(p);
- }
- (void) strncpy(lghn, p, len);
- lghn[len] = '\0';
- } else if (lghn) {
- *lghn = '\0';
- }
-
- return (0);
-}
-
-static int
-ctag_check(char *fromhost, char *fromfile, char *frombitmap, char *tohost,
- char *tofile, char *tobitmap, char *ctag, char *diskq)
-{
- char *file_dgname;
- char *bmp_dgname;
- char *que_dgname;
- char *localfile;
- char file_buf[MAX_RDC_HOST_SIZE];
- char bmp_buf[MAX_RDC_HOST_SIZE];
- char que_buf[NSC_MAXPATH];
- int is_primary;
- struct hostent *hp;
- char fromname[MAXHOSTNAMELEN], toname[MAXHOSTNAMELEN];
-
- if (!clustered)
- return (0);
-
- hp = gethost_byname(fromhost);
- (void) strncpy(fromname, hp->h_name, MAXHOSTNAMELEN);
- hp = gethost_byname(tohost);
- (void) strncpy(toname, hp->h_name, MAXHOSTNAMELEN);
- if (!self_check(fromname) && !self_check(toname)) {
- /*
- * If we could get a list of logical hosts on this cluster
- * then we could print something intelligent about where
- * the volume is mastered. For now, just print some babble
- * about the fact that we have no idea.
- */
- rdc_err(NULL,
- gettext("either %s:%s or %s:%s is not local"),
- fromhost, fromfile, tohost, tofile);
- }
-
- is_primary = self_check(fromname);
-
- /*
- * If implicit disk group name and no ctag specified by user,
- * we set the ctag to it.
- * If implicit disk group name, it must match any supplied ctag.
- */
- localfile = is_primary ? fromfile : tofile;
- file_dgname = cfg_dgname(localfile, file_buf, sizeof (file_buf));
- if (file_dgname && strlen(file_dgname))
- rdc_check_dgislocal(file_dgname);
-
- /*
- * Autogenerate a ctag, if not "-C local" or no "-C " specified
- */
- if (!rdc_islocal && !strlen(ctag) && file_dgname && strlen(file_dgname))
- (void) strncpy(ctag, file_dgname, MAX_RDC_HOST_SIZE);
-
- /*
- * making an exception here for users giving the "local"tag
- * this overrides this error message. (rdc_islocal ! = 1)
- */
- if (!rdc_islocal && strlen(ctag) &&
- file_dgname && strlen(file_dgname) &&
- strncmp(ctag, file_dgname, MAX_RDC_HOST_SIZE)) {
- rdc_warn(NULL, gettext("ctag \"%s\" does not "
- "match disk group name \"%s\" of volume %s"), ctag,
- file_dgname, localfile);
- return (-1);
- }
-
- /*
- * Do we have a non-volume managed disk without -C local specified?
- */
- if (!rdc_islocal && (!file_dgname || !strlen(file_dgname))) {
- rdc_err(NULL, gettext("volume \"%s\" is not part"
- " of a disk group,\nplease specify resource ctag\n"),
- localfile);
- }
-
- /*
- * Do we have a volume managed disk with -C local?
- */
- if (rdc_islocal && file_dgname && (strlen(file_dgname) > 0)) {
- rdc_err(NULL, gettext(
- "volume \"%s\" is part of a disk group\n"), localfile);
- }
-
- /*
- * Local bitmap must also have same ctag.
- */
- localfile = is_primary ? frombitmap : tobitmap;
- bmp_dgname = cfg_dgname(localfile, bmp_buf, sizeof (bmp_buf));
- if (bmp_dgname && strlen(bmp_dgname))
- rdc_check_dgislocal(bmp_dgname);
-
- /*
- * Assure that if the primary has a device group, so must the bitmap
- */
- if ((file_dgname && strlen(file_dgname)) &&
- (!bmp_dgname || !strlen(bmp_dgname))) {
- rdc_warn(NULL, gettext("bitmap %s is not in disk group \"%s\""),
- localfile, rdc_islocal < 1?file_dgname:ctag);
- return (-1);
- }
-
- /*
- * Assure that if the if there is a ctag, it must match the bitmap
- */
- if (!rdc_islocal && strlen(ctag) &&
- bmp_dgname && strlen(bmp_dgname) &&
- strncmp(ctag, bmp_dgname, MAX_RDC_HOST_SIZE)) {
- rdc_warn(NULL, gettext("ctag \"%s\" does not "
- "match disk group name \"%s\" of bitmap %s"), ctag,
- bmp_dgname, localfile);
- return (-1);
- }
-
- /*
- * If this is the SNDR primary and there is a local disk queue
- */
- if (is_primary && diskq[0]) {
-
- /*
- * Local disk queue must also have same ctag.
- */
- que_dgname = cfg_dgname(diskq, que_buf, sizeof (que_buf));
- if (que_dgname && strlen(que_dgname))
- rdc_check_dgislocal(que_dgname);
-
- /*
- * Assure that if the primary has a device group, so must
- * the disk queue
- */
- if ((file_dgname && strlen(file_dgname)) &&
- (!que_dgname || !strlen(que_dgname))) {
- rdc_warn(NULL, gettext("disk queue %s is not in disk "
- "group \"%s\""), diskq,
- rdc_islocal < 1?file_dgname:ctag);
- return (-1);
- }
-
- /*
- * Assure that if the if there is a ctag, it must match
- * the disk queue
- */
- if (!rdc_islocal && strlen(ctag) &&
- que_dgname && strlen(que_dgname) &&
- strncmp(ctag, que_dgname, MAX_RDC_HOST_SIZE)) {
- rdc_warn(NULL, gettext("ctag \"%s\" does not "
- "match disk group name \"%s\" of disk queue %s"),
- ctag, que_dgname, diskq);
- return (-1);
- }
- }
-
- return (0);
-}
-
-#define DISKQ_OKAY 0
-#define DISKQ_FAIL 1
-#define DISKQ_REWRITEG 2
-/*
- * check that newq is compatable with the groups current disk queue.
- * Newq is incompatable if it is set and the groups queue is set and the queues
- * are different.
- *
- * if newq is not set but should be, it will be set to the correct value.
- * returns:
- * DISK_REWRITEG entire group needs to take new value of disk_queue
- * DISKQ_OKAY newq contains a value that matches the group.
- * DISKQ_FAIL disk queues are incompatible.
- */
-static int
-check_diskqueue(CFGFILE *cfg, char *newq, char *newgroup)
-{
- int i, setnumber;
- _sd_dual_pair_t pair;
- char *group = pair.group;
- char *diskqueue = pair.diskqueue;
- char buf[CFG_MAX_BUF];
- char key[CFG_MAX_KEY];
- int open_cfg = cfg == NULL ? 1 : 0;
-
-
- if (newgroup == NULL || *newgroup == '\0') {
- if (*newq == '\0')
- return (DISKQ_OKAY); /* okay, */
- newgroup = "--nomatch--";
- }
-
- if (open_cfg) {
- if ((cfg = cfg_open(NULL)) == NULL)
- rdc_err(NULL,
- gettext("unable to access configuration"));
- if (!cfg_lock(cfg, CFG_RDLOCK))
- rdc_err(NULL, gettext("unable to lock configuration"));
- }
-
- /*CSTYLED*/
- for (i = 0; ; i++) {
- setnumber = i + 1;
- (void) snprintf(key, sizeof (key), "sndr.set%d", setnumber);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
- break;
- /*
- * I think this is quicker than
- * having to double dip into the config
- */
- if (parse_cfg_buf(buf, &pair, NULL))
- rdc_err(NULL, gettext("cfg input error"));
-
- if (strncmp(group, newgroup, NSC_MAXPATH) != 0) {
- if (((strncmp(diskqueue, newq, NSC_MAXPATH) == 0)) &&
- (diskqueue[0] != '\0')) {
- if (open_cfg)
- cfg_close(cfg);
- return (DISKQ_FAIL);
- }
- continue;
- }
- if (*newq == '\0') {
- if (diskqueue[0] != '\0')
- (void) strncpy(newq, diskqueue, NSC_MAXPATH);
- if (open_cfg)
- cfg_close(cfg);
- return (DISKQ_OKAY); /* okay, */
- }
-
- if (open_cfg)
- cfg_close(cfg);
- if (diskqueue[0] == '\0') /* no queue here */
- return (DISKQ_REWRITEG);
- return (strncmp(diskqueue, newq, NSC_MAXPATH)
- == 0 ? DISKQ_OKAY : DISKQ_FAIL);
- }
- if (open_cfg)
- cfg_close(cfg);
- return (DISKQ_OKAY);
-}
-
-
-int
-pair_diskqueue_check(int newpair)
-{
- int i, j;
- int rc;
-
- for (i = 0; i < newpair; i++) {
- if (strcmp(pair_list[i].group, pair_list[newpair].group) != 0)
- continue;
- if (strcmp(pair_list[i].diskqueue, pair_list[newpair].diskqueue)
- == 0)
- return (DISKQ_OKAY); /* matches existing group */
- if ((pair_list[newpair].group[0] != '\0') &&
- (pair_list[newpair].diskqueue[0] != '\0') &&
- (pair_list[i].diskqueue[0] != '\0')) {
- rdc_warn(NULL,
- gettext("disk queue %s does not match %s "
- "skipping set"), pair_list[newpair].diskqueue,
- pair_list[i].diskqueue);
- return (DISKQ_FAIL);
- }
-
- if ((strcmp(pair_list[newpair].diskqueue, "") == 0) &&
- pair_list[newpair].group[0] != '\0') {
- (void) strncpy(pair_list[newpair].diskqueue,
- pair_list[i].diskqueue, NSC_MAXPATH);
- return (DISKQ_OKAY); /* changed to existing group que */
- }
- if (strcmp(pair_list[i].diskqueue, "") == 0) {
- for (j = 0; j < newpair; j++) {
- if ((pair_list[j].group[0] != '\0') &&
- (strncmp(pair_list[j].group,
- pair_list[newpair].group,
- NSC_MAXPATH) == 0)) {
- (void) strncpy(pair_list[j].diskqueue,
- pair_list[newpair].diskqueue,
- NSC_MAXPATH);
- }
- }
- return (DISKQ_OKAY);
- }
- break; /* no problem with pair_list sets */
-
- }
-
- /* now check with already configured sets */
- rc = check_diskqueue(NULL, pair_list[newpair].diskqueue,
- pair_list[newpair].group);
- if (rc == DISKQ_REWRITEG) {
- for (i = 0; i < newpair; i++) {
- if (strcmp(pair_list[i].group,
- pair_list[newpair].group) != 0)
- continue;
-
- (void) strncpy(pair_list[i].diskqueue,
- pair_list[newpair].diskqueue, NSC_MAXPATH);
- }
- }
- return (rc);
-}
-
-int
-ii_set_exists(CFGFILE *cfg, char *ma, char *sh, char *bm)
-{
- char buf[CFG_MAX_BUF];
- char key[CFG_MAX_KEY];
- char master[NSC_MAXPATH];
- char shadow[NSC_MAXPATH];
- char bitmap[NSC_MAXPATH];
- int i;
-
- for (i = 1; ; i++) {
- (void) snprintf(key, sizeof (key), "ii.set%d", i);
- bzero(&master, sizeof (master));
- bzero(&shadow, sizeof (shadow));
- bzero(&bitmap, sizeof (bitmap));
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
- break;
- (void) sscanf(buf, "%s %s %s", master, shadow, bitmap);
- if (strcmp(master, ma) != 0)
- continue;
- if (strcmp(shadow, sh) != 0)
- continue;
- if (strcmp(bitmap, bm) != 0)
- continue;
- return (1);
- }
- return (0);
-}
-
-void
-rdc_ii_config(int argc, char **argv)
-{
- char *master;
- char *shadow;
- char *bitmap;
- char c;
- CFGFILE *cfg;
- int i;
- int setnumber;
- char key[CFG_MAX_KEY];
- char buf[CFG_MAX_BUF];
- int found;
- int sev;
-
- /* Parse the rest of the arguments to see what to do */
-
- if (argc - optind != 4) {
- usage();
- exit(1);
- }
-
- c = *argv[optind];
- switch (c) {
- case 'd':
- /* Delete an ndr_ii entry */
-
- master = argv[++optind];
- shadow = argv[++optind];
- bitmap = argv[++optind];
-
- if ((cfg = cfg_open(NULL)) == NULL)
- rdc_err(NULL,
- gettext("unable to access configuration"));
- if (!cfg_lock(cfg, CFG_WRLOCK))
- rdc_err(NULL, gettext("unable to lock configuration"));
-
- found = 0;
- /* get ndr_ii entries until a match is found */
- /*CSTYLED*/
- for (i = 0; ; i++) {
- setnumber = i + 1;
-
- (void) snprintf(key, sizeof (key),
- "ndr_ii.set%d.secondary",
- setnumber);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
- break;
- if (strcmp(buf, master) != 0)
- continue;
-
- /* Got a matching entry */
-
- (void) snprintf(key, sizeof (key),
- "ndr_ii.set%d.shadow",
- setnumber);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
- break;
- if (strcmp(buf, shadow) != 0)
- continue;
-
- (void) snprintf(key, sizeof (key),
- "ndr_ii.set%d.bitmap",
- setnumber);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
- break;
- if (strcmp(buf, bitmap) != 0)
- continue;
-
- (void) snprintf(key, sizeof (key),
- "ndr_ii.set%d", setnumber);
- if (cfg_put_cstring(cfg, key, NULL, 0) < 0) {
- rdc_warn(NULL,
- gettext("unable to remove \"%s\" "
- "from configuration storage: %s"),
- key, cfg_error(&sev));
- } else {
- if (cfg_commit(cfg) < 0)
- rdc_err(NULL,
- gettext("ndr_ii set %s %s %s "
- "not deconfigured."),
- master, shadow, bitmap);
- else
- spcs_log("sndr", NULL,
- gettext("ndr_ii set %s %s %s "
- "has been deconfigured."),
- master, shadow, bitmap);
- }
- found = 1;
- break;
- }
-
- if (!found) {
- rdc_err(NULL,
- gettext("did not find matching ndr_ii "
- "entry for %s %s %s"), master, shadow, bitmap);
- }
-
- cfg_close(cfg);
-
- break;
-
- case 'a':
- /* Add an ndr_ii entry */
-
- master = argv[++optind];
- shadow = argv[++optind];
- bitmap = argv[++optind];
-
- if ((cfg = cfg_open(NULL)) == NULL)
- rdc_err(NULL,
- gettext("unable to access configuration"));
- if (!cfg_lock(cfg, CFG_WRLOCK))
- rdc_err(NULL, gettext("unable to lock configuration"));
-
- found = 0;
- /* get ndr_ii entries in case a match is found */
- /*CSTYLED*/
- for (i = 0; ; i++) {
- setnumber = i + 1;
-
- (void) snprintf(key, sizeof (key),
- "ndr_ii.set%d.secondary",
- setnumber);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
- break;
- if (strcmp(buf, master) == 0) {
- rdc_err(NULL,
- gettext("found matching ndr_ii "
- "entry for %s"), master);
- }
- }
- /*
- * check to see if this is using a sndr bitmap.
- * kind of a courtesy check, as the ii copy would fail anyway
- * excepting the case where they had actually configured
- * ii/sndr that way, in which case they are broken
- * before we get here
- */
- /*CSTYLED*/
- for (i = 0; ; i++) {
- setnumber = i + 1;
-
- /*
- * Checking local bitmaps
- */
- (void) snprintf(key, sizeof (key), "sndr.set%d.phost",
- setnumber);
-
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
- break;
- if (self_check(buf)) {
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.pbitmap",
- setnumber);
- } else {
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.sbitmap",
- setnumber);
- }
-
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
- break;
-
- if ((strcmp(buf, bitmap) == 0) ||
- (strcmp(buf, master) == 0) ||
- (strcmp(buf, shadow) == 0)) {
- rdc_err(NULL,
- gettext("%s is already configured "
- "as a Remote Mirror bitmap"), buf);
- }
- }
- if (!ii_set_exists(cfg, master, shadow, bitmap)) {
- rdc_warn(NULL, gettext("Point-in-Time Copy set "
- "%s %s %s is not already configured. Remote "
- "Mirror will attempt to configure this set when "
- "a sync is issued to it. The results of that "
- "operation will be in /var/adm/ds.log"),
- master, shadow, bitmap);
- spcs_log("sndr", NULL, gettext("Point-in-Time Copy set "
- "%s %s %s is not already configured. Remote "
- "Mirror will attempt to configure this set when "
- "a sync is issued to it. The results of that "
- "operation will be in /var/adm/ds.log"),
- master, shadow, bitmap);
- } else {
- spcs_log("sndr", NULL, gettext("ndr_ii set "
- "%s %s %s has been configured."),
- master, shadow, bitmap);
- }
-
- /*
- * Prior to insertion in ndr_ii entry, if in a Sun Cluster
- * assure device groups are the same and cluster tag is set
- */
- if (clustered && !rdc_islocal) {
- char mst_dg[NSC_MAXPATH] = {0};
- char shd_dg[NSC_MAXPATH] = {0};
- char bmp_dg[NSC_MAXPATH] = {0};
-
- if (!(cfg_dgname(master, mst_dg, sizeof (mst_dg)) &&
- cfg_dgname(shadow, shd_dg, sizeof (shd_dg)) &&
- cfg_dgname(bitmap, bmp_dg, sizeof (bmp_dg))))
- rdc_warn(NULL, gettext("ndr_ii: %s %s %s are "
- "not in a device group"),
- master, shadow, bitmap);
- else if (strcmp(mst_dg, bmp_dg) ||
- strcmp(mst_dg, shd_dg))
- rdc_warn(NULL, gettext("ndr_ii: %s %s %s are "
- "not in different device groups"),
- master, shadow, bitmap);
- else {
- cfg_resource(cfg, shd_dg);
- (void) snprintf(buf, sizeof (buf),
- "%s %s %s update %s",
- master, shadow, bitmap, shd_dg);
- }
- } else {
- (void) snprintf(buf, sizeof (buf), "%s %s %s update",
- master, shadow, bitmap);
- }
-
- if ((cfg_put_cstring(cfg, "ndr_ii", buf, strlen(buf)) < 0) ||
- (cfg_commit(cfg) < 0))
- rdc_warn(NULL, gettext("unable to add \"%s\" to "
- "configuration storage: %s"),
- buf, cfg_error(&sev));
-
- cfg_close(cfg);
-
- break;
-
- default:
- usage();
- exit(1);
- }
-}
-
-void
-check_rdcbitmap(int cmd, char *hostp, char *bmp)
-{
- int i;
- CFGFILE *cfg;
- int entries;
- char **entry;
- char *host, *pri, *sec, *sbm, *bit, *mas, *sha, *ovr;
- char *shost, *buf, *que;
-
- if ((cfg = cfg_open(NULL)) == NULL)
- rdc_err(NULL,
- gettext("unable to access configuration"));
- if (!cfg_lock(cfg, CFG_RDLOCK))
- rdc_err(NULL, gettext("unable to lock configuration"));
-
- /*
- * look into II config to see if this is being used elsewhere
- */
- entry = NULL;
- entries = cfg_get_section(cfg, &entry, "ii");
- for (i = 0; i < entries; i++) {
- buf = entry[i];
-
- mas = strtok(buf, " "); /* master */
- sha = strtok(NULL, " "); /* shadow */
- bit = strtok(NULL, " "); /* bitmap */
- (void) strtok(NULL, " "); /* mode */
- ovr = strtok(NULL, " "); /* overflow */
-
- /*
- * got master, shadow, overflow, and bitmap, now compare
- */
- if ((strcmp(bmp, mas) == 0) ||
- (strcmp(bmp, sha) == 0) ||
- (strcmp(bmp, ovr) == 0) ||
- (strcmp(bmp, bit) == 0)) {
- rdc_err(NULL,
- gettext("bitmap %s is in use by"
- " Point-in-Time Copy"), bmp);
- }
- free(buf);
- }
- if (entries)
- free(entry);
-
-
- /*
- * and last but not least, make sure sndr is not using vol for anything
- */
- entry = NULL;
- entries = cfg_get_section(cfg, &entry, "sndr");
- for (i = 0; i < entries; i++) {
- buf = entry[i];
-
- /*
- * I think this is quicker than
- * having to double dip into the config
- */
- host = strtok(buf, " "); /* phost */
- pri = strtok(NULL, " "); /* primary */
- bit = strtok(NULL, " "); /* pbitmap */
- shost = strtok(NULL, " "); /* shost */
- sec = strtok(NULL, " "); /* secondary */
- sbm = strtok(NULL, " "); /* sbitmap */
- (void) strtok(NULL, " "); /* type */
- (void) strtok(NULL, " "); /* mode */
- (void) strtok(NULL, " "); /* group */
- (void) strtok(NULL, " "); /* cnode */
- (void) strtok(NULL, " "); /* options */
- que = strtok(NULL, " "); /* diskq */
-
- if (cmd == RDC_CMD_ENABLE) {
- if (self_check(host)) {
- if ((strcmp(bmp, pri) == 0) ||
- (strcmp(bmp, que) == 0) ||
- (strcmp(bmp, bit) == 0)) {
- rdc_err(NULL,
- gettext("bitmap %s is already "
- "in use by StorEdge Network Data "
- "Replicator"), bmp);
- }
- } else {
- if ((strcmp(bmp, sec) == 0) ||
- (strcmp(bmp, sbm) == 0)) {
- rdc_err(NULL,
- gettext("bitmap %s is already "
- "in use by StorEdge Network Data "
- "Replicator"), bmp);
- }
- }
- } else if (cmd == RDC_CMD_RECONFIG) {
-
- /*
- * read this logic 1000 times and consider
- * multi homed, one to many, many to one (marketing)
- * etc, etc, before changing
- */
- if (self_check(hostp)) {
- if (self_check(host)) {
- if ((strcmp(bmp, pri) == 0) ||
- (strcmp(bmp, que) == 0) ||
- (strcmp(bmp, bit) == 0)) {
- rdc_err(NULL,
- gettext("bitmap %s is already "
- "in use by StorEdge Network "
- "Data Replicator"), bmp);
- }
- } else {
- if ((strcmp(hostp, shost) == 0) &&
- (strcmp(bmp, sec) == 0) ||
- (strcmp(bmp, sbm) == 0)) {
- rdc_err(NULL,
- gettext("bitmap %s is already "
- "in use by StorEdge Network "
- "Data Replicator"), bmp);
-
- }
- }
- } else { /* self_check(hostp) failed */
- if (self_check(host)) {
- if ((strcmp(shost, hostp) == 0) &&
- (strcmp(bmp, sec) == 0) ||
- (strcmp(bmp, sbm) == 0)) {
- rdc_err(NULL,
- gettext("bitmap %s is already "
- "in use by StorEdge Network "
- "Data Replicator"), bmp);
- }
- } else {
- if ((strcmp(host, hostp) == 0) &&
- (strcmp(bmp, pri) == 0) ||
- (strcmp(bmp, que) == 0) ||
- (strcmp(bmp, bit) == 0)) {
- rdc_err(NULL,
- gettext("bitmap %s is already "
- "in use by StorEdge Network "
- "Data Replicator"), bmp);
- }
- }
- }
-
- }
-
- free(buf);
- }
- cfg_close(cfg);
-
- if (entries)
- free(entry);
-}
-int
-check_intrange(char *arg) {
- int i;
-
- for (i = 0; i < strlen(arg); i++) {
- if (arg[i] < '0' || arg[i] > '9') {
- rdc_warn(NULL, "not a valid number, must be a "
- "decimal between 1 and %d", MAXINT);
- return (0);
- }
- }
- errno = 0;
- i = (int)strtol(arg, NULL, 10);
- if ((errno) || (i < 1) || (i > MAXINT)) {
- rdc_warn(NULL, "not a valid number, must be a decimal "
- "between 1 and %d", MAXINT);
- return (0);
- }
- return (1);
-}
-
-void
-rewrite_group_diskqueue(CFGFILE *cfg, _sd_dual_pair_t *pair, char *diskqueue)
-{
- int set;
- char buf[CFG_MAX_BUF];
- char key[CFG_MAX_KEY];
- _sd_dual_pair_t tmpair;
-
- for (set = 1; /*CSTYLED*/; set++) {
- bzero(buf, CFG_MAX_BUF);
- bzero(&tmpair, sizeof (tmpair));
-
- (void) snprintf(key, sizeof (key), "sndr.set%d", set);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) {
- break;
- }
- if (parse_cfg_buf(buf, &tmpair, NULL))
- continue;
- if (pair->group && pair->group[0]) {
- if (strcmp(pair->group, tmpair.group) != 0)
- continue; /* not the group we want */
-
- } else { /* no group specified */
- if (strcmp(pair->thost, tmpair.thost) != 0)
- continue;
- if (strcmp(pair->tfile, tmpair.tfile) != 0)
- continue;
- }
-
- (void) sprintf(key, "sndr.set%d.diskq", set);
-
- if (cfg_put_cstring(cfg, key, diskqueue,
- strlen(diskqueue)) < 0) {
- perror(cfg_error(NULL));
- }
- }
-}
-
-void
-diskq_subcmd(int subcmd, char *qvol, char *group_arg, char *ctag_arg,
- char *tohost_arg, char *tofile_arg)
-{
- int found = 0;
- int setnumber = 0;
- char key[CFG_MAX_KEY];
- char buf[CFG_MAX_BUF];
- int i;
- int rc;
- int option = 0;
- _sd_dual_pair_t pair;
- CFGFILE *cfg;
- char *ctag = NULL;
- int resourced = 0;
-
- if ((cfg = cfg_open(NULL)) == NULL)
- rdc_err(NULL,
- gettext("unable to access configuration"));
-
- if (!cfg_lock(cfg, CFG_WRLOCK))
- rdc_err(NULL,
- gettext("unable to lock configuration"));
-
-redo:
- if (cfg_load_svols(cfg) < 0 ||
- cfg_load_dsvols(cfg) < 0 ||
- cfg_load_shadows(cfg) < 0)
- rdc_err(NULL,
- gettext("Unable to parse config filer"));
- load_rdc_vols(cfg);
-
- /*CSTYLED*/
- for (i = 0; i < rdc_maxsets;) {
- setnumber++;
-
- bzero(buf, CFG_MAX_BUF);
- (void) snprintf(key, sizeof (key),
- "sndr.set%d", setnumber);
- rc = cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF);
- if (rc < 0)
- break;
- if (parse_cfg_buf(buf, &pair, NULL))
- continue;
-
- if (strlen(group_arg) == 0) {
- if (strcmp(tohost_arg, pair.thost) == 0 &&
- strcmp(tofile_arg, pair.tfile) == 0) {
- (void) strcpy(group_arg, pair.group);
- found = 1;
- break;
- }
-
- } else {
- if (strcmp(group_arg, pair.group) == 0) {
- found = 1;
- break;
- }
- }
- }
-
- if (!found) {
- if (strlen(group_arg) == 0) {
- rdc_err(NULL,
- gettext("Unable to find %s:%s in "
- "configuration storage"),
- tohost_arg, tofile_arg);
- } else {
- rdc_err(NULL,
- gettext("Unable to find group %s in "
- "configuration storage"), group_arg);
- }
- }
- if (!resourced && strlen(pair.ctag)) { /* uh-oh... */
- cfg_unload_svols(cfg);
- cfg_unload_dsvols(cfg);
- cfg_unload_shadows(cfg);
- unload_rdc_vols();
- cfg_resource(cfg, pair.ctag);
- ctag = strdup(pair.ctag);
- resourced = 1;
- setnumber = 0;
- goto redo;
- }
-
- if (clustered && !rdc_islocal) {
- if (strcmp(ctag_arg, "") &&
- strncmp(ctag_arg, pair.ctag, MAX_RDC_HOST_SIZE))
- rdc_warn(NULL, gettext("ctags %s and %s "
- "do not match, proceeding with operation based "
- "on existing set information"), ctag_arg, ctag);
- }
- switch (subcmd) {
- case RDC_CMD_ADDQ:
- if (clustered && (ctag_check(pair.fhost, pair.ffile,
- pair.fbitmap, pair.thost, pair.tfile, pair.tbitmap,
- pair.ctag, qvol) < 0))
- exit(1);
-
- if (strlen(pair.diskqueue) > 0) {
- rdc_err(NULL, gettext("Remote Mirror set already "
- "has a disk queue"));
- }
- if (check_diskqueue(cfg, qvol, group_arg) == DISKQ_FAIL) {
- rdc_err(NULL,
- gettext("diskqueue %s is incompatible"), qvol);
- }
- if (rdc_operation(cfg, pair.fhost, pair.ffile, pair.fbitmap,
- pair.thost, pair.tfile, pair.tbitmap, subcmd, 0,
- pair.directfile, pair.group, pair.ctag, qvol, &pair.doasync,
- 0) < 0) {
- if (cfg_vol_disable(cfg, qvol, ctag, "sndr") < 0)
- rdc_warn(NULL, gettext("Failed to remove disk "
- "queue [%s] from configuration"), qvol);
- rdc_err(NULL, gettext("Add disk queue operation "
- "failed"));
- }
- if (nsc_lookup(volhash, qvol) == NULL) {
- if (cfg_vol_enable(cfg, qvol, ctag, "sndr") < 0) {
- rdc_err(NULL, gettext("Add disk queue "
- "operation failed"));
- }
- }
- rewrite_group_diskqueue(cfg, &pair, qvol);
-
- spcs_log("sndr", NULL, gettext("Remote Mirror: added "
- "diskqueue %s to set %s:%s and its group"), qvol,
- pair.thost, pair.tfile);
- break;
- case RDC_OPT_FORCE_QINIT:
- if (strlen(pair.diskqueue) == 0) {
- rdc_err(NULL, gettext("Remote Mirror set does not "
- "have a disk queue"));
- }
- subcmd = RDC_CMD_INITQ;
- option = RDC_OPT_FORCE_QINIT;
- if (rdc_operation(cfg, pair.fhost, pair.ffile, pair.fbitmap,
- pair.thost, pair.tfile, pair.tbitmap, subcmd, option,
- pair.directfile, pair.group, pair.ctag, qvol, &pair.doasync,
- 0) < 0) {
- exit(1);
- }
- break;
- case RDC_CMD_INITQ:
- if (strlen(pair.diskqueue) == 0) {
- rdc_err(NULL, gettext("Remote Mirror set does not "
- "have a disk queue"));
- }
- if (rdc_operation(cfg, pair.fhost, pair.ffile, pair.fbitmap,
- pair.thost, pair.tfile, pair.tbitmap, subcmd, 0,
- pair.directfile, pair.group, pair.ctag, qvol, &pair.doasync,
- 0) < 0) {
- exit(1);
- }
- break;
- case RDC_CMD_REMQ:
- if (strlen(pair.diskqueue) == 0) {
- rdc_err(NULL, gettext("Remote Mirror set does not "
- "have a disk queue"));
- }
- if (rdc_operation(cfg, pair.fhost, pair.ffile, pair.fbitmap,
- pair.thost, pair.tfile, pair.tbitmap, subcmd, 0,
- pair.directfile, pair.group, pair.ctag, qvol, &pair.doasync,
- 0) < 0) {
- exit(1);
- }
- if (cfg_vol_disable(cfg, pair.diskqueue, ctag, "sndr") < 0)
- rdc_warn(NULL, gettext("Failed to remove disk queue "
- "[%s] from configuration"), pair.diskqueue);
- rewrite_group_diskqueue(cfg, &pair, place_holder);
-
- spcs_log("sndr", NULL, gettext("Remote Mirror: removed "
- "diskqueue from set %s:%s and its group"), pair.thost,
- pair.tfile);
- break;
- case RDC_CMD_KILLQ:
- if (strlen(pair.diskqueue) == 0) {
- rdc_err(NULL, gettext("Remote Mirror set does not "
- "have a disk queue"));
- }
- if (rdc_operation(cfg, pair.fhost, pair.ffile, pair.fbitmap,
- pair.thost, pair.tfile, pair.tbitmap, subcmd, 0,
- pair.directfile, pair.group, pair.ctag, qvol, &pair.doasync,
- 0) < 0) {
- rdc_err(NULL, gettext("Failed to remove disk queue"));
- }
- if (cfg_vol_disable(cfg, pair.diskqueue, ctag, "sndr") < 0)
- rdc_warn(NULL, gettext("Failed to remove disk queue "
- "[%s] from configuration"), pair.diskqueue);
-
- rewrite_group_diskqueue(cfg, &pair, place_holder);
-
- spcs_log("sndr", NULL, gettext("Remote Mirror: forcibly "
- "removed diskqueue from set %s:%s and its group "),
- pair.thost, pair.tfile);
- break;
- case RDC_CMD_REPQ:
- if (clustered && (ctag_check(pair.fhost, pair.ffile,
- pair.fbitmap, pair.thost, pair.tfile, pair.tbitmap,
- pair.ctag, qvol) < 0))
- exit(1);
-
- if (strlen(pair.diskqueue) == 0) {
- rdc_err(NULL, gettext("Remote Mirror set does not "
- "have a disk queue"));
- }
- if (rdc_operation(cfg, pair.fhost, pair.ffile, pair.fbitmap,
- pair.thost, pair.tfile, pair.tbitmap, RDC_CMD_REMQ, 0,
- pair.directfile, pair.group, pair.ctag, qvol, &pair.doasync,
- 0) < 0) {
- rdc_err(NULL, gettext("Failed to remove disk queue"));
- }
- if (cfg_vol_disable(cfg, pair.diskqueue, ctag, "sndr") < 0)
- rdc_warn(NULL, gettext("Failed to remove disk queue "
- "[%s] from configuration"), pair.diskqueue);
-
- rewrite_group_diskqueue(cfg, &pair, place_holder);
-
- /* commit here, enable may fail */
- if (cfg_commit(cfg) < 0) {
- rdc_err(NULL, gettext("commit replace disk queue %s "
- "with %s failed"), pair.diskqueue, qvol);
- }
-
- if (check_diskqueue(cfg, qvol, group_arg) == DISKQ_FAIL) {
- rdc_err(NULL,
- gettext("cannot replace disk queue %s with %s"),
- pair.diskqueue, qvol);
- }
- if (rdc_operation(cfg, pair.fhost, pair.ffile, pair.fbitmap,
- pair.thost, pair.tfile, pair.tbitmap, RDC_CMD_ADDQ, 0,
- pair.directfile, pair.group, pair.ctag, qvol, &pair.doasync,
- 0) < 0) {
- if (cfg_vol_disable(cfg, qvol, ctag, "sndr") < 0)
- rdc_warn(NULL, gettext("Failed to remove disk "
- "queue [%s] from configuration"), qvol);
- rdc_err(NULL, gettext("Failed to add new disk queue"));
- }
- if (nsc_lookup(volhash, qvol) == NULL)
- if (cfg_vol_enable(cfg, qvol, ctag, "sndr") < 0) {
- rdc_err(NULL, gettext("Replace disk queue "
- "operation failed"));
- }
-
- rewrite_group_diskqueue(cfg, &pair, qvol);
-
- spcs_log("sndr", NULL, gettext("Remote Mirror: replaced "
- "diskqueue for set %s:%s and its group with %s"),
- pair.thost, pair.tfile, qvol);
- break;
- }
-
- cfg_unload_svols(cfg);
- cfg_unload_dsvols(cfg);
- cfg_unload_shadows(cfg);
- unload_rdc_vols();
-
- if (cfg_commit(cfg) < 0)
- rdc_err(NULL, gettext("commit failed on disk queue operation"));
-
- cfg_close(cfg);
- if (ctag)
- free(ctag);
-}
-void
-spcslog_sync(rdcconfig_t *sets, int start, int type)
-{
- rdcconfig_t *setp = sets;
-
- while (setp) {
- if (start) {
- spcs_log("sndr", NULL,
- gettext("%s %s %s %s %s %s %s %s\nSync Started"),
- program, rdc_decode_flag(RDC_CMD_COPY, type),
- setp->phost, setp->pfile, setp->pbmp,
- setp->shost, setp->sfile, setp->sbmp);
- } else {
- spcs_log("sndr", NULL,
- gettext("%s %s %s %s %s %s %s %s\nSync Ended"),
- program, rdc_decode_flag(RDC_CMD_COPY, type),
- setp->phost, setp->pfile, setp->pbmp,
- setp->shost, setp->sfile, setp->sbmp);
- }
- setp = setp->next;
- }
-}
-
-void
-spcslog_tunable(char *shost, char *svol)
-{
- if (qblock == RDC_OPT_SET_QNOBLOCK)
- spcs_log("sndr", NULL, gettext("diskqueue "
- "set to non blocking for %s:%s and any members "
- "of it's group"), shost, svol);
- else if (qblock == RDC_OPT_CLR_QNOBLOCK)
- spcs_log("sndr", NULL, gettext("diskqueue "
- "set to blocking for %s:%s and any members "
- "of it's group"), shost, svol);
-
- if (maxqfbas)
- spcs_log("sndr", NULL, gettext("maxqfbas set to %d for %s:%s"),
- maxqfbas, shost, svol);
- if (maxqitems)
- spcs_log("sndr", NULL, gettext("maxwrites set to %d for %s:%s"),
- maxqitems, shost, svol);
- if (asyncthr)
- spcs_log("sndr", NULL, gettext("%d async threads configured "
- "for %s:%s"), asyncthr, shost, svol);
-}
-
-int
-set_qblock(char *blockarg)
-{
- if (strcmp(blockarg, "block") == 0)
- qblock = RDC_OPT_CLR_QNOBLOCK;
- else if (strcmp(blockarg, "noblock") == 0)
- qblock = RDC_OPT_SET_QNOBLOCK;
- else
- return (1);
-
- return (0);
-}
-
-static void
-rdc_force_disable(CFGFILE *cfg, char *phost, char *pvol, char *pbmp,
- char *shost, char *svol, char *sbmp, char *ctag, char *lhname)
-{
- rdc_config_t parms;
- spcs_s_info_t ustatus;
- volcount_t *vc;
- char *datavol = NULL;
- char *bmpvol = NULL;
- int on_pri = 0;
- int on_sec = 0;
-
- /* are we on the primary or secondary host? */
- if (ctag && *ctag && *lhname) {
- if (strcmp(phost, lhname) == 0) {
- on_pri = 1;
- } else if (strcmp(shost, lhname) == 0) {
- on_sec = 1;
- }
- } else if (self_check(phost)) {
- on_pri = 1;
- } else if (self_check(shost)) {
- on_sec = 1;
- }
-
- if (on_pri) {
- datavol = pvol;
- bmpvol = pbmp;
- } else if (on_sec) {
- datavol = svol;
- bmpvol = sbmp;
- } else {
- rdc_err(NULL, gettext("Unable to determine whether current "
- "node is primary or secondary"));
- }
-
- /* set up parms structure */
- parms.command = RDC_CMD_DISABLE;
- (void) strncpy(parms.rdc_set->primary.intf, phost, MAX_RDC_HOST_SIZE);
- (void) strncpy(parms.rdc_set->primary.file, pvol, NSC_MAXPATH);
- (void) strncpy(parms.rdc_set->secondary.intf, shost, MAX_RDC_HOST_SIZE);
- (void) strncpy(parms.rdc_set->secondary.file, svol, NSC_MAXPATH);
- ustatus = spcs_s_ucreate();
- parms.options = RDC_OPT_FORCE_DISABLE;
-
- /*
- * We are now going to 'force' the kernel to disable the set. By
- * setting the RDC_OPT_FORCE_DISABLE flag, the kernel will bypass some
- * of the checks that are normally done when attempting to disable
- * a set. We need to do this force option in a cluster environment
- * when the logical hostname for the primary or secondary volume
- * is no longer available.
- */
- spcs_log("sndr", NULL, "%s sndradm -d %s %s %s %s %s %s",
- gettext("FORCE DISABLE"), phost, pvol, pbmp, shost, svol, sbmp);
- rdc_warn(NULL, gettext("Forcing set disable"));
- if (RDC_IOCTL(RDC_CONFIG, &parms, 0, 0, 0, 0, ustatus) != SPCS_S_OK)
- rdc_warn(&ustatus, gettext("set %s:%s not enabled in kernel"),
- shost, svol);
-
- /* if we get to this point, then a set was disabled. try sv-disable */
- vc = nsc_lookup(volhash, datavol);
- if (vc && (1 == vc->count))
- if (cfg_vol_disable(cfg, datavol, ctag, "sndr") < 0)
- rdc_warn(NULL, gettext("Failed to remove data volume "
- "[%s] from configuration"), datavol);
- vc = nsc_lookup(volhash, bmpvol);
- if (vc && (1 == vc->count))
- if (cfg_vol_disable(cfg, bmpvol, ctag, "sndr") < 0)
- rdc_warn(NULL, gettext("Failed to remove bitmap "
- "[%s] from configuration"), bmpvol);
-}
-
-void
-check_rdcsecondary(char *secondary)
-{
- int i;
- CFGFILE *cfg;
- int entries;
- char **entry;
- char *sha;
- char *buf;
-
- if ((cfg = cfg_open(NULL)) == NULL)
- rdc_err(NULL,
- gettext("error opening config"));
- if (!cfg_lock(cfg, CFG_RDLOCK))
- rdc_err(NULL, gettext("error locking config"));
-
- entry = NULL;
- entries = cfg_get_section(cfg, &entry, "ii");
- for (i = 0; i < entries; i++) {
- buf = entry[i];
-
- (void) strtok(buf, " "); /* master */
- sha = strtok(NULL, " "); /* shadow */
- if (strcmp(secondary, sha) == 0) {
- rdc_err(NULL,
- gettext("secondary %s is in use by"
- " Point-in-Time Copy"), secondary);
- }
- free(buf);
- }
- if (entries)
- free(entry);
- cfg_close(cfg);
-}
-
-int
-main(int argc, char *argv[])
-{
- char config_file[FILENAME_MAX];
- char fromhost[MAX_RDC_HOST_SIZE];
- char tohost[MAX_RDC_HOST_SIZE];
- char fromfile[NSC_MAXPATH];
- char tofile[NSC_MAXPATH];
- char frombitmap[NSC_MAXPATH];
- char tobitmap[NSC_MAXPATH];
- char directfile[NSC_MAXPATH];
- char group[NSC_MAXPATH];
- char ctag[MAX_RDC_HOST_SIZE];
- char options_cfg[CFG_MAX_BUF];
- char fromnetaddr[RDC_MAXADDR];
- char tonetaddr[RDC_MAXADDR];
- char tmphost[MAX_RDC_HOST_SIZE];
- char tmpfile[NSC_MAXPATH];
- char tmpbitmap[NSC_MAXPATH];
- char diskqueue[NSC_MAXPATH];
- char lhname[MAX_RDC_HOST_SIZE];
- char mode[16];
- rdc_version_t rdc_version;
- int pairs;
- int pid;
- int flag = 0;
- int fflag = 0;
- int reverse = 0;
- int nflag = 0;
- int iflag = 0;
- int doasync;
- int pflag = 0;
- int vflag = 0;
- int verbose = 0;
- int errflag = 0;
- int cfgflag = 0;
- int cfg_success;
- int Iflag = 0;
- char c;
- char inval = 0;
- int found;
- int rc;
- int geflag = 0;
- int qflag = 0;
- char *qarg;
- int Bflag = 0;
- char *bitfile;
- CFGFILE *cfg = NULL;
- int i;
- int setnumber;
- char key[CFG_MAX_KEY];
- char buf[CFG_MAX_BUF];
- char ctag_arg[MAX_RDC_HOST_SIZE];
- char group_arg[NSC_MAXPATH];
- int file_format = 0;
- int sev;
- int diskq_group = DISKQ_OKAY;
- int extra_argc;
- char *ctag_p, *group_p, *diskqueue_p;
- char *required;
- char *role_env;
- int checksetfields = -1;
- nsc_off_t boffset = 0;
- int oflag = 0;
- rdcconfig_t *sets = NULL;
- rdcconfig_t *sets_p = NULL;
- rdc_rc_t *rclist = NULL;
- rdc_rc_t *rcp = NULL;
- int host_not_found = 0;
-
- (void) setlocale(LC_ALL, "");
- (void) textdomain("rdc");
- role_env = getenv("SNDR_ROLE_REVERSE");
- if (role_env && strcmp(role_env, "sndr_allow_reverse") == 0)
- allow_role = 1;
-
- program = basename(argv[0]);
-
- rc = rdc_check_release(&required);
- if (rc < 0) {
- rdc_err(NULL,
- gettext("unable to determine the current "
- "Solaris release: %s\n"), strerror(errno));
- } else if (rc == FALSE) {
- rdc_err(NULL,
- gettext("incorrect Solaris release (requires %s)\n"),
- required);
- }
-
- if ((clustered = cfg_iscluster()) < 0) {
- rdc_err(NULL, gettext("unable to ascertain environment"));
- }
-
- (void) strcpy(ctag_arg, "");
- (void) strcpy(group_arg, "");
- bzero(ctag, MAX_RDC_HOST_SIZE);
- bzero(reconfig_ctag, MAX_RDC_HOST_SIZE);
- bzero(diskqueue, NSC_MAXPATH);
-
- rdc_maxsets = rdc_get_maxsets();
- if (rdc_maxsets == -1) {
- rdc_err(NULL,
- gettext("unable to get maxsets value from kernel"));
- }
-
- pair_list = calloc(rdc_maxsets, sizeof (*pair_list));
- if (pair_list == NULL) {
- rdc_err(NULL,
- gettext("unable to allocate pair_list array for %d sets"),
- rdc_maxsets);
- }
-
- bzero(group, sizeof (group));
- bzero(diskqueue, sizeof (diskqueue));
- qblock = 0;
-
- while ((c =
-#ifdef DEBUG
- getopt(argc, argv, "A:B:C:D:EF:HIO:PRUW:a:bdef:g:hilmno:pq:rsuvw"))
-#else
- getopt(argc, argv, "A:B:C:D:EF:HIO:PRUW:a:bdef:g:hilmno:pq:rsuvw"))
-#endif
- != -1) {
- switch (c) {
- case 'B':
- if (!allow_role || flag) {
- inval = 1;
- break;
- }
- bitfile = optarg;
- Bflag = 1;
- flag = RDC_BITMAPOP;
- break;
- case 'H':
- /* 'h' was already assigned */
- if (flag)
- inval = 1;
- flag = RDC_CMD_HEALTH;
- break;
- case 'I':
- /* List or edit ndr_ii configuration entries */
- Iflag = 1;
- break;
- case 'R':
- if (flag)
- inval = 1;
- flag = RDC_CMD_RECONFIG;
- break;
-#ifdef DEBUG
- case 'U': /* UDP support */
- proto_test = 1;
- break;
-#endif
- case 'F':
- if (flag && flag != RDC_CMD_TUNABLE)
- inval = 1;
- flag = RDC_CMD_TUNABLE;
-
- if (check_intrange(optarg))
- maxqfbas = atoi(optarg);
- else
- exit(1);
-
- break;
- case 'W':
- if (flag && flag != RDC_CMD_TUNABLE)
- inval = 1;
- flag = RDC_CMD_TUNABLE;
-
- if (check_intrange(optarg))
- maxqitems = atoi(optarg);
- else
- exit(1);
-
- break;
- case 'A':
- if (flag && flag != RDC_CMD_TUNABLE)
- inval = 1;
- flag = RDC_CMD_TUNABLE;
-
- if (check_intrange(optarg))
- asyncthr = atoi(optarg);
- else
- exit(1);
-
- break;
- case 'D':
- if (flag && flag != RDC_CMD_TUNABLE)
- inval = 1;
- flag = RDC_CMD_TUNABLE;
-
- if (set_qblock(optarg)) {
- usage();
- exit(1);
- }
- iflag |= qblock;
- break;
- case 'a':
- if (flag && flag != RDC_CMD_TUNABLE)
- inval = 1;
- flag = RDC_CMD_TUNABLE;
- if (strcmp(optarg, "off") == 0)
- autosync = AUTOSYNC_OFF;
- else if (strcmp(optarg, "on") == 0)
- autosync = AUTOSYNC_ON;
- else
- inval = 1;
- break;
- case 'C':
- if (clustered) {
- (void) strncpy(ctag_arg, optarg,
- MAX_RDC_HOST_SIZE);
- process_clocal(ctag_arg);
- } else
- inval = 1;
- break;
- case 'g':
- if (flag == RDC_CMD_ENABLE)
- inval = 1;
- geflag = 1;
- (void) strncpy(group_arg, optarg, NSC_MAXPATH);
- verify_groupname(group_arg);
- break;
- case 'b':
- /* ignore */
- break;
- case 'n':
- nflag = 1;
- break;
- case 'd':
- if (flag)
- inval = 1;
- flag = RDC_CMD_DISABLE;
- break;
- case 'e':
- if (flag || geflag)
- inval = 1;
- flag = RDC_CMD_ENABLE;
- iflag |= RDC_OPT_SETBMP;
- break;
- case 'E':
- if (flag)
- inval = 1;
- flag = RDC_CMD_ENABLE;
- iflag |= RDC_OPT_CLRBMP;
- break;
- case 'f':
- fflag = 1;
- (void) strcpy(config_file, optarg);
- break;
- case 'h':
- usage();
- exit(0);
- break;
- case 'l':
- if (flag)
- inval = 1;
- flag = RDC_CMD_LOG;
- break;
- case 'm':
- if (flag)
- inval = 1;
- flag = RDC_CMD_COPY;
- iflag |= RDC_OPT_FULL;
- break;
- case 'O':
- case 'o':
-
- if (!allow_role || oflag) {
- inval = 1;
- break;
- }
- if (c == 'o') {
- oflag = RDC_BITMAPOR;
- } else {
- oflag = RDC_BITMAPSET;
- }
- boffset = strtoull(optarg, NULL, 0);
- break;
- case 'P':
- if (flag)
- inval = 1;
- pflag = 1;
- verbose = 1;
- break;
- case 'p':
- if (flag)
- inval = 1;
- pflag = 1;
- break;
- case 'q':
- if (flag)
- inval = 1;
- flag = RDC_CMD_INITQ;
- qflag = optind;
- qarg = optarg;
- break;
- case 'i':
- if (flag)
- inval = 1;
- pflag = 1;
- file_format = 1;
- break;
- case 'r':
- reverse = 1;
- iflag |= RDC_OPT_REVERSE;
- break;
- case 's':
- if (flag)
- inval = 1;
- flag = RDC_CMD_STATUS;
- nflag = 1; /* No prompt for a status */
- break;
- case 'u':
- if (flag)
- inval = 1;
- flag = RDC_CMD_COPY;
- iflag |= RDC_OPT_UPDATE;
- break;
- case 'v':
- if (flag)
- inval = 1;
- pflag = 1;
- vflag = 1;
- break;
- case 'w':
- if (flag)
- inval = 1;
- flag = RDC_CMD_WAIT;
- break;
- case '?':
- errflag++;
- }
- }
-
- if (inval || ((flag != RDC_BITMAPOP) && oflag)) {
- rdc_warn(NULL, gettext("invalid argument combination"));
- errflag = 1;
- }
-
- if (flag && Iflag) {
- /* Mutually incompatible */
- usage();
- exit(1);
- }
-
- if (Iflag) {
- rdc_ii_config(argc, argv);
- exit(0);
- }
-
- if (vflag) {
- spcs_s_info_t ustatus;
-
- ustatus = spcs_s_ucreate();
- rc = RDC_IOCTL(RDC_VERSION, &rdc_version, 0, 0, 0, 0, ustatus);
- if (rc == SPCS_S_ERROR) {
- rdc_err(&ustatus, gettext("statistics error"));
- }
- spcs_s_ufree(&ustatus);
-#ifdef DEBUG
- (void) printf(gettext("Remote Mirror version %d.%d.%d.%d\n"),
- rdc_version.major, rdc_version.minor,
- rdc_version.micro, rdc_version.baseline);
-#else
- if (rdc_version.micro) {
- (void) printf(gettext(
- "Remote Mirror version %d.%d.%d\n"),
- rdc_version.major,
- rdc_version.minor,
- rdc_version.micro);
- } else {
- (void) printf(gettext("Remote Mirror version %d.%d\n"),
- rdc_version.major, rdc_version.minor);
- }
-#endif
- exit(0);
- }
-
- if (!(flag || pflag) || errflag) {
- usage();
- exit(1);
- }
-
- if (pflag && !fflag && (argc - optind) == 0) {
- /* print with no set specified */
- exit(rdc_print(file_format, verbose,
- group_arg, ctag_arg, NULL, NULL, NULL));
- }
-
- if (qflag) { /* change disk queue setting */
- int subcmd = 0;
- int offset = 0;
- char *ptr;
- char *qvol;
- char tohost_arg[MAX_RDC_HOST_SIZE];
- char tofile_arg[NSC_MAXPATH];
-
- if (strcmp("a", qarg) == 0) {
- subcmd = RDC_CMD_ADDQ;
- offset = 1;
- } else if (strcmp("d", qarg) == 0) {
- subcmd = RDC_CMD_REMQ;
- offset = 0;
- } else if (strcmp("r", qarg) == 0) {
- subcmd = RDC_CMD_REPQ;
- offset = 1;
- } else {
- rdc_warn(NULL, " %s Invalid qopt", qarg);
- q_usage(1);
- exit(1);
- }
- if (strlen(group_arg) == 0) {
- /* pick out single set as shost:svol */
- ptr = strtok(argv[qflag + offset], ":");
- if (ptr)
- (void) strncpy(tohost_arg, ptr,
- MAX_RDC_HOST_SIZE);
- else {
- rdc_warn(NULL, gettext("Bad host specified"));
- q_usage(1);
- exit(1);
- }
- ptr = strtok(NULL, ":");
- if (ptr)
- (void) strncpy(tofile_arg, ptr, NSC_MAXPATH);
- else {
- rdc_warn(NULL, gettext("Bad set specified"));
- q_usage(1);
- exit(1);
- }
- }
-
- qvol = argv[qflag];
- if ((qvol == NULL) && (subcmd != RDC_CMD_REMQ)) {
- rdc_warn(NULL, gettext("missing queue volume"));
- q_usage(1);
- exit(1);
- }
- diskq_subcmd(subcmd, qvol, group_arg, ctag_arg,
- tohost_arg, tofile_arg);
- exit(0);
- }
-
- if (flag == RDC_CMD_RECONFIG && !fflag) {
- /* See what is to be reconfigured */
- if (argc - optind == 0)
- flag = RDC_CMD_RESET;
- else {
- if (argc - optind < 2) {
- usage();
- exit(1);
- }
- c = *argv[optind++];
- if (argv[optind -1][1] != '\0') {
- usage();
- exit(2);
- }
- switch (c) {
- case 'b':
- if (argc - optind < 2) {
- usage();
- exit(1);
- }
- if (*argv[optind] == 'p')
- reconfig_pbitmap = argv[++optind];
- else if (*argv[optind] == 's')
- reconfig_sbitmap = argv[++optind];
- else {
- usage();
- exit(1);
- }
- optind++;
- break;
-#ifdef _RDC_CAMPUS
- case 'd':
- reconfig_direct = argv[optind++];
- break;
-#endif
- case 'g':
- reconfig_group = argv[optind++];
- verify_groupname(reconfig_group);
- break;
- case 'C':
- if (clustered) {
- (void) strncpy(reconfig_ctag,
- argv[optind++], MAX_RDC_HOST_SIZE);
- process_clocal(reconfig_ctag);
- } else {
- usage();
- exit(1);
- }
- break;
- case 'm':
- if (strcmp(argv[optind], "sync") == 0)
- reconfig_doasync = 0;
- else if (strcmp(argv[optind], "async") == 0)
- reconfig_doasync = 1;
- else {
- usage();
- exit(1);
- }
- optind++;
- break;
- case 'r':
- if (allow_role) {
- iflag |= RDC_OPT_REVERSE_ROLE;
- break;
- }
- /* FALLTHROUGH */
- default:
- usage();
- exit(1);
- }
- }
- }
- if (fflag) {
- checksetfields = 1;
- if ((argc - optind) != 0) {
- usage();
- exit(1);
- }
- } else {
- if ((argc - optind) == 0) {
- /* Use libcfg to figure out what to operate on */
- cfgflag = 1;
-#ifdef DEBUG
- rdc_warn(NULL, gettext("using current config"));
-#endif
- checksetfields = 0;
- } else {
- if ((argc - optind) < 8 && (argc - optind) != 1) {
- usage();
- exit(1);
- }
- }
- }
-
- if (cfgflag) {
- if (flag == RDC_CMD_ADDQ ||
- flag == RDC_CMD_REMQ ||
- flag == RDC_CMD_KILLQ ||
- flag == RDC_CMD_INITQ) {
- rdc_err(NULL, gettext("can not use current config "
- "for disk queue operations"));
- }
- } else if (fflag) {
- if (flag == RDC_CMD_ADDQ ||
- flag == RDC_CMD_REMQ ||
- flag == RDC_CMD_KILLQ ||
- flag == RDC_CMD_INITQ) {
- rdc_err(NULL, gettext("can not use a config file "
- "for disk queue operations"));
- }
- }
- if (cfgflag) {
- if (flag == RDC_CMD_ENABLE) {
- rdc_err(NULL, gettext("can not use current config "
- "for enable command"));
- }
- if ((flag == RDC_CMD_RECONFIG) && (reconfig_pbitmap ||
- reconfig_sbitmap)) {
- rdc_err(NULL, gettext("can not use current config "
- "for bitmap reconfiguration"));
- }
- if (flag == RDC_BITMAPOP) {
- rdc_err(NULL, gettext("can not use current config "
- "for bitmap set command"));
- }
- pairs = read_libcfg(flag, group_arg, ctag_arg);
- if (pairs == 0) {
- (void) fprintf(stderr,
- gettext("no matching Remote Mirror sets found "
- "in config\n"));
- exit(1);
- }
- } else if (!fflag) {
- /*
- * Format is either:
- *
- * tohost:tofile
- *
- * or something like this for example:
- *
- * fromhost fromfile frombitmap tohost tofile tobitmap ip sync
- * g group C ctag
- */
-
- if (argc - optind == 1) {
- char tohost_arg[MAX_RDC_HOST_SIZE];
- char tofile_arg[NSC_MAXPATH];
- char *ptr;
-
- checksetfields = 0;
- if (flag == RDC_CMD_ENABLE) {
- rdc_err(NULL,
- gettext("must specify full set details for "
- "enable command"));
- }
- ptr = strtok(argv[optind], ":");
- if (ptr)
- (void) strncpy(tohost_arg, ptr,
- MAX_RDC_HOST_SIZE);
- else {
- rdc_err(NULL, gettext("Bad host specified"));
- }
- ptr = strtok(NULL, ":");
- if (ptr)
- (void) strncpy(tofile_arg, ptr, NSC_MAXPATH);
- else {
- rdc_err(NULL, gettext("Bad set specified"));
- }
-
- /* Now look up tohost:tofile via libcfg */
-
- if ((cfg = cfg_open(NULL)) == NULL)
- rdc_err(NULL,
- gettext("unable to access configuration"));
-
- if (!cfg_lock(cfg, CFG_RDLOCK))
- rdc_err(NULL,
- gettext("unable to lock configuration"));
-
- setnumber = 0;
- found = 0;
- /*CSTYLED*/
- for (i = 0; i < rdc_maxsets;) {
- setnumber++;
-
- bzero(buf, CFG_MAX_BUF);
- (void) snprintf(key, sizeof (key),
- "sndr.set%d", setnumber);
- rc = cfg_get_cstring(cfg, key, buf,
- CFG_MAX_BUF);
- if (rc < 0)
- break;
-
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.shost", setnumber);
- (void) cfg_get_cstring(cfg, key, tohost,
- sizeof (tohost));
- if (strncmp(tohost, tohost_arg, NSC_MAXPATH))
- continue;
-
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.secondary", setnumber);
- (void) cfg_get_cstring(cfg, key, tofile,
- sizeof (tofile));
- if (strncmp(tofile, tofile_arg, NSC_MAXPATH))
- continue;
-
- found = 1;
-
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.phost", setnumber);
- (void) cfg_get_cstring(cfg, key, fromhost,
- sizeof (fromhost));
-
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.primary", setnumber);
- (void) cfg_get_cstring(cfg, key, fromfile,
- sizeof (fromfile));
-
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.pbitmap", setnumber);
- (void) cfg_get_cstring(cfg, key, frombitmap,
- sizeof (frombitmap));
-
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.sbitmap", setnumber);
- (void) cfg_get_cstring(cfg, key, tobitmap,
- sizeof (tobitmap));
-
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.type", setnumber);
- (void) cfg_get_cstring(cfg, key, directfile,
- sizeof (directfile));
- if (strcmp(directfile, "ip") == 0)
- (void) strcpy(directfile, "");
-
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.mode", setnumber);
- (void) cfg_get_cstring(
- cfg, key, mode, sizeof (mode));
-
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.group", setnumber);
- (void) cfg_get_cstring(cfg, key, group,
- sizeof (group));
- if (strcmp(group_arg, "") &&
- strncmp(group_arg, group, NSC_MAXPATH))
- continue;
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.cnode", setnumber);
- (void) cfg_get_cstring(
- cfg, key, ctag, sizeof (ctag));
- if ((strlen(ctag_arg) > 0) &&
- (strcmp(ctag_arg, ctag) != 0))
- rdc_err(NULL,
- gettext("ctags %s and %s "
- "do not match"), ctag_arg, ctag);
-
- if (strcmp(mode, "sync") == 0)
- doasync = 0;
- else if (strcmp(mode, "async") == 0)
- doasync = 1;
- else {
- rdc_err(NULL,
- gettext("set %s:%s neither sync "
- "nor async"), tohost, tofile);
- }
- break;
- }
- cfg_close(cfg);
- if (!found) {
- rdc_err(NULL,
- gettext("set %s:%s not found in config"),
- tohost_arg, tofile_arg);
- }
- } else {
- checksetfields = 1;
- (void) strncpy(fromhost, argv[optind],
- MAX_RDC_HOST_SIZE);
- (void) strncpy(fromfile, argv[optind+1], NSC_MAXPATH);
- (void) strncpy(frombitmap, argv[optind+2], NSC_MAXPATH);
- (void) strncpy(tohost, argv[optind+3],
- MAX_RDC_HOST_SIZE);
- (void) strncpy(tofile, argv[optind+4], NSC_MAXPATH);
- (void) strncpy(tobitmap, argv[optind+5], NSC_MAXPATH);
-
- /* Check the length of entries from the command line */
- if ((fromhost[MAX_RDC_HOST_SIZE - 1] != '\0') ||
- (tohost[MAX_RDC_HOST_SIZE - 1] != '\0')) {
- rdc_err(NULL,
- gettext("hostname is longer than %d "
- "characters\n"), (MAX_RDC_HOST_SIZE - 1));
- }
-
- /* Check if it's ip address -- not allowed */
- if ((inet_addr(fromhost) != (in_addr_t)(-1)) ||
- (inet_addr(tohost) != (in_addr_t)(-1))) {
- rdc_err(NULL, gettext(
- "The hostname specified is invalid.\n"
- "See 'man inet(3SOCKET)'"));
- }
-
- if ((fromfile[NSC_MAXPATH - 1] != '\0') ||
- (tofile[NSC_MAXPATH - 1] != '\0') ||
- (frombitmap[NSC_MAXPATH - 1] != '\0') ||
- (tobitmap[NSC_MAXPATH - 1] != '\0')) {
- rdc_err(NULL, gettext("device name is longer "
- "than %d characters\n"), (NSC_MAXPATH - 1));
- }
-#ifdef _RDC_CAMPUS
- if (argv[optind+6][0] == '/') {
- /* FCAL directio */
- (void) strncpy(directfile, argv[optind+6],
- NSC_MAXPATH);
- } else if (strcmp(argv[optind+6], "ip") != 0) {
-#else
- if (strcmp(argv[optind+6], "ip") != 0) {
-#endif
- usage();
- exit(1);
- } else
- (void) strcpy(directfile, "ip");
-
- if (strcmp(argv[optind+7], "sync") == 0)
- doasync = 0;
- else if (strcmp(argv[optind+7], "async") == 0)
- doasync = 1;
- else {
- usage();
- exit(1);
- }
-
- /*
- * At this point, we could have a set which is
- * clustered, but neither a 'C ctag' or '-C ctag' has
- * been specified. To avoid clobbering the ctag if a
- * dscfg operation is done in the future, we should get
- * the ctag out of the config at this point. To do this,
- * set the cluster resource filter to NULL to look at
- * all sets in the config, pulling out the ctag for the
- * set matching shost:svol. If the set is not found,
- * fail here. Note, we skip this set on an enable as the
- * set is not yet in the config, so no need to waste
- * time.
- */
- if ((argc - optind == 8) && clustered &&
- (flag != RDC_CMD_ENABLE)) {
- int setnumber;
- char key[CFG_MAX_KEY];
-
- if ((cfg = cfg_open(NULL)) == NULL) {
- rdc_err(NULL,
- gettext("unable to access configuration"));
- }
- if (!cfg_lock(cfg, CFG_RDLOCK)) {
- rdc_err(NULL,
- gettext("unable to lock configuration"));
- }
-
- cfg_resource(cfg, NULL);
-
- if ((setnumber =
- find_setnumber_in_libcfg(cfg, NULL, tohost,
- tofile)) < 0) {
- cfg_close(cfg);
- rdc_err(NULL,
- gettext("unable to find Remote "
- "Mirror set "
- "%s:%s in config"),
- tohost, tofile);
- }
-
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.cnode", setnumber);
- if (cfg_get_cstring(cfg, key, ctag_arg,
- MAX_RDC_HOST_SIZE) < 0) {
- cfg_close(cfg);
- rdc_err(NULL,
- gettext("unable to determine ctag "
- "for Remote Mirror set %s:%s"),
- tohost, tofile);
- }
-
- rdc_islocal = strcmp(ctag_arg, "-") ? 0 : 1;
-
- cfg_close(cfg);
- }
-
- extra_argc = argc - optind;
- if (extra_argc < 8 || extra_argc > 14 ||
- extra_argc % 2 != 0) {
- usage();
- exit(1);
- }
-
- /*
- * Loop through all of the extra arguments specified
- * on the command line, setting the appropriate values
- * for valid entries. If an unrecognized argument is
- * detected, abort with error. Note: This hack should be
- * removed and we should not accept these entries as
- * arguments, they should be passed in as switches.
- */
- for (i = (8 + optind); i < argc; i += 2) {
- /* string case statement */
- if (strcmp(argv[i], "g") == 0) {
- (void) strncpy(group, argv[i + 1],
- NSC_MAXPATH);
- if (group[NSC_MAXPATH - 1] != '\0') {
- rdc_err(NULL, gettext("group name is "
- "longer than %d characters\n"),
- (NSC_MAXPATH - 1));
- }
- } else if (strcmp(argv[i], "C") == 0) {
- if (!clustered) {
- usage();
- exit(1);
- }
- (void) strncpy(ctag, argv[i + 1],
- MAX_RDC_HOST_SIZE);
-
- if (ctag[MAX_RDC_HOST_SIZE - 1] != '\0') {
- rdc_err(NULL, gettext("cluster name "
- "is longer than %d characters\n"),
- (MAX_RDC_HOST_SIZE - 1));
- }
- process_clocal(ctag);
-
- /*
- * well here is something.
- * what if they went sndradm -C local
- * host a b host a b ip sync C foobar?
- * they might be confused
- * lets stop them if ctag_arg and ctag
- * don't match and forgive if they are
- * the same, below also.
- */
- if ((strlen(ctag_arg) > 0) &&
- (strcmp(ctag_arg, ctag) != 0)) {
- rdc_err(NULL, gettext("ctags "
- "%s and %s do not match "),
- ctag_arg, ctag);
-
- }
- } else if (strcmp(argv[i], "q") == 0) {
- (void) strncpy(diskqueue, argv[i + 1],
- NSC_MAXPATH);
- if (diskqueue[NSC_MAXPATH - 1] != '\0') {
- rdc_err(NULL, gettext("diskq name is "
- "longer than %d characters\n"),
- (NSC_MAXPATH - 1));
- }
- } else {
- /* Unrecognized argument */
- usage();
- exit(1);
- }
- }
- }
-
- /*
- * Are we able to determine the existance of either
- * of these host addresses?
- */
- if (gethost_netaddrs(fromhost, tohost,
- (char *)&fromnetaddr, (char *)&tonetaddr) < 0) {
- (void) fprintf(stderr, "\n");
- rdc_warn(NULL, gettext("unable to determine IP "
- "addresses for either host %s or host %s"),
- fromhost, tohost);
-
- if (flag != RDC_CMD_DISABLE)
- exit(1);
- else
- host_not_found = 1;
- }
-
- /*
- * Are we running on neither host?
- */
- if (!self_check(fromhost) && !self_check(tohost)) {
- if (flag == RDC_CMD_DISABLE) {
- (void) fprintf(stderr, "\n");
- rdc_warn(NULL, gettext("Not running on either host "
- "%s or host %s"), fromhost, tohost);
- host_not_found = 1;
- }
- }
-
- /*
- * at this point, hopfully it is safe to say that
- * if a ctag was supplied via -C tag it is safe to
- * move it from ctag_arg to ctag. If it was passed in
- * at the end and the beginning of the cli, it must
- * match, as per checks above. if it was not passed
- * in at the end, but at the beginning, we can deal.
- * this should handle the case of shost:svol.
- * which is the main reason for this.
- *
- * there are 3 cases: passed in by cli, checked just above.
- * using libdscfg, you must pass in -C tag to have
- * ctag_check pass.
- * finally a file. same rules as libdscfg.
- */
- if ((strlen(ctag) == 0) && (strlen(ctag_arg) > 0))
- (void) strcpy(ctag, ctag_arg);
-
- if (flag == RDC_CMD_RECONFIG) {
- if (reconfig_pbitmap) {
- (void) strncpy(frombitmap, reconfig_pbitmap,
- NSC_MAXPATH);
- check_rdcbitmap(flag, fromhost, frombitmap);
- }
- if (reconfig_sbitmap) {
- (void) strncpy(tobitmap, reconfig_sbitmap,
- NSC_MAXPATH);
- check_rdcbitmap(flag, tohost, tobitmap);
- }
-#ifdef _RDC_CAMPUS
- if (reconfig_direct)
- (void) strncpy(directfile, reconfig_direct,
- NSC_MAXPATH);
-#endif
- if (reconfig_group)
- (void) strncpy(group, reconfig_group,
- NSC_MAXPATH);
-
- if (strlen(reconfig_ctag) > 0)
- (void) strncpy(ctag, reconfig_ctag,
- MAX_RDC_HOST_SIZE);
- if (reconfig_doasync != -1)
- doasync = reconfig_doasync;
- }
-
- if (flag == RDC_CMD_ENABLE || flag == RDC_CMD_RECONFIG) {
- if (ctag_check(fromhost, fromfile, frombitmap,
- tohost, tofile, tobitmap, ctag, diskqueue) < 0)
- exit(1);
- if ((diskq_group = check_diskqueue(NULL, diskqueue,
- group)) == DISKQ_FAIL) {
- rdc_err(NULL, gettext("disk queue %s is "
- "incompatible with existing queue"),
- diskqueue);
- }
-
- }
- pairs = 1;
- } else {
- pairs = read_config(flag, config_file, group_arg, ctag_arg);
- if (pairs == 0) {
- rdc_err(NULL, gettext("%s contains no "
- "matching Remote Mirror sets"), config_file);
- }
- }
-
- if (!nflag && !pflag && prompt_user(flag, iflag) == -1)
- exit(1);
-
- while (pairs--) {
-
- if (cfgflag || fflag) {
- (void) strncpy(fromfile, pair_list[pairs].ffile,
- NSC_MAXPATH);
- (void) strncpy(tofile, pair_list[pairs].tfile,
- NSC_MAXPATH);
- (void) strncpy(frombitmap, pair_list[pairs].fbitmap,
- NSC_MAXPATH);
- (void) strncpy(fromhost,
- pair_list[pairs].fhost, MAX_RDC_HOST_SIZE);
- (void) strncpy(tohost, pair_list[pairs].thost,
- MAX_RDC_HOST_SIZE);
- (void) strncpy(tobitmap, pair_list[pairs].tbitmap,
- NSC_MAXPATH);
- (void) strncpy(directfile, pair_list[pairs].directfile,
- NSC_MAXPATH);
- (void) strncpy(group, pair_list[pairs].group,
- NSC_MAXPATH);
- (void) strncpy(ctag, pair_list[pairs].ctag,
- MAX_RDC_HOST_SIZE);
- (void) strncpy(diskqueue, pair_list[pairs].diskqueue,
- NSC_MAXPATH);
-
- bcopy(pair_list[pairs].fnetaddr, fromnetaddr,
- RDC_MAXADDR);
- bcopy(pair_list[pairs].tnetaddr, tonetaddr,
- RDC_MAXADDR);
-
- doasync = pair_list[pairs].doasync;
- }
-
- if (pflag) {
- static int first = 1;
-
- if (first) {
- if ((cfg = cfg_open(NULL)) == NULL)
- rdc_err(NULL,
- gettext("unable to access configuration"));
-
- if (!cfg_lock(cfg, CFG_RDLOCK))
- rdc_err(NULL,
- gettext("unable to lock configuration"));
-
- first = 0;
- }
-
- (void) rdc_print(file_format, verbose,
- group_arg, ctag_arg, tohost, tofile, cfg);
-
- if (pairs == 0) {
- cfg_close(cfg);
- exit(0);
- }
-
- /* short circuit the rest of the command loop */
- continue;
- }
- if (Bflag) {
- int ret;
- ret = rdc_bitmapset(tohost, tofile, bitfile, oflag,
- boffset);
- exit(ret);
- }
- if ((fflag || cfgflag) && flag == RDC_CMD_RECONFIG) {
- char orig_fbmp[MAXHOSTNAMELEN];
- char orig_tbmp[MAXHOSTNAMELEN];
- int ret;
- rdc_config_t parms;
- spcs_s_info_t ustatus;
-
- parms.command = RDC_CMD_STATUS;
- parms.rdc_set->netconfig = NULL;
- (void) strncpy(parms.rdc_set->primary.intf, fromhost,
- MAX_RDC_HOST_SIZE);
- (void) strncpy(parms.rdc_set->secondary.intf, tohost,
- MAX_RDC_HOST_SIZE);
- (void) strncpy(parms.rdc_set->primary.file, fromfile,
- NSC_MAXPATH);
- (void) strncpy(parms.rdc_set->secondary.file, tofile,
- NSC_MAXPATH);
- ustatus = spcs_s_ucreate();
- ret = RDC_IOCTL(RDC_CONFIG, &parms,
- NULL, 0, 0, 0, ustatus);
- if (ret != SPCS_S_OK) {
- rdc_err(NULL, gettext("unable to get set status"
- " before reconfig operation"));
- }
- (void) strncpy(orig_fbmp, parms.rdc_set->primary.bitmap,
- NSC_MAXPATH);
- (void) strncpy(orig_tbmp,
- parms.rdc_set->secondary.bitmap, NSC_MAXPATH);
-
- if (strncmp(orig_fbmp, frombitmap, NSC_MAXPATH) != 0)
- check_rdcbitmap(flag, fromhost, frombitmap);
- if (strncmp(orig_tbmp, tobitmap, NSC_MAXPATH) != 0)
- check_rdcbitmap(flag, tohost, tobitmap);
- spcs_s_ufree(&ustatus);
-
- }
- /*
- * take a peek in the config to see if
- * the bitmap is being used elsewhere
- */
- if (flag == RDC_CMD_ENABLE) {
- struct stat stb;
- /*
- * just for fun, lets see if some silly person
- * specified the same vol and bitmap
- */
- if ((strcmp(fromfile, frombitmap) == 0) ||
- (strcmp(tofile, tobitmap) == 0))
- rdc_err(NULL, gettext("volumes and bitmaps"
- " must not match"));
- if (self_check(fromhost)) {
- check_rdcbitmap(flag, fromhost, frombitmap);
- if (stat(fromfile, &stb) != 0) {
- rdc_err(NULL,
- gettext("unable to access %s: %s"),
- fromfile, strerror(errno));
- }
- if (!S_ISCHR(stb.st_mode)) {
- rdc_err(NULL,
- gettext("%s is not a character device"),
- fromfile);
- }
- } else { /* on the secondary */
- check_rdcbitmap(flag, tohost, tobitmap);
- /* extra check for secondary vol */
- check_rdcsecondary(tofile);
- if (stat(tofile, &stb) != 0) {
- rdc_err(NULL,
- gettext("unable to access %s: %s"),
- tofile, strerror(errno));
- }
- if (!S_ISCHR(stb.st_mode)) {
- rdc_err(NULL,
- gettext("%s is not a character device"),
- tofile);
- }
- }
-
- }
-
- if (flag == RDC_CMD_ENABLE || flag == RDC_CMD_DISABLE ||
- flag == RDC_CMD_RECONFIG) {
- if ((cfg = cfg_open(NULL)) == NULL)
- rdc_err(NULL,
- gettext("unable to access configuration"));
-
- if (!cfg_lock(cfg, CFG_WRLOCK))
- rdc_err(NULL,
- gettext("unable to lock configuration"));
-
- cfg_resource(cfg, clustered ? ctag : NULL);
- } else
- cfg = NULL;
-
- if (cfg && perform_autosv() &&
- (flag == RDC_CMD_ENABLE || flag == RDC_CMD_DISABLE ||
- flag == RDC_CMD_RECONFIG)) {
- if (cfg_load_svols(cfg) < 0 ||
- cfg_load_dsvols(cfg) < 0 ||
- cfg_load_shadows(cfg) < 0)
- rdc_err(NULL,
- gettext("Unable to parse config filer"));
- load_rdc_vols(cfg);
- }
- cfg_success = (cfg == NULL);
- if (cfg && flag == RDC_CMD_ENABLE) {
- /* Enabled, so add the set via libcfg */
-
- /* Build a new sndr entry and put it */
- group_p = *group? group : place_holder;
- diskqueue_p = *diskqueue? diskqueue : place_holder;
-
- if ((diskqueue_p == place_holder) &&
- (group_p != place_holder)) {
- get_group_diskq(cfg, group_p, diskqueue);
- if (*diskqueue)
- diskqueue_p = diskqueue;
- }
-
- /*
- * format in pconfig is:
- * phost.primary.pbitmap.shost.secondary.
- * sbitmap.type.mode.group.cnode.options.diskq
- */
- (void) snprintf(buf, sizeof (buf),
- "%s %s %s %s %s %s %s %s %s %s - %s",
- fromhost, fromfile, frombitmap, tohost, tofile,
- tobitmap, directfile,
- doasync? "async" : "sync", group_p,
- clustered? ctag : "-", diskqueue_p);
-
- if (cfg_put_cstring(cfg, "sndr", buf, strlen(buf)) < 0)
- rdc_warn(NULL,
- gettext("unable to add \"%s\" to "
- "configuration storage: %s"),
- buf, cfg_error(&sev));
- setnumber = find_setnumber_in_libcfg(cfg, clustered?
- ctag : NULL, tohost, tofile);
- if (setnumber < 0)
- rdc_warn(NULL,
- gettext("unable to add \"%s\" to "
- "configuration storage: %s"),
- diskqueue_p, cfg_error(&sev));
-
- else
- cfg_success = 1;
-
- /* Add cluster aware info */
- if (clustered && !rdc_islocal) {
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.options", setnumber);
- if (self_check(fromhost)) {
- if (cfg_put_options(cfg, CFG_SEC_CONF,
- key, "lghn", fromhost) < 0) {
- rdc_err(NULL,
- gettext("unable to add "
- "\"%s\" to configuration "
- "storage: %s"),
- fromhost, cfg_error(&sev));
- }
- } else if (self_check(tohost)) {
- if (cfg_put_options(cfg, CFG_SEC_CONF,
- key, "lghn", tohost) < 0) {
- rdc_err(NULL,
- gettext("unable to add "
- "\"%s\" to configuration "
- "storage: %s"),
- fromhost, cfg_error(&sev));
- }
- }
- }
- } else if (cfg && flag == RDC_CMD_DISABLE) {
- found = 0;
- /* Disabled, so delete the set via libcfg */
-
- /* get sndr entries until shost, sfile match */
- for (i = 0; i < rdc_maxsets; i++) {
- setnumber = i + 1;
- (void) snprintf(key, sizeof (key), "sndr.set%d",
- setnumber);
- if (cfg_get_cstring(cfg, key, buf,
- CFG_MAX_BUF) < 0) {
- break;
- }
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.secondary", setnumber);
- if (cfg_get_cstring(cfg, key, buf,
- CFG_MAX_BUF) < 0)
- break;
- if (strcmp(buf, tofile) != 0)
- continue;
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.shost",
- setnumber);
- if (cfg_get_cstring(cfg, key, buf,
- CFG_MAX_BUF) < 0)
- break;
- if (strcmp(buf, tohost) != 0)
- continue;
- found = 1;
-#ifdef DEBUG
- if (checksetfields == -1) {
- rdc_err(NULL,
- gettext("checksetfields not set"));
- }
-#endif
- if (checksetfields) {
- checkgfields(cfg, setnumber, fromhost,
- fromfile, frombitmap, tobitmap,
- directfile, (doasync == 1)
- ? "async" : "sync", group, ctag,
- diskqueue);
- }
-
- /* perform cluster specific options */
- if (clustered) {
- /* get the logical host, if set */
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.options", setnumber);
- (void) cfg_get_single_option(cfg,
- CFG_SEC_CONF, key, "lghn",
- lhname, MAX_RDC_HOST_SIZE);
-
- /* figure out the cluster tag, if any */
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.cnode", setnumber);
- if (cfg_get_cstring(cfg, key, buf,
- CFG_MAX_BUF) < 0)
- break;
- if (strcmp(buf, ctag))
- rdc_err(NULL, gettext("ctags %s"
- " and %s do not match"),
- buf, ctag);
- } else {
- *lhname = '\0';
- *ctag = '\0';
- }
-
- /* figure out the disk queue, if any */
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.diskq",
- setnumber);
- if (cfg_get_cstring(cfg, key, buf,
- CFG_MAX_BUF) < 0)
- break;
- if (strlen(buf) > 0) {
- (void) strncpy(diskqueue, buf,
- NSC_MAXPATH);
- } else {
- *diskqueue = '\0';
- }
- (void) snprintf(key, sizeof (key), "sndr.set%d",
- setnumber);
- if (cfg_put_cstring(cfg, key, NULL, 0) < 0)
- rdc_warn(NULL,
- gettext("unable to remove \"%s\" "
- "from configuration storage: %s"),
- buf, cfg_error(&sev));
- else
- cfg_success = 1;
- break;
- }
- if (found == 0) {
- rdc_err(NULL,
- gettext("Unable to find %s:%s in "
- "configuration storage"),
- tohost, tofile);
- }
- if (host_not_found) {
- rdc_force_disable(cfg, fromhost, fromfile,
- frombitmap, tohost, tofile, tobitmap, ctag,
- lhname);
- if (cfg_commit(cfg) < 0)
- rdc_err(NULL, gettext("commit on "
- "force disable failed"));
- cfg_close(cfg);
- return (0);
- }
- } else if (cfg && flag == RDC_CMD_RECONFIG) {
- /* Update relevant cfg record */
-
- cfg_resource(cfg, NULL);
-
- /* get sndr entries until shost, sfile match */
- for (i = 0; i < rdc_maxsets; i++) {
- setnumber = i + 1;
- (void) snprintf(key, sizeof (key), "sndr.set%d",
- setnumber);
- if (cfg_get_cstring(cfg, key, buf,
- CFG_MAX_BUF) < 0) {
- break;
- }
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.secondary", setnumber);
- if (cfg_get_cstring(cfg, key, buf,
- CFG_MAX_BUF) < 0)
- break;
- if (strcmp(buf, tofile) != 0)
- continue;
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.shost",
- setnumber);
- if (cfg_get_cstring(cfg, key, buf,
- CFG_MAX_BUF) < 0)
- break;
- if (strcmp(buf, tohost) != 0)
- continue;
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.cnode",
- setnumber);
- if (cfg_get_cstring(cfg, key, buf,
- CFG_MAX_BUF) < 0)
- break;
- if (reconfig_ctag[0] == '\0')
- (void) strncpy(ctag, buf,
- sizeof (ctag));
- if (doasync)
- (void) strcpy(mode, "async");
- else
- (void) strcpy(mode, "sync");
- if (strcmp(directfile, "") == 0)
- (void) strcpy(directfile, "ip");
-
- group_p = strlen(group) > 0 ? group :
- place_holder;
-
- /*
- * if we are reconfigging out altogether,
- * get rid of the diskqueue
- */
- if (group_p == place_holder)
- diskqueue_p = place_holder;
- else
- diskqueue_p = strlen(diskqueue) > 0 ?
- diskqueue : place_holder;
-
- /*
- * do a little diskq dance here for reconfigs
- * that did not specify the diskqueue whilst
- * reconfigging ...
- */
- if ((diskqueue_p == place_holder) &&
- (group_p != place_holder)) {
- get_group_diskq(cfg, group_p,
- diskqueue);
- diskqueue_p = strlen(diskqueue) > 0 ?
- diskqueue : place_holder;
- }
-
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.options", setnumber);
- if (cfg_get_cstring(cfg, key, options_cfg,
- CFG_MAX_BUF) < 0) {
- break;
- }
-
- ctag_p = strlen(ctag) > 0 ?
- ctag : place_holder;
- (void) snprintf(buf, sizeof (buf),
- "%s %s %s %s %s %s %s %s %s %s %s %s",
- fromhost, fromfile, frombitmap,
- tohost, tofile, tobitmap,
- directfile, mode, group_p,
- ctag_p, options_cfg, diskqueue_p);
-
- (void) snprintf(key, sizeof (key), "sndr.set%d",
- setnumber);
- if (cfg_put_cstring(cfg, key, buf,
- strlen(buf)) < 0)
- rdc_warn(NULL,
- gettext("unable to update \"%s\" "
- "in configuration storage: %s"),
- buf, cfg_error(&sev));
- else
- cfg_success = 1;
- break;
- }
- }
-
- if (cfg_success) {
- if (cfg && perform_autosv()) {
- if (self_check(fromhost)) {
- if (diskqueue[0] &&
- (strcmp(diskqueue, fromfile) == 0) ||
- (strcmp(diskqueue, frombitmap) == 0)) {
- rdc_err(NULL, gettext("disk "
- "queue volume %s must not "
- "match any primary Remote "
- "Mirror volume or bitmap"),
- diskqueue);
- }
-
- if (diskqueue[0]) {
- different_devs(fromfile, diskqueue);
- different_devs(frombitmap, diskqueue);
- validate_name(cfg, diskqueue);
- }
- different_devs(fromfile, frombitmap);
- validate_name(cfg, fromfile);
- validate_name(cfg, frombitmap);
- } else {
- different_devs(tofile, tobitmap);
- validate_name(cfg, tofile);
- validate_name(cfg, tobitmap);
- }
- }
- /*
- * okay, if the command is sync, just build
- * a list of rdcconfig_t's after the pairs--
- * loop is done, we will pass this list to
- * librdc to multithread the syncs (after
- * forking off a daemonish type process
- * that waits for the libcall to complete
- * ints of interest:
- * flag ie RDC_CMD_COPY, iflag RDC_OPT_UPDATE,
- * reverse RDC_OPT_REVERSE, RDC_OPT_FORWARD
- * if necessary, turn autosync back on
- */
- if (flag == RDC_CMD_COPY) {
- if (autosync_is_on(tohost, tofile) ==
- AUTOSYNC_ON)
- enable_autosync(fromhost, fromfile,
- tohost, tofile);
-
- if (sets == NULL) {
- sets_p = sets =
- rdc_alloc_config(fromhost, fromfile,
- frombitmap, tohost, tofile,
- tobitmap, "mode", "group", "ctag",
- "options", 0);
-
- if (sets_p == NULL) {
- rdc_err(NULL,
- gettext("rdc config alloc"
- "failed %s"), rdc_error(NULL));
- }
- continue;
- }
-
- sets_p = sets_p->next =
- rdc_alloc_config(fromhost, fromfile,
- frombitmap, tohost, tofile, tobitmap,
- "mode", "group", "ctag", "options", 0);
-
- if (sets_p == NULL) {
- rdc_err(NULL, gettext("rdc config alloc"
- "failed %s"), rdc_error(NULL));
- }
- continue;
- }
-
- /*
- * block incoming signals until after the possible
- * cfg_commit is done
- */
- block_sigs();
- if (rdc_operation(cfg, fromhost, fromfile, frombitmap,
- tohost, tofile, tobitmap, flag, iflag, directfile,
- group, ctag, diskqueue, &doasync, reverse) < 0) {
- ;
- /*EMPTY*/
- } else if (cfg) {
- if (diskq_group == DISKQ_REWRITEG) {
- rewrite_group_diskqueue(cfg,
- &pair_list[pairs], diskqueue);
- }
- if (perform_autosv() &&
- (flag == RDC_CMD_ENABLE ||
- flag == RDC_CMD_DISABLE ||
- flag == RDC_CMD_RECONFIG)) {
- unload_rdc_vols();
- cfg_unload_shadows();
- cfg_unload_dsvols();
- cfg_unload_svols();
- }
- if ((iflag & RDC_OPT_REVERSE_ROLE) != 0 &&
- allow_role) {
- bzero(tmphost, MAX_RDC_HOST_SIZE);
- bzero(tmpfile, NSC_MAXPATH);
- bzero(tmpbitmap, NSC_MAXPATH);
- (void) strncpy(tmphost, fromhost,
- MAX_RDC_HOST_SIZE);
- (void) strncpy(tmpfile, fromfile,
- NSC_MAXPATH);
- (void) strncpy(tmpbitmap, frombitmap,
- NSC_MAXPATH);
-
- (void) strncpy(fromhost, tohost,
- MAX_RDC_HOST_SIZE);
- (void) strncpy(fromfile, tofile,
- NSC_MAXPATH);
- (void) strncpy(frombitmap, tobitmap,
- NSC_MAXPATH);
-
- (void) strncpy(tohost, tmphost,
- MAX_RDC_HOST_SIZE);
- (void) strncpy(tofile, tmpfile,
- NSC_MAXPATH);
- (void) strncpy(tobitmap, tmpbitmap,
- NSC_MAXPATH);
- group_p = strlen(group) > 0 ? group :
- place_holder;
- diskqueue_p = strlen(diskqueue) > 0 ?
- diskqueue : place_holder;
- ctag_p = strlen(ctag) > 0 ?
- ctag : place_holder;
- (void) snprintf(buf, sizeof (buf), "%s "
- "%s %s %s %s %s %s %s %s %s %s %s",
- fromhost, fromfile, frombitmap,
- tohost, tofile, tobitmap,
- directfile, mode, group_p,
- ctag_p, options_cfg, diskqueue_p);
-
- (void) snprintf(key, sizeof (key),
- "sndr.set%d", setnumber);
- if (cfg_put_cstring(cfg, key, buf,
- strlen(buf)) < 0)
- rdc_err(NULL,
- gettext("unable to update \"%s\" "
- "in configuration storage: %s"),
- buf, cfg_error(&sev));
- }
- if (cfg_commit(cfg) < 0) {
- rdc_err(NULL, gettext("commit on role "
- "reversal failed"));
- }
- }
- unblock_sigs();
- }
-
- if (cfg) {
- cfg_close(cfg);
- }
-
- }
- if (flag == RDC_CMD_COPY) {
- pid = fork();
- if (pid == -1) { /* error forking */
- perror("fork");
- exit(1);
- }
- } else {
- exit(0);
- }
- if (pid > 0) /* parent process */
- exit(0);
-
- spcslog_sync(sets, 1, iflag);
- if (iflag & RDC_OPT_REVERSE) {
- if (iflag & RDC_OPT_UPDATE)
- rclist = rdc_ursync(sets);
- else
- rclist = rdc_rsync(sets);
- } else if (iflag & RDC_OPT_UPDATE) {
- rclist = rdc_usync(sets);
- } else
- rclist = rdc_fsync(sets);
-
- rcp = rclist;
- while (rcp) {
- if (rcp->rc < 0) {
- /* rclist->msg has already been gettext'd */
- (void) fprintf(stderr,
- gettext("Remote Mirror: %s %s %s %s %s %s\n"),
- rcp->set.phost, rcp->set.pfile, rcp->set.pbmp,
- rcp->set.shost, rcp->set.sfile, rcp->set.sbmp);
- rdc_warn(NULL, "%s", rcp->msg);
- spcs_log("sndr", NULL, "%s", rcp->msg);
- }
- rcp = rcp->next;
- }
-
- spcslog_sync(sets, 0, iflag);
-
- if (sets)
- rdc_free_config(sets, RDC_FREEALL);
- if (rclist)
- rdc_free_rclist(rclist);
-
- return (0);
-}
-/*
- * process_clocal()
- * pre: a non null string
- * post: if the string is "local"
- * then it is converted to "-"
- * and rdc_islocal is set to 1
- * if not rdc_islocal set to 0
- */
-void
-process_clocal(char *ctag)
-{
- /*
- * Check for the special cluster tag and convert into the
- * internal representation.
- */
-
- if (ctag != NULL && strcmp(ctag, RDC_LOCAL_TAG) == 0) {
- (void) strcpy(ctag, "-");
- rdc_islocal = 1;
- } else {
- rdc_islocal = 0;
- }
-}
-
-static void
-rdc_check_dgislocal(char *dgname)
-{
- char *othernode;
- int rc;
-
- /*
- * check where this disk service is mastered
- */
-
- rc = cfg_dgname_islocal(dgname, &othernode);
- if (rc < 0) {
- rdc_err(NULL, gettext("unable to find "
- "disk service, %s: %s"), dgname, strerror(errno));
- }
-
- if (rc == 0) {
- rdc_err(NULL, gettext("disk service, %s, is "
- "active on node \"%s\"\nPlease re-issue "
- "the command on that node"), dgname, othernode);
- }
-}
-
-static void
-different_devs(char *dev1, char *dev2)
-{
- struct stat buf1, buf2;
-
- if (stat(dev1, &buf1) < 0) {
- spcs_log("sndr", NULL, gettext("Remote Mirror: can't stat %s"),
- dev1);
- rdc_err(NULL, gettext("Remote Mirror: can't stat %s"), dev1);
- }
- if (stat(dev2, &buf2) < 0) {
- spcs_log("sndr", NULL, gettext("Remote Mirror: can't stat %s"),
- dev2);
- rdc_err(NULL, gettext("Remote Mirror: can't stat %s"), dev2);
- }
- if (buf1.st_rdev == buf2.st_rdev) {
- spcs_log("sndr", NULL, gettext("Remote Mirror: '%s' and '%s' "
- "refer to the same device"), dev1, dev2);
- rdc_err(NULL, gettext("Remote Mirror: '%s' and '%s' refer to "
- "the same device"), dev1, dev2);
- }
-}
-
-static void
-validate_name(CFGFILE *cfg, char *vol)
-{
- char *altname;
- int rc;
-
- if (!cfg) {
- rdc_err(NULL, gettext("Remote Mirror: null cfg ptr in "
- "validate_name"));
- }
-
- rc = cfg_get_canonical_name(cfg, vol, &altname);
- if (rc < 0) {
- spcs_log("sndr", NULL, gettext("Remote Mirror: unable to parse "
- "config file\n"));
- rdc_err(NULL, gettext("Remote Mirror: unable to parse config "
- "file\n"));
- }
- if (rc) {
- spcs_log("sndr", NULL, gettext("Remote Mirror: '%s': already "
- "configured as '%s'"), vol, altname);
- rdc_err(NULL, gettext("Remote Mirror: The volume '%s' has been "
- "configured previously as '%s'. Re-enter command with "
- "the latter name."), vol, altname);
- }
-}
-
-/*
- * Add the autosync value to the option field for the sndr set specified by
- * tohost:tofile.
- *
- * ASSUMPTIONS:
- * - cfg file is available to take a write lock.
- * - set is already configured in dscfg
- *
- * INPUTS:
- * autosync_val - value to set autosync to
- * tohost - secondary host
- * tofile - secondary volume
- *
- * OUTPUTS:
- * none.
- *
- */
-static void
-set_autosync(int autosync_val, char *tohost, char *tofile, char *ctag)
-{
- CFGFILE *cfg;
- char key[CFG_MAX_KEY], buf[CFG_MAX_BUF];
- char tag[CFG_MAX_BUF], val[CFG_MAX_BUF];
- char auto_tag[CFG_MAX_BUF];
- _sd_dual_pair_t pair;
- _sd_dual_pair_t tmpair;
- int setnumber, options = 0, already_set = 0, cfg_success = 0;
- int set;
-
- /* verify valid autosync request */
- if ((autosync_val != AUTOSYNC_ON) && (autosync_val != AUTOSYNC_OFF)) {
-#ifdef DEBUG
- rdc_warn(NULL,
- gettext("set_autosync called with improper value"));
-#endif
- return;
- }
-
- if ((cfg = cfg_open(NULL)) == NULL) {
- rdc_err(NULL, gettext("unable to access configuration"));
- }
- if (!cfg_lock(cfg, CFG_WRLOCK)) {
- rdc_err(NULL, gettext("unable to lock configuration"));
- }
-
- if (clustered) {
- cfg_resource(cfg, ctag);
- } else {
- cfg_resource(cfg, NULL);
- }
-
- /* find set number in config */
- if ((setnumber = find_setnumber_in_libcfg(cfg, clustered? ctag : NULL,
- tohost, tofile)) < 0) {
- cfg_close(cfg);
- rdc_err(NULL, gettext("unable to find Remote Mirror set %s:%s: "
- "in config"), tohost, tofile);
- }
- (void) snprintf(key, sizeof (key), "sndr.set%d.options", setnumber);
- (void) snprintf(auto_tag, sizeof (auto_tag), "auto");
-
- /* Check if there are any options already set, including ours */
- if (cfg_get_options(cfg, CFG_SEC_CONF, key, tag, CFG_MAX_BUF, val,
- CFG_MAX_BUF) >= 0) {
- options = 1;
-
- do {
- if (strcmp(tag, auto_tag) == 0) {
- already_set = 1;
- }
- } while (cfg_get_options(cfg, CFG_SEC_CONF, NULL, tag,
- CFG_MAX_BUF, val, CFG_MAX_BUF) >= 0);
- }
-
- /* options already exist, edit ours out */
- if (options && already_set) {
- char *p, *q;
- int need_to_clear_buf = 1;
-
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) {
- rdc_err(NULL, gettext("unable to get options field "
- "for Remote Mirror set %s:%s"), tohost, tofile);
- }
-
- /* parse out our options, all of the form "auto=" */
- p = strdup(buf);
- bzero(buf, sizeof (buf));
-
- q = strtok(p, ";");
- do {
- /* if another tag/value exists, keep it */
- if (strncmp(auto_tag, q, 4) != 0) {
- (void) strcat(buf, q);
- (void) strcat(buf, ";");
- need_to_clear_buf = 0;
- }
- } while (q = strtok(NULL, ";"));
- free(p);
-
- /* if we were the only option, clear the field */
- if (need_to_clear_buf) {
- (void) strcat(buf, "-");
- }
-
- if (cfg_put_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) {
- rdc_err(NULL, gettext("unable to clear autosync value "
- "in config for Remote Mirror set %s:%s"), tohost,
- tofile);
- } else {
- cfg_success = 1;
- }
- }
-
- /* autosync is not present in options field, add if on is requested */
- if (autosync_val == AUTOSYNC_ON) {
- if (cfg_put_options(cfg, CFG_SEC_CONF, key, auto_tag, "on")
- < 0) {
- rdc_err(NULL, gettext("unable to update autosync value "
- "in config for Remote Mirror set %s:%s"), tohost,
- tofile);
- } else {
- cfg_success = 1;
- }
- }
- /* if we are in a group, update any other sets in the same group */
- do {
- bzero(&pair, sizeof (pair));
- bzero(buf, CFG_MAX_BUF);
-
- (void) snprintf(key, sizeof (key), "sndr.set%d", setnumber);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) {
- break;
- }
- if (parse_cfg_buf(buf, &pair, NULL))
- break;
- if (pair.group == NULL) /* not in a group */
- break;
- if (!pair.group[0])
- break; /* not in a group */
- for (set = 1; /*CSTYLED*/; set++) {
- if (set == setnumber)
- continue;
- bzero(buf, CFG_MAX_BUF);
- options = 0;
- already_set = 0;
-
- (void) snprintf(key, sizeof (key), "sndr.set%d", set);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) {
- break; /* last set processed */
- }
- bzero(&tmpair, sizeof (tmpair));
- if (parse_cfg_buf(buf, &tmpair, NULL))
- break;
- if (strcmp(pair.group, tmpair.group) != 0)
- continue; /* not the group we want */
-
- (void) snprintf(key, sizeof (key), "sndr.set%d.options",
- set);
- /*
- * Check if there are any options already set,
- * including ours
- */
- if (cfg_get_options(cfg, CFG_SEC_CONF, key, tag,
- CFG_MAX_BUF, val, CFG_MAX_BUF) >= 0) {
- options = 1;
-
- do {
- if (strcmp(tag, auto_tag) == 0) {
- already_set = 1;
- }
- } while (cfg_get_options(cfg, CFG_SEC_CONF,
- NULL, tag, CFG_MAX_BUF, val,
- CFG_MAX_BUF) >= 0);
- }
-
- /* options already exist, edit ours out */
- if (options && already_set) {
- char *p, *q;
- int need_to_clear_buf = 1;
-
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF)
- < 0) {
- rdc_err(NULL, gettext("unable to get "
- "options field for Remote Mirror set "
- "%s:%s"), tmpair.thost, tmpair.tfile);
- }
-
- /*
- * parse out our options, all of the
- * form "auto="
- */
- p = strdup(buf);
- bzero(buf, sizeof (buf));
-
- q = strtok(p, ";");
- do {
- /*
- * if another tag/value exists,
- * keep it
- */
- if (strncmp(auto_tag, q, 4) != 0) {
- (void) strcat(buf, q);
- (void) strcat(buf, ";");
- need_to_clear_buf = 0;
- }
- } while (q = strtok(NULL, ";"));
- free(p);
-
- /*
- * if we were the only option,
- * clear the field
- */
- if (need_to_clear_buf) {
- (void) strcat(buf, "-");
- }
-
- if (cfg_put_cstring(cfg, key, buf, CFG_MAX_BUF)
- < 0) {
- rdc_err(NULL, gettext("unable to clear "
- "autosync value in config for "
- "Remote Mirror set %s:%s"),
- tmpair.thost, tmpair.tfile);
- cfg_success = 0;
- }
- }
-
- /*
- * autosync is not present in options field,
- * add if on is requested
- */
- if (autosync_val == AUTOSYNC_ON) {
- if (cfg_put_options(cfg, CFG_SEC_CONF, key,
- auto_tag, "on") < 0) {
- rdc_err(NULL, gettext("unable to update"
- " autosync value in config for "
- "Remote Mirror set %s:%s"),
- tmpair.thost,
- tmpair.tfile);
- cfg_success = 0;
- }
- }
- }
-
- /* CONSTCOND */
- } while (0);
- if (cfg_success) {
- if (cfg_commit(cfg) < 0) {
- rdc_err(NULL, gettext("commit on role reversal failed"));
- }
- }
-
- cfg_close(cfg);
-}
-
-/*
- * Check to see if autosync is on for set specified by tohost:tofile.
- *
- * ASSUMPTIONS:
- * config is available to take a read lock against it.
- *
- * INPUTS:
- * tohost - secondary host
- * tofile - secondary volume
- *
- * OUTPUTS:
- * -1 error
- * AUTOSYNC_ON if autosync is on
- * AUTOSYNC_OFF if autosync is off
- */
-static int
-autosync_is_on(char *tohost, char *tofile)
-{
- CFGFILE *cfg;
- int setnumber, autosync_val = AUTOSYNC_OFF;
- char key[CFG_MAX_KEY];
- char tag[CFG_MAX_BUF], val[CFG_MAX_BUF];
-
- if ((cfg = cfg_open(NULL)) == NULL) {
- rdc_err(NULL, gettext("unable to access configuration"));
- }
-
- if (!cfg_lock(cfg, CFG_RDLOCK)) {
- cfg_close(cfg);
- rdc_err(NULL, gettext("unable to lock configuration"));
- }
-
- if ((setnumber = find_setnumber_in_libcfg(cfg, NULL, tohost, tofile)) <
- 0) {
- cfg_close(cfg);
- rdc_err(NULL, gettext("cannot find Remote Mirror set %s:%s in "
- "config"), tohost, tofile);
- }
-
- (void) snprintf(key, CFG_MAX_KEY, "sndr.set%d.options", setnumber);
- if (cfg_get_options(cfg, CFG_SEC_CONF, key, tag, CFG_MAX_BUF, val,
- CFG_MAX_BUF) >= 0) {
- do {
- if (strcmp(tag, "auto") == 0) {
- if (strcmp(val, "on") == 0) {
- autosync_val = AUTOSYNC_ON;
- }
- break;
- }
- } while (cfg_get_options(cfg, CFG_SEC_CONF, NULL, tag,
- CFG_MAX_BUF, val, CFG_MAX_BUF) >= 0);
- }
-
- cfg_close(cfg);
- return (autosync_val);
-}
-
-void
-enable_autosync(char *fhost, char *ffile, char *thost, char *tfile)
-{
- rdc_config_t parms;
- spcs_s_info_t ustat;
- rdc_addr_t *p;
-
- ustat = spcs_s_ucreate();
- parms.command = RDC_CMD_TUNABLE;
-
- p = &parms.rdc_set[0].primary;
- (void) strncpy(p->intf, fhost, MAX_RDC_HOST_SIZE);
- (void) strncpy(p->file, ffile, MAX_RDC_HOST_SIZE);
-
- p = &parms.rdc_set[0].secondary;
- (void) strncpy(p->intf, thost, NSC_MAXPATH);
- (void) strncpy(p->file, tfile, NSC_MAXPATH);
-
- parms.rdc_set[0].autosync = 1;
- parms.rdc_set[0].maxqfbas = -1;
- parms.rdc_set[0].maxqitems = -1;
- parms.rdc_set[0].asyncthr = -1;
- parms.rdc_set[0].netconfig = NULL;
-
- if ((RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, ustat)) !=
- SPCS_S_OK) {
- rdc_warn(&ustat, gettext("failed to update autosync for"
- " Remote Mirror set %s:%s"), thost, tfile);
- spcs_log("sndr", &ustat, gettext("failed to update autosync for"
- " Remote Mirror set %s:%s"), thost, tfile);
- }
- spcs_s_ufree(&ustat);
-}
-
-static int
-rdc_operation(CFGFILE *cfg, char *fromhost, char *fromfile, char *frombitmap,
- char *tohost, char *tofile, char *tobitmap,
- int flag, int iflag,
- char *directfile, char *group, char *ctag, char *diskqueue,
- int *doasync, int reverse)
-{
- const int getaddr = (flag == RDC_CMD_ENABLE);
- const int rpcbind = !getaddr;
- rdc_config_t parms;
- int ret;
- spcs_s_info_t ustatus;
- struct hostent *hp;
- char fromname[MAXHOSTNAMELEN], toname[MAXHOSTNAMELEN];
- char orig_fbmp[MAXHOSTNAMELEN], orig_tbmp[MAXHOSTNAMELEN];
- char orig_diskq[NSC_MAXPATH];
- struct t_info tinfo;
- int success = 1;
- int autosync_toggle_needed = 0;
- char *vol1, *vol2, *vol3;
-
- conf = &nconf;
-
- hp = gethost_byname(fromhost);
- (void) strncpy(fromname, hp->h_name, MAXHOSTNAMELEN);
- hp = gethost_byname(tohost);
- (void) strncpy(toname, hp->h_name, MAXHOSTNAMELEN);
-
- if (self_check(fromname) && self_check(toname)) {
- rdc_err(NULL, gettext("both %s and %s are local"),
- fromhost, tohost);
- }
-
- /* we have to find out what to sv disable after reconfig */
- if (flag == RDC_CMD_RECONFIG) {
-
- parms.command = RDC_CMD_STATUS;
- parms.rdc_set->netconfig = NULL;
- (void) strncpy(parms.rdc_set->primary.intf, fromhost,
- MAX_RDC_HOST_SIZE);
- (void) strncpy(parms.rdc_set->secondary.intf, tohost,
- MAX_RDC_HOST_SIZE);
- (void) strncpy(parms.rdc_set->primary.file, fromfile,
- NSC_MAXPATH);
- (void) strncpy(parms.rdc_set->secondary.file, tofile,
- NSC_MAXPATH);
- ustatus = spcs_s_ucreate();
- ret = RDC_IOCTL(RDC_CONFIG, &parms,
- NULL, 0, 0, 0, ustatus);
- if (ret != SPCS_S_OK) {
- rdc_err(NULL, gettext("unable to get set status"
- " before reconfig operation"));
- }
- (void) strncpy(orig_fbmp, parms.rdc_set->primary.bitmap,
- NSC_MAXPATH);
- (void) strncpy(orig_tbmp, parms.rdc_set->secondary.bitmap,
- NSC_MAXPATH);
- (void) strncpy(orig_diskq, parms.rdc_set->disk_queue,
- NSC_MAXPATH);
- }
-
- /*
- * another terrible addition, if we are reconfigging mode
- * and not logging, just give up.
- */
- if ((reconfig_doasync != -1) &&
- (!(parms.rdc_set->flags & RDC_LOGGING))) {
- rdc_err(NULL, gettext("cannot reconfigure sync/async, "
- "Remote Mirror set not logging"));
- spcs_log("sndr", NULL, gettext("cannot reconfigure sync/async, "
- "Remote Mirror set not logging"));
- }
-
- /*
- * Now build up the address for each host including port and transport
- */
- if (getaddr) {
- svp = get_addr(toname, RDC_PROGRAM, RDC_VERS_MIN,
- &conf, proto_test ? NC_UDP:NULL, "rdc", &tinfo,
- rpcbind);
-
- if (svp == NULL) {
- rdc_warn(NULL, gettext("unable to determine network "
- "information for %s"), toname);
-#ifdef DEBUG
- (void) printf("get_addr failed for Ver 4 %s\n", toname);
-#endif
- return (-1);
- }
- svaddr = *svp;
- } else {
- bzero(&svaddr, sizeof (svaddr));
- }
-
- parms.rdc_set->secondary.addr.len = svaddr.len;
- parms.rdc_set->secondary.addr.maxlen =
- svaddr.maxlen;
- parms.rdc_set->secondary.addr.buf =
- (void *)svaddr.buf;
-
-#ifdef DEBUG_ADDR
- (void) fprintf(stderr, "secondary buf %x len %d\n",
- svaddr.buf, svaddr.len);
-
- for (i = 0; i < svaddr.len; i++)
- (void) printf("%u ", svaddr.buf[i]);
- (void) printf("\n");
-#endif
-
- if (getaddr) {
- svp = get_addr(fromname, RDC_PROGRAM, RDC_VERS_MIN,
- &conf, proto_test ? NC_UDP: NULL, "rdc", &tinfo,
- rpcbind);
- if (svp == NULL) {
-#ifdef DEBUG
- (void) printf("get_addr failed for Ver 4 %s\n",
- fromname);
-#endif
- return (-1);
- }
- svaddr = *svp;
- }
-
- parms.rdc_set->primary.addr.len = svaddr.len;
- parms.rdc_set->primary.addr.maxlen = svaddr.maxlen;
- parms.rdc_set->primary.addr.buf = (void *)svaddr.buf;
-
-#ifdef DEBUG_ADDR
- (void) fprintf(stderr, "primary buf %x len %d\n",
- svaddr.buf, svaddr.len);
- for (i = 0; i < svaddr.len; i++)
- (void) printf("%u ", svaddr.buf[i]);
- (void) printf("\n");
-#endif
-
- if (getaddr) {
- (void) convert_nconf_to_knconf(conf, &knconf);
-#ifdef DEBUG_ADDR
- (void) printf("knconf %x %s %s %x\n", knconf.knc_semantics,
- knconf.knc_protofmly, knconf.knc_proto, knconf.knc_rdev);
-#endif
- parms.rdc_set->netconfig = &knconf;
- } else {
- parms.rdc_set->netconfig = NULL;
- }
-
- if (!self_check(fromname) && !self_check(toname)) {
- if (!clustered)
- rdc_err(NULL, gettext("neither %s nor %s is local"),
- fromhost, tohost);
- else {
- /*
- * IF we could get a list of logical hosts on this cluster
- * Then we could print something intelligent about where
- * the volume is mastered. For now, just print some babble
- * about the fact that we have no idea.
- */
- rdc_err(NULL,
- gettext("either %s:%s or %s:%s is not local"),
- fromhost, fromfile, tohost, tofile);
- }
- }
-
- (void) strncpy(parms.rdc_set->primary.intf, fromhost,
- MAX_RDC_HOST_SIZE);
- (void) strncpy(parms.rdc_set->primary.file, fromfile, NSC_MAXPATH);
- (void) strncpy(parms.rdc_set->primary.bitmap, frombitmap, NSC_MAXPATH);
-
- (void) strncpy(parms.rdc_set->secondary.intf, tohost,
- MAX_RDC_HOST_SIZE);
- (void) strncpy(parms.rdc_set->secondary.file, tofile, NSC_MAXPATH);
- (void) strncpy(parms.rdc_set->secondary.bitmap, tobitmap, NSC_MAXPATH);
-
- if ((group == NULL) || ((strcmp(group, "-")) == 0))
- parms.rdc_set->group_name[0] = 0;
- else
- (void) strncpy(parms.rdc_set->group_name, group, NSC_MAXPATH);
-
- if (self_check(tohost) &&
- (strlen(diskqueue) > 0) && (diskqueue[0] != '-'))
- if ((flag == RDC_CMD_ENABLE) || (flag == RDC_CMD_ADDQ))
- rdc_err(NULL, gettext("enabling disk queue on a Remote"
- " Mirror secondary is not allowed (%s)"),
- diskqueue);
-
- if ((diskqueue == NULL) || ((strcmp(diskqueue, "-")) == 0))
- parms.rdc_set->disk_queue[0] = 0;
- else
- (void) strncpy(parms.rdc_set->disk_queue, diskqueue,
- NSC_MAXPATH);
-
- parms.rdc_set->maxqfbas = maxqfbas;
- parms.rdc_set->maxqitems = maxqitems;
- parms.rdc_set->asyncthr = asyncthr;
- /* set up the permanent set id for this set */
- if (flag == RDC_CMD_ENABLE) {
- char key[CFG_MAX_KEY];
- char setid[64];
- int set;
- parms.rdc_set->setid = get_new_cfg_setid(cfg);
- if (parms.rdc_set->setid <= 0) {
- rdc_err(NULL, gettext("unable to obtain unique set id "
- "for %s:%s"), tohost, tofile);
- }
- if ((set = find_setnumber_in_libcfg(cfg, clustered? ctag : NULL,
- tohost, tofile)) < 0) {
- rdc_err(NULL, gettext("unable to store unique set id"
- " for %s:%s"), tohost, tofile);
- }
- (void) snprintf(key, sizeof (key), "sndr.set%d.options", set);
- (void) snprintf(setid, sizeof (setid), "%d",
- parms.rdc_set->setid);
-
- if (cfg_put_options(cfg, CFG_SEC_CONF, key, "setid",
- setid) < 0) {
- rdc_err(NULL, gettext("unable to store unique set "
- "id for %s:%s: %s"), tohost, tofile,
- gettext(cfg_error(NULL)));
- }
- } else if (flag != RDC_CMD_DISABLE) { /* set already gone from cfg */
- parms.rdc_set->setid = get_cfg_setid(cfg, ctag, tohost, tofile);
- if (parms.rdc_set->setid <= 0) {
- rdc_err(NULL, gettext("unable to obtain unique set id "
- "for %s:%s"), tohost, tofile);
- }
- }
-
- /*
- * Always set autosync flag to default so nothing gets messed up. If
- * we are doing an autosync operation, it'll all get taken care of
- * then.
- */
- parms.rdc_set->autosync = AUTOSYNC;
-
-
- /* gethostid(3c) is defined to return a 32bit value */
- parms.rdc_set->syshostid = (int32_t)gethostid();
-
- parms.command = 0;
- parms.options = iflag;
- parms.command = flag;
- if (flag == RDC_CMD_ENABLE || flag == RDC_CMD_RECONFIG) {
- if (*doasync)
- parms.options |= RDC_OPT_ASYNC;
- else
- parms.options |= RDC_OPT_SYNC;
- } else if (flag == RDC_CMD_COPY) {
- if (reverse)
- parms.options |= RDC_OPT_REVERSE;
- else
- parms.options |= RDC_OPT_FORWARD;
- }
-
- if (self_check(fromname)) {
- if (flag == RDC_CMD_COPY && reverse && mounted(fromfile))
- rdc_err(NULL, gettext("can not start reverse sync"
- " as a file system is mounted on %s"),
- fromfile);
- parms.options |= RDC_OPT_PRIMARY;
- if (strcmp(directfile, "ip") == 0)
- parms.rdc_set->direct_file[0] = 0; /* no directfile */
- else
- (void) strncpy(parms.rdc_set->direct_file, directfile,
- NSC_MAXPATH);
- } else {
- parms.options |= RDC_OPT_SECONDARY;
- parms.rdc_set->direct_file[0] = 0; /* no fcal directio */
- }
-
- if ((asyncthr || maxqitems || maxqfbas || qblock) &&
- (parms.options & RDC_OPT_SECONDARY)) {
- rdc_err(NULL, gettext("changing queue parameters may "
- " only be done on a primary Remote Mirror host"));
- spcs_log("sndr", NULL, gettext("changing queue parameters may "
- " only be done on a primary Remote Mirror host"));
-
- }
-
- ustatus = spcs_s_ucreate();
-
- if (flag == RDC_CMD_COPY) {
- parms.command = RDC_CMD_STATUS;
- ret = RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, ustatus);
- if ((ret != SPCS_S_OK) ||
- !(parms.rdc_set->flags & RDC_LOGGING)) {
- rdc_err(NULL, gettext("can not start sync"
- " as Remote Mirror set %s:%s is not logging"),
- tohost, tofile);
- }
- spcs_log("sndr", NULL,
- gettext("%s %s %s %s %s %s %s %s\nStarting"),
- program, rdc_decode_flag(flag, parms.options),
- fromhost, fromfile, frombitmap,
- tohost, tofile, tobitmap);
- parms.command = RDC_CMD_COPY;
- }
-
- if ((flag == RDC_CMD_COPY) &&
- (autosync_is_on(tohost, tofile) == AUTOSYNC_ON)) {
- /* check if autosync needs to be turned on when doing a copy/update */
- parms.rdc_set->autosync = AUTOSYNC_ON;
- autosync_toggle_needed = 1;
- } else if ((flag == RDC_CMD_LOG) &&
- (autosync_is_on(tohost, tofile) == AUTOSYNC_ON)) {
- /* check if autosync needs to be turned off when going to logging */
- parms.rdc_set->autosync = AUTOSYNC_OFF;
- autosync_toggle_needed = 1;
- } else if (((autosync == AUTOSYNC_ON) || (autosync == AUTOSYNC_OFF)) &&
- (flag == RDC_CMD_TUNABLE)) {
- /*
- * Request to change the autosync value. cfg file will be
- * available at this point. If autosync request is to turn off,
- * mark off in both the config and the kernel regardless of
- * the state of the set. If the request is to turn autosync on,
- * set in the kernel if the set is not in logging mode.
- *
- * XXX
- * If the set is in logging mode because of a network
- * failure, we will not know. Therefore, a manual update
- * will have to be issued to enable autosync in the
- * kernel.
- * XXX
- */
- set_autosync(autosync, tohost, tofile, ctag);
-
- if (autosync == AUTOSYNC_OFF) {
- parms.rdc_set->autosync = AUTOSYNC_OFF;
- } else if (autosync == AUTOSYNC_ON) {
- parms.command = RDC_CMD_STATUS;
- ret = RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0,
- ustatus);
- if (ret != SPCS_S_OK) {
- rdc_err(NULL, gettext("can not determine "
- "status of Remote Mirror set %s:%s"),
- tohost, tofile);
- }
-
- /* need to reset the tunables after a status ioctl */
- parms.rdc_set->autosync = autosync;
- parms.rdc_set->maxqfbas = maxqfbas;
- parms.rdc_set->maxqitems = maxqitems;
- parms.rdc_set->asyncthr = asyncthr;
-
- /*
- * if in logging mode, just update config, kernel will
- * be updated with the next copy/update request.
- */
- if (parms.rdc_set->flags & RDC_LOGGING) {
- parms.rdc_set->autosync = AUTOSYNC;
- } else {
- parms.rdc_set->autosync = AUTOSYNC_ON;
- }
-
- parms.command = flag;
- }
- }
-
- if (autosync_toggle_needed) {
- parms.command = RDC_CMD_TUNABLE;
- ret = RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, ustatus);
- if (ret != SPCS_S_OK) {
- spcs_log("sndr", NULL, gettext("failed to update "
- "autosync for Remote Mirror set %s:%s"), tohost,
- tofile);
- rdc_err(NULL, gettext("failed to update autosync for "
- "Remote Mirror set %s:%s"), tohost, tofile);
- }
- /* reset command and default autosync flags */
- parms.rdc_set->autosync = AUTOSYNC;
- parms.command = flag;
- }
-
- errno = 0;
- ret = RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, ustatus);
- if ((ret != SPCS_S_OK) && (flag != RDC_CMD_HEALTH)) {
- (void) fprintf(stderr,
- gettext("Remote Mirror: %s %s %s %s %s %s\n"),
- fromhost, fromfile,
- frombitmap, tohost, tofile, tobitmap);
-
- if (errno == RDC_EEINVAL) {
- spcs_log("sndr", NULL,
- "%s %s %s %s %s %s %s %s\n%s",
- program, rdc_decode_flag(flag, parms.options),
- fromhost, fromfile, frombitmap,
- tohost, tofile, tobitmap,
- gettext("invalid command option"));
- rdc_err(&ustatus,
- gettext("Remote Mirror: invalid command option "
- "'%s'"), rdc_decode_flag(flag,
- parms.options));
- } else {
- spcs_log("sndr", &ustatus,
- "%s %s %s %s %s %s %s %s",
- program, rdc_decode_flag(flag, parms.options),
- fromhost, fromfile, frombitmap,
- tohost, tofile, tobitmap);
- if ((flag == RDC_CMD_RECONFIG) &&
- (!(iflag & RDC_OPT_REVERSE_ROLE))) {
- success = 0;
- rdc_warn(&ustatus, 0);
- } else
- rdc_err(&ustatus, 0);
- }
- }
- if ((flag == RDC_CMD_RECONFIG) && (iflag & RDC_OPT_REVERSE_ROLE) == 0) {
- parms.command = RDC_CMD_STATUS;
- if (RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, ustatus) ==
- SPCS_S_OK) {
- char shostbuf[CFG_MAX_BUF];
- char svolbuf[CFG_MAX_BUF];
- char key[CFG_MAX_KEY];
- int i, numels;
- int cfgsuccess = 1;
-
- /*
- * okeydoke, at this point we could have a reconfig
- * gone bad. libdscfg does not know about this.
- * parms contains the kernel picture, and we know
- * what we tried to reconfig. find out where it went
- * wrong, find the set in libdscfg, update it. We'll
- * issue a warning, then return 0 (eventually).
- * this will allow libdscfg to be committed with the
- * good info. got it?
- * BTW: the only time we can run into this multiple
- * reconfig attempt failure is IF we reconfig from file
- * and some thing goes wrong with one of the reconfigs
- */
-
- /* find the set in libdscfg */
-
- numels = cfg_get_num_entries(cfg, "sndr");
- /* yes, numels could be -1 */
- for (i = 1; i < numels; i++) {
- bzero(shostbuf, sizeof (shostbuf));
- bzero(svolbuf, sizeof (svolbuf));
- bzero(key, sizeof (key));
-
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.shost", i);
-
- (void) cfg_get_cstring(cfg, key, &shostbuf,
- sizeof (shostbuf));
- if (strncmp(shostbuf, tohost, sizeof (tohost)))
- continue;
-
- bzero(key, sizeof (key));
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.secondary", i);
- (void) cfg_get_cstring(cfg, key, &svolbuf,
- sizeof (svolbuf));
- if (strncmp(svolbuf, tofile, NSC_MAXPATH))
- continue;
- break;
-
- /*
- * found it, now i contains the set offset.
- * i, being the variable, not bad english.
- */
-
- }
- /* shouldn't happen */
- if ((numels < 1) || (i > numels)) {
- rdc_warn(NULL, gettext("unable to retrieve "
- "set from configuration database"));
- /*
- * yuck. but indents are pushing the envelope
- * we should not be updating config
- * if we did not find the entry
- * the error will have to do
- */
- cfgsuccess = 0;
- goto notfound;
- }
-
- /*
- * now, put all the correct names back for errors etc.
- * also, sock them into dscfg, if the the config was a
- * success for one, it will be a redundant but harmless
- */
-
- /*
- * we could not have reconfigged mode if we
- * are not logging, AND the kernel CAN return
- * sync as the status of an async set if it is
- * currently syncing.. Hence the flags & RDC_LOGGING
- */
- if (parms.rdc_set->flags & RDC_LOGGING) {
- bzero(key, sizeof (key));
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.mode", i);
- if (parms.rdc_set->flags & RDC_ASYNC) {
- *doasync = 1;
- if (cfg_put_cstring(cfg, key, "async",
- strlen("async")) < 0) {
- cfgsuccess = 0;
- }
-
- } else {
- *doasync = 0;
- if (cfg_put_cstring(cfg, key, "sync",
- strlen("sync")) < 0) {
- cfgsuccess = 0;
- }
- }
- }
-#ifdef _RDC_CAMPUS
- if (*parms.rdc_set->direct_file) {
- (void) strncpy(directfile,
- parms.rdc_set->direct_file, NSC_MAXPATH);
- bzero(key, sizeof (key));
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.type", i);
- if (cfg_put_cstring(cfg, key, directfile,
- strlen(directfile)) < 0)
- cfgsuccess = 0;
- } else {
- (void) strncpy(directfile, "-", NSC_MAXPATH);
- bzero(key, sizeof (key));
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.type", i);
- if (cfg_put_cstring(cfg, key, directfile,
- strlen(directfile)) < 0)
- cfgsuccess = 0;
- }
-#endif
-
- if (*parms.rdc_set->group_name) {
- (void) strncpy(group, parms.rdc_set->group_name,
- NSC_MAXPATH);
- bzero(key, sizeof (key));
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.group", i);
- if (cfg_put_cstring(cfg, key, group,
- strlen(group)) < 0)
- cfgsuccess = 0;
-
- } else {
- (void) strncpy(group, "-", NSC_MAXPATH);
- bzero(key, sizeof (key));
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.group", i);
- if (cfg_put_cstring(cfg, key, group,
- strlen(group)) < 0)
- cfgsuccess = 0;
- }
-
- if (*parms.rdc_set->disk_queue) {
- (void) strncpy(diskqueue,
- parms.rdc_set->disk_queue, NSC_MAXPATH);
- } else {
- (void) strncpy(diskqueue, "-", NSC_MAXPATH);
- }
- bzero(key, sizeof (key));
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.diskq", i);
- if (cfg_put_cstring(cfg, key, diskqueue,
- strlen(diskqueue)) < 0)
- cfgsuccess = 0;
-
- (void) strncpy(frombitmap,
- parms.rdc_set->primary.bitmap, NSC_MAXPATH);
- bzero(key, sizeof (key));
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.pbitmap", i);
- if (cfg_put_cstring(cfg, key, frombitmap,
- strlen(frombitmap)) < 0)
- cfgsuccess = 0;
-
- (void) strncpy(tobitmap,
- parms.rdc_set->secondary.bitmap, NSC_MAXPATH);
- bzero(key, sizeof (key));
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.sbitmap", i);
- if (cfg_put_cstring(cfg, key, tobitmap,
- strlen(tobitmap)) < 0)
- cfgsuccess = 0;
-
- bzero(key, sizeof (key));
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.cnode", i);
- if (clustered)
- if (cfg_put_cstring(cfg, key, ctag,
- strlen(ctag)) < 0)
- cfgsuccess = 0;
-notfound:
- if (cfgsuccess == 0) {
- rdc_warn(NULL, gettext("unable to update "
- "configuration storage"));
- }
- } else {
- spcs_log("sndr", NULL,
- "%s %s %s %s %s %s %s %s\n%s",
- program, rdc_decode_flag(flag, parms.options),
- fromhost, fromfile, frombitmap,
- tohost, tofile, tobitmap,
- gettext("unable to update config file"));
- rdc_err(&ustatus,
- gettext("Remote Mirror: unable to update "
- "config file"));
-
- }
- }
-
- if (flag == RDC_CMD_HEALTH && errno == 0) {
- (void) fprintf(stderr,
- gettext("Remote Mirror: %s %s %s %s %s %s\n"),
- fromhost, fromfile,
- frombitmap, tohost, tofile, tobitmap);
-
- if (ret == RDC_ACTIVE)
- (void) fprintf(stderr, "Active\n");
- else if (ret == RDC_INACTIVE)
- (void) fprintf(stderr, "Inactive\n");
- else
- (void) fprintf(stderr, "Unknown\n");
- } else if (ret != SPCS_S_OK) {
- if (errno == RDC_EEINVAL) {
- spcs_log("sndr", NULL,
- "%s %s %s %s %s %s %s %s\n%s",
- program, rdc_decode_flag(flag, parms.options),
- fromhost, fromfile, frombitmap,
- tohost, tofile, tobitmap,
- gettext("invalid command option"));
- rdc_err(&ustatus,
- gettext("Remote Mirror: invalid command option "
- "'%s'"),
- rdc_decode_flag(flag, parms.options));
- }
- }
- if (flag == RDC_CMD_STATUS) {
- (void) fprintf(stderr,
- gettext("Remote Mirror: %s %s %s %s %s %s\n"),
- fromhost, fromfile,
- frombitmap, tohost, tofile, tobitmap);
- (void) fprintf(stderr, "flags 0x%x\n", parms.rdc_set->flags |
- parms.rdc_set->sync_flags | parms.rdc_set->bmap_flags);
- } else if (success) {
- spcs_log("sndr", NULL,
- gettext("%s %s %s %s %s %s %s %s\nSuccessful"),
- program, rdc_decode_flag(flag, parms.options),
- fromhost, fromfile, frombitmap,
- tohost, tofile, tobitmap);
- if (flag == RDC_CMD_TUNABLE)
- spcslog_tunable(tohost, tofile);
- }
-
- if (cfg && perform_autosv()) {
- spcs_s_ufree(&ustatus);
- /* figure out which are the local volumes */
- if (parms.options & RDC_OPT_PRIMARY) {
- vol1 = fromfile;
- vol2 = frombitmap;
- if ((diskqueue && diskqueue[0]) &&
- (strncmp(diskqueue, "-", 1) != 0))
- vol3 = diskqueue;
- else
- vol3 = NULL;
- } else {
- vol1 = tofile;
- vol2 = tobitmap;
- vol3 = NULL;
- if ((flag == RDC_CMD_ENABLE) &&
- (strlen(diskqueue) > 0) &&
- (strncmp(diskqueue, "-", 1)) != 0) {
- rdc_warn(NULL,
- gettext("enabling a disk queue on a "
- "Remote Mirror secondary is not allowed. "
- "(%s) ignored"), diskqueue);
- }
- }
-
- if (flag == RDC_CMD_ENABLE) {
- ustatus = spcs_s_ucreate();
- /*
- * SV-enable all local volumes
- * if the sv_enables fail, disable the sndr vols
- * that we just enabled
- * and return -1 so the cfg_commit() won't happen
- */
-
- if (nsc_lookup(volhash, vol1) == NULL) {
- if (cfg_vol_enable(cfg, vol1, ctag, "sndr")
- < 0) {
- spcs_log("sndr", NULL,
- "sv enable failed for %s, "
- "disabling Remote Mirror set %s:%s",
- vol1, tohost, tofile);
- /*
- * warn here, but we are going to exit
- * we want to catch any errors on the
- * way down, then exit
- */
-
- rdc_warn(NULL,
- "unable to sv enable %s\n"
- "disabling Remote Mirror set %s:%s",
- vol1, tohost, tofile);
-
- parms.command = RDC_CMD_DISABLE;
- ret = RDC_IOCTL(RDC_CONFIG, &parms,
- NULL, 0, 0, 0, ustatus);
- if (ret != SPCS_S_OK) {
- (void) fprintf(stderr,
- gettext("Remote Mirror:"
- " %s %s %s %s %s %s\n"),
- fromhost, fromfile,
- frombitmap, tohost, tofile,
- tobitmap);
- spcs_log("sndr", &ustatus,
- "%s %s %s %s %s %s %s %s",
- program,
- rdc_decode_flag(parms.command,
- parms.options),
- fromhost,
- fromfile, frombitmap,
- tohost, tofile, tobitmap);
- rdc_err(&ustatus, 0);
- }
- /*
- * ok, we should've reported any errs
- * exit explictly
- */
- exit(1);
-
- }
- }
- if (vol2 && nsc_lookup(volhash, vol2) == NULL) {
- if (cfg_vol_enable(cfg, vol2, ctag, "sndr")
- < 0) {
- spcs_log("sndr", NULL,
- "sv enable failed for %s, "
- "disabling Remote Mirror set %s:%s",
- vol1, tohost, tofile);
- /*
- * warn here, but we are going to exit
- * we want to catch any errors on the
- * way down, then exit
- */
-
- rdc_warn(NULL,
- "unable to sv enable %s\n"
- "disabling Remote Mirror set %s:%s",
- vol2, tohost, tofile);
-
- parms.command = RDC_CMD_DISABLE;
- ret = RDC_IOCTL(RDC_CONFIG, &parms,
- NULL, 0, 0, 0, ustatus);
- if (ret != SPCS_S_OK) {
- (void) fprintf(stderr,
- gettext("Remote Mirror:"
- " %s %s %s %s %s %s\n"),
- fromhost, fromfile,
- frombitmap, tohost, tofile,
- tobitmap);
- spcs_log("sndr", &ustatus,
- "%s %s %s %s %s %s %s %s",
- program,
- rdc_decode_flag(parms.command,
- parms.options),
- fromhost,
- fromfile, frombitmap,
- tohost, tofile, tobitmap);
- rdc_err(&ustatus, 0);
- }
- /*
- * ok, we should've reported any errs
- * exit explictly
- */
- exit(1);
-
- }
- }
-
- if (vol3 && nsc_lookup(volhash, diskqueue) == NULL) {
- if (cfg_vol_enable(cfg, diskqueue, ctag, "sndr")
- < 0) {
- spcs_log("sndr", NULL,
- "sv enable failed for %s, "
- "disabling Remote Mirror set %s:%s",
- diskqueue, tohost, tofile);
- if (cfg_vol_disable(cfg, vol1, ctag,
- "sndr") < 0)
- rdc_warn(NULL, gettext("Failed to "
- "remove volume [%s] from "
- "configuration"), vol1);
- if (cfg_vol_disable(cfg, vol2, ctag,
- "sndr") < 0)
- rdc_warn(NULL, gettext("Failed to "
- "remove volume [%s] from "
- "configuration"), vol2);
-
- /*
- * warn here, but we are going to exit
- * we want to catch any errors on the
- * way down, then exit
- */
-
- rdc_warn(NULL,
- "unable to sv enable %s\n"
- "disabling Remote Mirror set %s:%s",
- diskqueue, tohost, tofile);
-
- parms.command = RDC_CMD_DISABLE;
- ret = RDC_IOCTL(RDC_CONFIG, &parms,
- NULL, 0, 0, 0, ustatus);
- if (ret != SPCS_S_OK) {
- (void) fprintf(stderr,
- gettext("Remote Mirror:"
- " %s %s %s %s %s %s\n"),
- fromhost, fromfile,
- frombitmap, tohost, tofile,
- tobitmap);
- spcs_log("sndr", &ustatus,
- "%s %s %s %s %s %s %s %s",
- program,
- rdc_decode_flag(parms.command,
- parms.options),
- fromhost,
- fromfile, frombitmap,
- tohost, tofile, tobitmap);
- rdc_err(&ustatus, 0);
- }
- /*
- * ok, we should've reported any errs
- * exit explictly
- */
- exit(1);
-
- }
- }
- } else if (flag == RDC_CMD_DISABLE) {
- /*
- * If we're no longer using a volume, SV-disable it
- */
- volcount_t *vc;
-
- vc = nsc_lookup(volhash, vol1);
- if (vc && (1 == vc->count)) {
- if (cfg_vol_disable(cfg, vol1, ctag, "sndr")
- < 0)
- rdc_warn(NULL, gettext("Failed to "
- "remove volume [%s] from "
- "configuration"), vol1);
-
- } else if (!vc) {
- rdc_warn(NULL,
- gettext("Unable to find %s in config"),
- vol1);
- }
-
- if (vol2) {
- vc = nsc_lookup(volhash, vol2);
- if (vc && (1 == vc->count)) {
- if (cfg_vol_disable(cfg, vol2, ctag,
- "sndr") < 0)
- rdc_warn(NULL, gettext("Failed to "
- "remove volume [%s] from "
- "configuration"), vol2);
- } else if (!vc) {
- rdc_warn(NULL, gettext("Unable to find"
- " %s in config"), vol2);
- }
- }
-
- if (diskqueue != NULL && strlen(diskqueue) > 0) {
- vc = nsc_lookup(volhash, diskqueue);
- if (vc && (1 == vc->count)) {
- if (cfg_vol_disable(cfg, diskqueue, ctag,
- "sndr") < 0)
- rdc_warn(NULL, gettext("Failed to "
- "remove disk queue [%s] from "
- "configuration"), diskqueue);
- } else if (!vc) {
- rdc_warn(NULL, gettext("Unable to find"
- " %s in config"), diskqueue);
- }
- }
- /* WARNING about to go to 4 space indenting */
- } else if (flag == RDC_CMD_RECONFIG) {
- volcount_t *vc;
- /* disable ex-bitmaps, enable new bitmaps */
- if (parms.options & RDC_OPT_PRIMARY) {
- if (strcmp(orig_fbmp, frombitmap) != 0) {
- vc = nsc_lookup(volhash, orig_fbmp);
- if (vc && (vc->count == 1)) {
- if (cfg_vol_disable(cfg, orig_fbmp, ctag,
- "sndr") < 0)
- rdc_warn(NULL, gettext("Failed to "
- "remove bitmap [%s] from "
- "configuration"), orig_fbmp);
- } else if (!vc) {
- rdc_warn(NULL, gettext("Unable to find "
- "%s in config"), orig_fbmp);
- }
- if (nsc_lookup(volhash, frombitmap) == NULL) {
- if (cfg_vol_enable(cfg, frombitmap, ctag,
- "sndr") < 0) {
- spcs_log("sndr", NULL,
- "reconfig sv enable failed for %s, "
- "disabling Remote Mirror set %s:%s",
- frombitmap, tohost, tofile);
- rdc_warn(NULL,
- "unable to sv enable %s\n"
- "disabling Remote Mirror set %s:%s",
- frombitmap, tohost, tofile);
- parms.command = RDC_CMD_DISABLE;
- ret = RDC_IOCTL(RDC_CONFIG, &parms,
- NULL, 0, 0, 0, ustatus);
- if (ret != SPCS_S_OK) {
- (void) fprintf(stderr,
- gettext("Remote Mirror:"
- " %s %s %s %s %s %s\n"),
- fromhost, fromfile,
- frombitmap, tohost, tofile,
- tobitmap);
- spcs_log("sndr", &ustatus,
- "%s %s %s %s %s %s %s %s",
- program,
- rdc_decode_flag(parms.command,
- parms.options),
- fromhost,
- fromfile, frombitmap,
- tohost, tofile, tobitmap);
- rdc_warn(&ustatus, 0);
- }
- exit(1);
- }
- }
- } else if ((orig_diskq[0] != '\0') &&
- (strcmp(orig_diskq, diskqueue) != 0)) {
- vc = nsc_lookup(volhash, orig_diskq);
- if (vc && (vc->count == 1)) {
- if (cfg_vol_disable(cfg, orig_diskq, ctag,
- "sndr") < 0)
- rdc_warn(NULL, gettext("Failed to "
- "remove disk queue [%s] from "
- "configuration"), orig_diskq);
- } else if (!vc) {
- rdc_warn(NULL, gettext("Unable to find "
- "%s in config"), orig_diskq);
- }
- if (vol3 &&
- (nsc_lookup(volhash, diskqueue) == NULL)) {
- if (cfg_vol_enable(cfg, diskqueue, ctag,
- "sndr") < 0) {
- spcs_log("sndr", NULL, "reconfig sv "
- "enable of diskqueue %s failed, "
- "disabling Remote Mirror set %s:%s",
- diskqueue, tohost, tofile);
- rdc_warn(NULL, "reconfig sv "
- "enable of diskqueue %s failed."
- "disabling Remote Mirror set %s:%s",
- diskqueue, tohost, tofile);
- parms.command = RDC_CMD_DISABLE;
- ret = RDC_IOCTL(RDC_CONFIG, &parms,
- NULL, 0, 0, 0, ustatus);
- if (ret != SPCS_S_OK) {
- (void) fprintf(stderr,
- gettext("Remote Mirror:"
- " %s %s %s %s %s %s\n"),
- fromhost, fromfile,
- frombitmap, tohost, tofile,
- tobitmap);
- spcs_log("sndr", &ustatus,
- "%s %s %s %s %s %s %s %s",
- program,
- rdc_decode_flag(parms.command,
- parms.options),
- fromhost,
- fromfile, frombitmap,
- tohost, tofile, tobitmap);
- rdc_warn(&ustatus, 0);
- }
- exit(1);
- }
- }
- }
- } else if (flag != RDC_OPT_PRIMARY) {
- if (strcmp(orig_tbmp, tobitmap) != 0) {
- vc = nsc_lookup(volhash, orig_tbmp);
- if (vc && (vc->count == 1)) {
- if (cfg_vol_disable(cfg, orig_tbmp, ctag,
- "sndr") < 0)
- rdc_warn(NULL, gettext("Failed to "
- "remove bitmap [%s] from "
- "configuration"), orig_tbmp);
- } else if (!vc) {
- rdc_warn(NULL,
- gettext("Unable to find %s in config"),
- orig_tbmp);
- }
- if (nsc_lookup(volhash, tobitmap) == NULL) {
- if (cfg_vol_enable(cfg, tobitmap, ctag,
- "sndr") < 0) {
- spcs_log("sndr", NULL,
- "reconfig sv enable failed for %s, "
- "disabling Remote Mirror set %s:%s",
- tobitmap, tohost, tofile);
- rdc_warn(NULL,
- "unable to sv enable %s\n"
- "disabling Remote Mirror set %s:%s",
- tobitmap, tohost, tofile);
- parms.command = RDC_CMD_DISABLE;
- ret = RDC_IOCTL(RDC_CONFIG, &parms,
- NULL, 0, 0, 0, ustatus);
- if (ret != SPCS_S_OK) {
- (void) fprintf(stderr,
- gettext("Remote Mirror:"
- " %s %s %s %s %s %s\n"),
- fromhost, fromfile,
- frombitmap, tohost, tofile,
- tobitmap);
- spcs_log("sndr", &ustatus,
- "%s %s %s %s %s %s %s %s",
- program,
- rdc_decode_flag(parms.command,
- parms.options),
- fromhost, fromfile, frombitmap,
- tohost, tofile, tobitmap);
- rdc_warn(&ustatus, 0);
- }
- exit(1);
- }
- }
- }
- }
- /* END 4 space indenting */
- }
- }
- spcs_s_ufree(&ustatus);
-
- return (0);
-}
-
-
-/*
- * read_config()
- *
- * DESCRIPTION: Read the lines in a configuration file and return the
- * pairs of devices to be mirrored/enabled/disabled/updated.
- * The format for the configuration file is as follows:
- *
- * fromhost fromfile frombitmap tohost tofile tobitmap
- *
- * where fromfile is the primary device which is local to the
- * fromhost subsystem, tofile is the secondary device which is
- * local to the tohost subsystem, and type is 1 if the device
- * a simckd device or 0 otherwise. Any line preceeded by a '#'
- * is considered to be a comment.
- *
- * Inputs:
- * char *config_file Name of configuration file for rdcadm
- *
- * Outputs:
- * int i Number of pairs of devices
- *
- * Side Effects: The 0 to i-1 entries in the pair_list are filled.
- *
- */
-
-int
-read_config(int flag, char *config_file, char *group_arg, char *ctag_arg)
-{
- int ret;
- char dsk_flagstr[NSC_MAXPATH];
- char line[1024], tmp_line[1024];
- char fromhost[MAX_RDC_HOST_SIZE];
- char fromfile[NSC_MAXPATH];
- char frombitmap[NSC_MAXPATH];
- char tohost[MAX_RDC_HOST_SIZE];
- char tofile[NSC_MAXPATH];
- char tobitmap[NSC_MAXPATH];
- char directfile[NSC_MAXPATH];
- char sync[16];
- int doasync;
- FILE *fp;
- int i, j;
- char *extra_args[EXTRA_ARGS];
- char *tmp, *split_str = " \t\n";
-
- for (j = 0; j < EXTRA_ARGS; j++)
- extra_args[j] = malloc(NSC_MAXPATH);
-
- if (!(fp = fopen(config_file, "r"))) {
- rdc_err(NULL, gettext("error opening %s"), config_file);
- }
-
- i = 0;
- while (fgets(line, sizeof (line), fp)) {
- if (line[0] == '#') /* this is a comment */
- continue;
-
- ret = 0;
- (void) strcpy(tmp_line, line);
-
- if ((tmp = strtok(tmp_line, split_str)) != NULL) {
- if (strlen(tmp) >= MAX_RDC_HOST_SIZE) {
- (void) printf(gettext("hostname is longer than %d "
- "characters\n"), (MAX_RDC_HOST_SIZE - 1));
- continue;
- }
- (void) strncpy(fromhost, tmp, (MAX_RDC_HOST_SIZE - 1));
- fromhost[(MAX_RDC_HOST_SIZE - 1)] = '\0';
- ret++;
- }
- if ((tmp = strtok(NULL, split_str)) != NULL) {
- if (strlen(tmp) >= NSC_MAXPATH) {
- (void) printf(gettext(
- "device name is longer than %d "
- "characters\n"), (NSC_MAXPATH - 1));
- continue;
- }
- (void) strncpy(fromfile, tmp, (NSC_MAXPATH - 1));
- fromfile[(NSC_MAXPATH - 1)] = '\0';
- ret++;
- }
- if ((tmp = strtok(NULL, split_str)) != NULL) {
- if (strlen(tmp) >= NSC_MAXPATH) {
- (void) printf(gettext(
- "device name is longer than %d "
- "characters\n"), (NSC_MAXPATH - 1));
- continue;
- }
- (void) strncpy(frombitmap, tmp, (NSC_MAXPATH - 1));
- frombitmap[(NSC_MAXPATH - 1)] = '\0';
- ret++;
- }
- if ((tmp = strtok(NULL, split_str)) != NULL) {
- if (strlen(tmp) >= MAX_RDC_HOST_SIZE) {
- (void) printf(gettext(
- "hostname is longer than %d "
- "characters\n"), (MAX_RDC_HOST_SIZE - 1));
- continue;
- }
- (void) strncpy(tohost, tmp, (MAX_RDC_HOST_SIZE - 1));
- tohost[(MAX_RDC_HOST_SIZE - 1)] = '\0';
- ret++;
- }
- if ((tmp = strtok(NULL, split_str)) != NULL) {
- if (strlen(tmp) >= NSC_MAXPATH) {
- (void) printf(gettext(
- "device name is longer than %d "
- "characters\n"), (NSC_MAXPATH - 1));
- continue;
- }
- (void) strncpy(tofile, tmp, (NSC_MAXPATH - 1));
- tofile[(NSC_MAXPATH - 1)] = '\0';
- ret++;
- }
- if ((tmp = strtok(NULL, split_str)) != NULL) {
- if (strlen(tmp) >= NSC_MAXPATH) {
- (void) printf(gettext(
- "device name is longer than %d "
- "characters\n"), (NSC_MAXPATH - 1));
- continue;
- }
- (void) strncpy(tobitmap, tmp, (NSC_MAXPATH - 1));
- tobitmap[(NSC_MAXPATH - 1)] = '\0';
- ret++;
- }
- if ((tmp = strtok(NULL, split_str)) != NULL) {
- (void) strncpy(dsk_flagstr, tmp, 15);
- dsk_flagstr[15] = '\0';
- ret++;
- }
- if ((tmp = strtok(NULL, split_str)) != NULL) {
- (void) strncpy(sync, tmp, 15);
- sync[15] = '\0';
- ret++;
- }
- for (j = 0; j < EXTRA_ARGS; j++) {
- if ((tmp = strtok(NULL, split_str)) != NULL) {
- (void) strncpy(extra_args[j], tmp,
- (NSC_MAXPATH - 1));
- extra_args[j][(NSC_MAXPATH - 1)] = '\0';
- ret++;
- }
- }
-
- if (ret == 0) /* this is a blank line */
- continue;
-
- if (ret < 8) {
- (void) fclose(fp);
- rdc_warn(NULL,
- gettext("invalid format in %s"), config_file);
- rdc_err(NULL, "%s", line);
- }
-
- if (i >= rdc_maxsets) {
- (void) fclose(fp);
- rdc_err(NULL,
- gettext("number of Remote Mirror sets exceeds %d"),
- rdc_maxsets);
- }
-
-#ifdef _RDC_CAMPUS
- if (dsk_flagstr[0] == '/') {
- /* fcal directio */
- (void) strncpy(directfile, dsk_flagstr, NSC_MAXPATH);
- } else if (strcmp(dsk_flagstr, "ip") != 0) {
-#else
- if (strcmp(dsk_flagstr, "ip") != 0) {
-#endif
- (void) fclose(fp);
- rdc_err(NULL,
-#ifdef _RDC_CAMPUS
- gettext("ip/fcal specification missing"));
-#else
- gettext("ip specification missing"));
-#endif
- } else
- (void) strcpy(directfile, "ip");
-
- if (strcmp(sync, "sync") == 0)
- doasync = 0;
- else if (strcmp(sync, "async") == 0)
- doasync = 1;
- else {
- (void) fclose(fp);
- rdc_err(NULL,
- gettext("sync/async specification missing"));
- }
- (void) strncpy(pair_list[i].fhost, fromhost, MAX_RDC_HOST_SIZE);
- (void) strncpy(pair_list[i].ffile, fromfile, NSC_MAXPATH);
- (void) strncpy(pair_list[i].fbitmap, frombitmap, NSC_MAXPATH);
- (void) strncpy(pair_list[i].thost, tohost, MAX_RDC_HOST_SIZE);
- (void) strncpy(pair_list[i].tfile, tofile, NSC_MAXPATH);
- (void) strncpy(pair_list[i].tbitmap, tobitmap, NSC_MAXPATH);
- (void) strncpy(pair_list[i].directfile, directfile,
- NSC_MAXPATH);
- pair_list[i].doasync = doasync;
-
- if (gethost_netaddrs(fromhost, tohost,
- (char *)pair_list[i].fnetaddr,
- (char *)pair_list[i].tnetaddr) < 0) {
- (void) fclose(fp);
- rdc_err(NULL, gettext("unable to determine IP "
- "addresses for hosts %s, %s"), fromhost, tohost);
- }
-
- if (parse_extras(ret - 8, extra_args, i) < 0) {
- (void) fclose(fp);
- rdc_err(NULL, gettext("illegal option in:\n%s"),
- line);
- }
-
- if (flag == RDC_CMD_ENABLE || flag == RDC_CMD_RECONFIG) {
- if (ctag_check(fromhost, fromfile, frombitmap,
- tohost, tofile, tobitmap, pair_list[i].ctag,
- pair_list[i].diskqueue) < 0)
- continue; /* Ignore illegal sets */
- if (pair_diskqueue_check(i))
- continue; /* ignore sets with incorrect diskq */
- }
-
- /* Filter according to ctag and group arguments */
- if (strcmp(ctag_arg, "") &&
- strncmp(ctag_arg, pair_list[i].ctag,
- MAX_RDC_HOST_SIZE))
- continue;
- if (strcmp(group_arg, "") &&
- strncmp(group_arg, pair_list[i].group, NSC_MAXPATH))
- continue;
-
- i++;
- }
- (void) fclose(fp);
- for (j = 0; j < EXTRA_ARGS; j++)
- free(extra_args[j]);
- return (i);
-}
-
-
-/*
- * read_libcfg()
- *
- * DESCRIPTION: Read the relevant config info via libcfg
- *
- * Outputs:
- * int i Number of pairs of devices
- *
- * Side Effects: The 0 to i-1 entries in the pair_list are filled.
- *
- */
-static int
-read_libcfg(int flag, char *group_arg, char *ctag_arg)
-{
- int rc;
- CFGFILE *cfg;
- int i;
- _sd_dual_pair_t *pairp;
- char buf[CFG_MAX_BUF];
- char key[CFG_MAX_KEY];
- int setnumber;
-
- if ((cfg = cfg_open(NULL)) == NULL)
- rdc_err(NULL, gettext("unable to access configuration"));
-
- if (!cfg_lock(cfg, CFG_RDLOCK))
- rdc_err(NULL, gettext("unable to lock configuration"));
-
- if (strcmp(ctag_arg, ""))
- cfg_resource(cfg, ctag_arg);
- else {
- cfg_resource(cfg, NULL);
- }
-
- setnumber = 0;
- /*CSTYLED*/
- for (i = 0; i < rdc_maxsets;) {
- setnumber++;
-
- bzero(buf, CFG_MAX_BUF);
- (void) snprintf(key, sizeof (key), "sndr.set%d", setnumber);
- rc = cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF);
- if (rc < 0)
- break;
-
- pairp = &pair_list[i];
- if (parse_cfg_buf(buf, pairp, NULL))
- continue;
-
- if (strcmp(group_arg, "") &&
- strncmp(group_arg, pairp->group, NSC_MAXPATH))
- continue;
-
- if (flag == RDC_CMD_RECONFIG) {
- if (reconfig_pbitmap)
- (void) strncpy(pairp->fbitmap, reconfig_pbitmap,
- NSC_MAXPATH);
- if (reconfig_sbitmap)
- (void) strncpy(pairp->tbitmap, reconfig_sbitmap,
- NSC_MAXPATH);
-#ifdef _RDC_CAMPUS
- if (reconfig_direct)
- (void) strncpy(directfile, reconfig_direct,
- NSC_MAXPATH);
-#endif
- if (reconfig_group)
- (void) strncpy(pairp->group, reconfig_group,
- NSC_MAXPATH);
-
- if (strlen(reconfig_ctag) > 0)
- (void) strncpy(pairp->ctag, reconfig_ctag,
- MAX_RDC_HOST_SIZE);
-
- if (reconfig_doasync != -1)
- pairp->doasync = reconfig_doasync;
- }
-
-
- if (ctag_check(pairp->fhost, pairp->ffile,
- pairp->fbitmap, pairp->thost, pairp->tfile,
- pairp->tbitmap, pairp->ctag, pairp->diskqueue) < 0)
- continue; /* Ignore illegal sets */
-
- if (gethost_netaddrs(pairp->fhost, pairp->thost,
- (char *)pairp->fnetaddr,
- (char *)pairp->tnetaddr) < 0) {
- rdc_err(NULL, gettext("unable to determine IP "
- "addresses for hosts %s, %s"), pairp->fhost,
- pairp->thost);
- }
-
- i++;
- }
-
- cfg_close(cfg);
- return (i);
-}
-
-void
-q_usage(int prhdr)
-{
- if (prhdr)
- (void) fprintf(stderr, gettext("disk queue usage:\n"));
-
- (void) fprintf(stderr,
- gettext("\t%s -g <group> -q a <vol>\t\tadd disk queue to "
- "group\n"), program);
- (void) fprintf(stderr,
- gettext("\t%s -g <group> -q d \t\tremove disk queue from"
- " group\n"), program);
- (void) fprintf(stderr,
- gettext("\t%s -g <group> -q r <newvol>\treplace disk queue for a"
- " group\n"), program);
-
- (void) fprintf(stderr,
- gettext("\t%s -q a <vol> <shost>:<sdev>\tadd disk queue to "
- "a set\n"), program);
- (void) fprintf(stderr,
- gettext("\t%s -q d <shost>:<sdev>\t\tremove disk queue from "
- "a set\n"), program);
- (void) fprintf(stderr,
- gettext("\t%s -q r <newvol> <shost>:<sdev>\treplace disk queue for "
- "a set\n"), program);
-
-}
-
-static void
-usage()
-{
- (void) fprintf(stderr, gettext("usage:\n"));
-
- (void) fprintf(stderr,
- gettext("\t%s [opts] -a {on | off} [set]\t"
- "set autosync\n"), program);
-
- (void) fprintf(stderr,
- gettext("\t%s [opts] -A <asyncthr> [set]\t"
- "set the number of asynchronous\n\t\t\t\t\t\tthreads\n"),
- program);
-
- (void) fprintf(stderr,
- gettext("\t%s [opts] -d [set]\t\t\t"
- "disable\n"), program);
-
- (void) fprintf(stderr,
- gettext("\t%s [opts] -e [set]\t\t\t"
- "enable with bits in bitmap set\n"), program);
-
- (void) fprintf(stderr,
- gettext("\t%s [opts] -E [set]\t\t\t"
- "enable with bits in bitmap clear\n"), program);
-
- (void) fprintf(stderr,
- gettext("\t%s [opts] -F <maxqfbas> [set]\t"
- "set maximum fbas to queue\n"), program);
-
- (void) fprintf(stderr,
- gettext("\t%s [opts] -D {block | noblock} [set]\t"
- "set disk queue blocking mode\n"), program);
-
- (void) fprintf(stderr,
- gettext("\t%s [opts] -H [set]\t\t\t"
- "report link health\n"), program);
-
- (void) fprintf(stderr,
- gettext("\t%s -h\t\t\t\tusage message\n"), program);
-
- (void) fprintf(stderr,
- gettext("\t%s -I a <master> <shadow> <bitmap>\t"
- "add ndr_ii config entry\n"), program);
-
- (void) fprintf(stderr,
- gettext("\t%s -I d <master> <shadow> <bitmap>\t"
- "delete ndr_ii config entry\n"), program);
-
- (void) fprintf(stderr,
- gettext("\t%s [opts] -i [set]\t\t\t"
- "print sets in config file format\n"), program);
-
- (void) fprintf(stderr,
- gettext("\t%s [opts] -l [set]\t\t\t"
- "enter logging mode\n"), program);
-
- (void) fprintf(stderr,
- gettext("\t%s [opts] -m [set]\t\t\t"
- "full sync\n"), program);
-
- (void) fprintf(stderr,
- gettext("\t%s [opts] -m -r [set]\t\t"
- "full reverse sync\n"), program);
-
- (void) fprintf(stderr,
- gettext("\t%s [opts] -P [set]\t\t\t"
- "print sets verbose\n"), program);
-
- (void) fprintf(stderr,
- gettext("\t%s [opts] -p [set]\t\t\t"
- "print sets\n"), program);
-
- (void) fprintf(stderr,
- gettext("\t%s [opts] -R\t\t\t"
- "reset error conditions\n"), program);
-
- (void) fprintf(stderr,
- gettext("\t%s [opts] -R b p <bitmap> [set]\t"
- "reconfig primary bitmap\n"), program);
-
- (void) fprintf(stderr,
- gettext("\t%s [opts] -R b s <bitmap> [set]\t"
- "reconfig secondary bitmap\n"), program);
-
- if (clustered)
- (void) fprintf(stderr,
- gettext("\t%s [opts] -R C <ctag> [set]\t"
- "reconfig cluster tag\n"), program);
-
-#ifdef _RDC_CAMPUS
- (void) fprintf(stderr,
- gettext("\t%s [opts] -R d <pathname> [set]\t"
- "reconfig campus direct file\n"), program);
-#endif
-
- (void) fprintf(stderr,
- gettext("\t%s [opts] -R -f <volset-file> \t"
- "reconfig from file\n"), program);
-
- (void) fprintf(stderr,
- gettext("\t%s [opts] -R g <group> [set]\t"
- "reconfig group\n"), program);
-
- (void) fprintf(stderr,
- gettext("\t%s [opts] -R m {sync|async} [set]\t"
- "reconfig mode\n"), program);
-
- if (allow_role)
- (void) fprintf(stderr,
- gettext("\t%s [opts] -R r [set]\t\t"
- "reverse roles\n"), program);
-
- (void) fprintf(stderr,
- gettext("\t%s [opts] -u [set]\t\t\t"
- "update sync\n"), program);
-
- (void) fprintf(stderr,
- gettext("\t%s [opts] -u -r [set]\t\t"
- "update reverse sync\n"), program);
-
- (void) fprintf(stderr,
- gettext("\t%s -v\t\t\t\tdisplay version\n"), program);
-
- (void) fprintf(stderr,
- gettext("\t%s [opts] -W <maxwrites> [set]\t"
- "set maximum writes to queue\n"), program);
-
- (void) fprintf(stderr,
- gettext("\t%s [opts] -w [set]\t\t\t"
- "wait\n"), program);
- q_usage(0);
-
- (void) fprintf(stderr, gettext("\nopts:\n"));
- (void) fprintf(stderr, gettext("\t-n\t\tnon-interactive mode "
- "(not valid for print operations)\n"));
- (void) fprintf(stderr, gettext(
- "\t-g <group>\toperate on sets in group only "
- "(not valid for enable\n\t\t\toperations)\n"));
- if (clustered)
- (void) fprintf(stderr,
- gettext("\t-C <ctag>\tignore sets not in cluster ctag "
- "(not valid for enable\n\t\t\toperations)\n"));
-
- (void) fprintf(stderr, gettext("\nset:\n"));
- if (clustered)
- (void) fprintf(stderr,
- gettext("\t<phost> <pdev> <pbmp> "
-#ifdef _RDC_CAMPUS
- "<shost> <sdev> <sbmp> {ip | <directfile>} "
-#else
- "<shost> <sdev> <sbmp> ip "
-#endif
- "\\\n\t\t{sync | async} [g <group>] [q <qdev>] "
- "[C <ctag>]\n"));
- else
- (void) fprintf(stderr,
- gettext("\t<phost> <pdev> <pbmp> "
-#ifdef _RDC_CAMPUS
- "<shost> <sdev> <sbmp> {ip | <directfile>} "
-#else
- "<shost> <sdev> <sbmp> ip "
-#endif
- "\\\n\t\t{sync | async} [g <group>] [q <qdev>]\n"));
- (void) fprintf(stderr,
- gettext("\t<shost>:<sdev>\t\t"
- "operate on set matching shost and sdev\n"));
- (void) fprintf(stderr,
- gettext("\t-f volset-file\t\t"
- "operate on all sets specified in config file\n"
- "\t\t\t\tnote: not valid for single set operations. See\n"
- "\t\t\t\t%s(1RDC).\n"), program);
- (void) fprintf(stderr,
- gettext("\t<no arg>\t\toperate on all configured sets\n"));
-}
-
-int
-prompt_user(int flag, int options)
-{
- int c;
-
- switch (flag) {
- case RDC_CMD_DISABLE:
- (void) printf(gettext("Disable Remote Mirror? (Y/N) [N]: "));
- break;
- case RDC_CMD_ENABLE:
- (void) printf(gettext("Enable Remote Mirror? (Y/N) [N]: "));
- break;
- case RDC_CMD_HEALTH:
- (void) printf(gettext("Report Remote Mirror link health? (Y/N)"
- "[N]: "));
- break;
- case RDC_CMD_COPY:
- if (options & RDC_OPT_FULL) {
- if (options & RDC_OPT_REVERSE)
- (void) printf(gettext("Overwrite primary with"
- " secondary? (Y/N) [N]: "));
- else
- (void) printf(gettext("Overwrite secondary with"
- " primary? (Y/N) [N]: "));
- } else {
- if (options & RDC_OPT_REVERSE)
- (void) printf(gettext("Refresh primary with"
- " secondary? (Y/N) [N]: "));
- else
- (void) printf(gettext("Refresh secondary with"
- " primary? (Y/N) [N]: "));
- }
- break;
- case RDC_CMD_RECONFIG:
- (void) printf(gettext(
- "Perform Remote Mirror reconfiguration? (Y/N) [N]: "));
- break;
- case RDC_CMD_RESET:
- (void) printf(gettext("Perform Remote Mirror reset? (Y/N) "
- "[N]: "));
- break;
- case RDC_CMD_TUNABLE:
- (void) printf(gettext("Change Remote Mirror tunable? (Y/N) "
- "[N]: "));
- break;
- case RDC_CMD_LOG:
- (void) printf(gettext(
- "Put Remote Mirror into logging mode? (Y/N) [N]: "));
- break;
- case RDC_CMD_WAIT:
- (void) printf(gettext(
- "Wait for Remote Mirror sync completion? (Y/N) [N]: "));
- break;
- default:
- (void) printf(gettext("Perform Remote Mirror operation? (Y/N) "
- "[N]: "));
- }
-
- c = getchar();
- if ((c != 'y') && (c != 'Y')) {
- (void) printf("\n");
- return (-1);
- }
- return (0);
-}
-
-static void
-load_rdc_vols(CFGFILE *cfg)
-{
- int set;
- char key[ CFG_MAX_KEY ];
- char buf[ CFG_MAX_BUF ];
- _sd_dual_pair_t pair;
- char *vol, *bmp;
- char *host1 = pair.fhost, *host2 = pair.thost;
- char *diskqueue = pair.diskqueue;
- volcount_t *volcount;
- char lghn[ MAX_RDC_HOST_SIZE ];
-
- if (volhash) {
- return;
- }
-
- cfg_rewind(cfg, CFG_SEC_CONF);
- volhash = nsc_create_hash();
- for (set = 1; /*CSTYLED*/; set++) {
- (void) snprintf(key, CFG_MAX_KEY, "sndr.set%d", set);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF)) {
- break;
- }
-
- if (parse_cfg_buf(buf, &pair, lghn))
- continue;
- vol = pair.ffile;
- bmp = pair.fbitmap;
-
- /* use lghn if possible */
- if (*lghn) {
- if (strcmp(host2, lghn) == 0) {
- vol = pair.tfile;
- bmp = pair.tbitmap;
- }
- } else if (!self_check(host1)) {
- /* next one had better be ours */
- vol = pair.tfile;
- bmp = pair.tbitmap;
-
- if (!self_check(host2)) {
- rdc_warn(NULL,
- gettext("config error: neither %s nor %s"
- " is localhost"), host1, host2);
- continue;
- }
- }
-
- /* primary vol may be used more than once */
- volcount = (volcount_t *)nsc_lookup(volhash, vol);
- if (volcount) {
- volcount->count++;
- } else {
- volcount = (volcount_t *)malloc(sizeof (volcount_t));
- volcount->count = 1;
- (void) nsc_insert_node(volhash, volcount, vol);
- }
-
- /* bitmap ought to be only used once */
- volcount = (volcount_t *)nsc_lookup(volhash, bmp);
- if (volcount) {
- /* argh */
- volcount->count++;
- } else {
- volcount = (volcount_t *)malloc(sizeof (volcount_t));
- volcount->count = 1;
- (void) nsc_insert_node(volhash, volcount, bmp);
- }
-
- if (strcmp(diskqueue, place_holder) == 0)
- continue;
- /* diskqueue vol may be used more than once */
- volcount = (volcount_t *)nsc_lookup(volhash, diskqueue);
- if (volcount) {
- volcount->count++;
- } else {
- volcount = (volcount_t *)malloc(sizeof (volcount_t));
- volcount->count = 1;
- (void) nsc_insert_node(volhash, volcount, diskqueue);
- }
- }
-}
-
-static void
-unload_rdc_vols()
-{
- nsc_remove_all(volhash, free);
- volhash = 0;
-}
-
-static int
-perform_autosv()
-{
- if (!clustered) {
- return (1);
- } else {
- return (cfg_issuncluster());
- }
-}
-
-/*
- * Check the user supplied fields against those in the dscfg for
- * this set.
- * Never returns on an error.
- */
-static void
-checkgfields(CFGFILE *cfg, int setnumber, char *fromhost, char *fromfile,
- char *frombitmap, char *tobitmap, char *type, char *mode, char *group,
- char *ctag, char *diskq)
-{
- if (fromhost[0])
- checkgfield(cfg, setnumber, "phost",
- gettext("primary host"), fromhost);
- if (fromfile[0])
- checkgfield(cfg, setnumber, "primary",
- gettext("primary volume"), fromfile);
- if (frombitmap[0])
- checkgfield(cfg, setnumber, "pbitmap",
- gettext("primary bitmap"), frombitmap);
- if (tobitmap[0])
- checkgfield(cfg, setnumber, "sbitmap",
- gettext("secondary bitmap"), tobitmap);
- if (type[0])
- checkgfield(cfg, setnumber, "type",
- gettext("type of connection"), type);
- if (mode[0])
- checkgfield(cfg, setnumber, "mode",
- gettext("mode of connection"), mode);
- if (group[0])
- checkgfield(cfg, setnumber, "group",
- gettext("group"), group);
- if (ctag[0])
- checkgfield(cfg, setnumber, "cnode",
- gettext("cluster tag"), ctag);
- if (diskq[0])
- checkgfield(cfg, setnumber, "diskq",
- gettext("disk queue volume"), diskq);
-}
-
-/*
- * Check the 'fname' field in the dscfg file for set number 'setnumber'
- * If it does not match the user's data, 'data', then print the error
- * message using the friendly field name 'ufield'.
- * Never returns on an error.
- */
-static void
-checkgfield(CFGFILE *cfg, int setnumber, char *fname, char *ufield, char *data)
-{
- char buf[CFG_MAX_BUF];
- char key[CFG_MAX_KEY];
-
- (void) snprintf(key, sizeof (key), "sndr.set%d.%s", setnumber, fname);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) {
- rdc_err(NULL, gettext("unable to fetch data for key %s"),
- key);
- }
- if (strcmp(buf, data) != 0) {
- rdc_err(NULL,
- gettext("the value specified for the %s field is not\nthe "
- "same as that contained within the configuration storage "
- "file for this set.\nYou specified \"%s\" "
- "expected \"%s\"."),
- ufield, data, buf);
- }
-}
-
-/*
- * load and send the contents of the bitmap file to the kernel.
- */
-static int
-rdc_bitmapset(char *tohost, char *tofile, char *bitmap, int op,
- nsc_off_t offset)
-{
- rdc_bitmap_op_t bmop;
- int fd;
- void *buffer;
- int buffersz;
- struct stat s;
- int n;
- int ret;
- /*
- * open bitmap file for reading.
- */
- if ((fd = open(bitmap, O_RDONLY)) < 0) {
- rdc_warn(NULL, gettext("Unable to open bitmap file %s"),
- bitmap);
- return (1);
- }
- (void) fstat(fd, &s);
-
- if (S_ISREG(s.st_mode) == 0) {
- rdc_warn(NULL, gettext("Bitmap %s is not a regular file"),
- bitmap);
- (void) close(fd);
- return (1);
- }
-
- if (op == 0) {
- op = RDC_BITMAPOR;
- }
- /*
- * use the file size to allocate buffer. This
- * size should be a multiple of FBA, but don't check
- * it here.
- */
- buffersz = s.st_size;
- buffer = malloc(buffersz);
- if (buffer == NULL) {
- rdc_warn(NULL, gettext("Unable to allocate %d bytes "
- "for bitmap file %s"), buffersz, bitmap);
- (void) close(fd);
- return (1);
- }
- n = read(fd, buffer, buffersz);
- (void) close(fd);
- if (n != buffersz) {
- rdc_warn(NULL, gettext("Unable to read the bitmap file, "
- "read returned %d instead of %d"),
- n, buffersz);
- free(buffer);
- return (1);
- }
- bmop.offset = offset;
- bmop.op = op;
- (void) strncpy(bmop.sechost, tohost, MAX_RDC_HOST_SIZE);
- (void) strncpy(bmop.secfile, tofile, NSC_MAXPATH);
- bmop.len = buffersz;
- bmop.addr = (unsigned long)buffer;
- ret = rdc_ioctl_simple(RDC_BITMAPOP, &bmop);
- free(buffer);
- if (ret < 0) {
- rdc_warn(NULL, gettext("Setting bitmap ioctl failed for set "
- "%s:%s"), tohost, tofile);
-
- switch (errno) {
- case EIO:
- rdc_warn(NULL, gettext("One of the sets is not "
- "enabled"));
- break;
- case ENXIO:
- rdc_warn(NULL, gettext("One of the sets is not "
- "logging"));
- break;
- default:
- break;
- }
- } else {
- ret = 0;
- }
- if (ret)
- ret = 1;
- return (ret);
-}
-
-/*
- * verify_groupname: Check the group name for the following rules:
- * 1. The name does not start with a '-'
- * 2. The name does not contain any space characters as defined by
- * isspace(3C).
- *
- * If either of these rules are broken, error immediately.
- */
-static void
-verify_groupname(char *grp)
-{
- int i;
-
- if (grp[0] == '-') {
- rdc_err(NULL, gettext("group name cannot start with a '-'"));
- }
-
- for (i = 0; grp[i] != '\0'; i++) {
- if (isspace(grp[i])) {
- rdc_err(NULL, gettext("group name cannot contain a "
- "space"));
- }
- }
-}
diff --git a/usr/src/cmd/avs/rdc/sndrboot.c b/usr/src/cmd/avs/rdc/sndrboot.c
deleted file mode 100644
index fcdb59899b..0000000000
--- a/usr/src/cmd/avs/rdc/sndrboot.c
+++ /dev/null
@@ -1,881 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <stdio.h>
-#include <sys/mnttab.h>
-#include <errno.h>
-#include <limits.h>
-#include <fcntl.h>
-#include <strings.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <locale.h>
-#include <langinfo.h>
-#include <libintl.h>
-#include <stdarg.h>
-#include <netdb.h>
-#include <ctype.h>
-#include <sys/utsname.h>
-
-#include <sys/nsctl/rdc_io.h>
-#include <sys/nsctl/rdc_ioctl.h>
-#include <sys/nsctl/rdc_prot.h>
-
-#include <sys/nsctl/cfg.h>
-#include <sys/nsctl/cfg_cluster.h>
-
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_u.h>
-#include <sys/unistat/spcs_errors.h>
-
-#include "rdcadm.h"
-
-/*
- * Special re-use of sndrboot to fix SNDR set IDs during post-patch processing
- */
-#define RDC_CMD_FIXSETIDS 0xFEEDFACE
-
-/*
- * config file user level Dual copy pair structure
- */
-typedef struct _sd_dual_pair {
- char fhost[MAX_RDC_HOST_SIZE]; /* Hostname for primary device */
- char fnetaddr[RDC_MAXADDR]; /* Host netaddr for primary device */
- char ffile[NSC_MAXPATH]; /* Primary device */
- char fbitmap[NSC_MAXPATH]; /* Primary bitmap device */
- char thost[MAX_RDC_HOST_SIZE]; /* Hostname for secondary device */
- char tnetaddr[RDC_MAXADDR]; /* Host netaddr for secondary device */
- char tfile[NSC_MAXPATH]; /* Secondary device */
- char tbitmap[NSC_MAXPATH]; /* Secondary bitmap device */
- char directfile[NSC_MAXPATH]; /* Local FCAL direct IO volume */
- char diskqueue[NSC_MAXPATH]; /* Disk Queue volume */
- char group[NSC_MAXPATH]; /* Group name */
- char lhost[MAX_RDC_HOST_SIZE]; /* Logical hostname for cluster */
- int doasync; /* Device is in sync/async mode */
- int setid; /* unique setid of this set */
-} _sd_dual_pair_t;
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netinet/tcp.h>
-#include <rpc/rpc_com.h>
-#include <rpc/rpc.h>
-
-#include <sys/nsctl/librdc.h>
-
-char *ctag = NULL;
-
-int parseopts(int, char **, int *);
-static int rdc_operation(char *, char *, char *, char *, char *, char *, int,
- char *, char *, char *, int, char *, int setid);
-static int read_libcfg(int);
-static void usage(void);
-
-extern char *basename(char *);
-
-int rdc_maxsets;
-static _sd_dual_pair_t *pair_list;
-char *program;
-
-struct netbuf svaddr;
-struct netbuf *svp;
-struct netconfig nconf;
-struct netconfig *conf;
-struct knetconfig knconf;
-static int clustered = 0;
-static int proto_test = 0;
-
-#ifdef lint
-int
-sndrboot_lintmain(int argc, char *argv[])
-#else
-int
-main(int argc, char *argv[])
-#endif
-{
- char fromhost[MAX_RDC_HOST_SIZE];
- char tohost[MAX_RDC_HOST_SIZE];
- char fromfile[NSC_MAXPATH];
- char tofile[NSC_MAXPATH];
- char frombitmap[NSC_MAXPATH];
- char tobitmap[NSC_MAXPATH];
- char directfile[NSC_MAXPATH];
- char diskqueue[NSC_MAXPATH];
- char group[NSC_MAXPATH];
- char lhost[MAX_RDC_HOST_SIZE];
- int pairs;
- int pid;
- int flag = 0;
- int doasync;
- int rc;
- char *required;
- int setid;
-
- (void) setlocale(LC_ALL, "");
- (void) textdomain("rdc");
-
- program = basename(argv[0]);
-
- rc = rdc_check_release(&required);
- if (rc < 0) {
- rdc_err(NULL,
- gettext("unable to determine the current "
- "Solaris release: %s\n"), strerror(errno));
- } else if (rc == FALSE) {
- rdc_err(NULL,
- gettext("incorrect Solaris release (requires %s)\n"),
- required);
- }
-
- rdc_maxsets = rdc_get_maxsets();
- if (rdc_maxsets == -1) {
- spcs_log("sndr", NULL,
- gettext("%s unable to get maxsets value from kernel"),
- program);
-
- rdc_err(NULL,
- gettext("unable to get maxsets value from kernel"));
- }
-
- pair_list = calloc(rdc_maxsets, sizeof (*pair_list));
- if (pair_list == NULL) {
- rdc_err(NULL,
- gettext(
- "unable to allocate pair_list"
- " array for %d sets"),
- rdc_maxsets);
- }
-
- if (parseopts(argc, argv, &flag))
- return (1);
- pairs = read_libcfg(flag);
-
- if (flag == RDC_CMD_FIXSETIDS) {
- if (pairs) {
- spcs_log("sndr", NULL, gettext("Fixed %d Remote Mirror"
- " set IDs"), pairs);
-#ifdef DEBUG
- rdc_warn(NULL, gettext("Fixed %d Remote Mirror set "
- "IDs"), pairs);
-#endif
- }
- return (0);
- }
-
- if (pairs == 0) {
-#ifdef DEBUG
- rdc_err(NULL,
- gettext("Config contains no dual copy sets"));
-#else
- return (0);
-#endif
- }
-
- while (pairs--) {
- pid = fork();
- if (pid == -1) { /* error forking */
- perror("fork");
- continue;
- }
-
- if (pid > 0) /* this is parent process */
- continue;
-
-/*
- * At this point, this is the child process. Do the operation
- */
-
- (void) strncpy(fromfile,
- pair_list[pairs].ffile, NSC_MAXPATH);
- (void) strncpy(tofile,
- pair_list[pairs].tfile, NSC_MAXPATH);
- (void) strncpy(frombitmap,
- pair_list[pairs].fbitmap, NSC_MAXPATH);
- (void) strncpy(fromhost,
- pair_list[pairs].fhost, MAX_RDC_HOST_SIZE);
- (void) strncpy(tohost,
- pair_list[pairs].thost, MAX_RDC_HOST_SIZE);
- (void) strncpy(tobitmap,
- pair_list[pairs].tbitmap, NSC_MAXPATH);
- (void) strncpy(directfile,
- pair_list[pairs].directfile, NSC_MAXPATH);
- (void) strncpy(diskqueue,
- pair_list[pairs].diskqueue, NSC_MAXPATH);
- (void) strncpy(group,
- pair_list[pairs].group, NSC_MAXPATH);
- (void) strncpy(lhost,
- pair_list[pairs].lhost, MAX_RDC_HOST_SIZE);
-
- doasync = pair_list[pairs].doasync;
- setid = pair_list[pairs].setid;
- if (rdc_operation(fromhost, fromfile, frombitmap,
- tohost, tofile, tobitmap, flag, directfile, group,
- diskqueue, doasync, lhost, setid)
- < 0) {
- exit(255);
- }
-
- exit(0);
- }
-
- while ((wait((int *)0) > 0))
- ;
- return (0);
-}
-
-static int
-rdc_operation(fromhost, fromfile, frombitmap, tohost, tofile,
- tobitmap, flag, directfile, group, diskqueue, doasync,
- lhost, setid)
-char *fromhost, *fromfile, *frombitmap;
-char *tohost, *tofile, *tobitmap;
-int flag, doasync;
-char *directfile;
-char *group, *diskqueue;
-int setid;
-char *lhost;
-{
- const int getaddr = (flag == RDC_CMD_RESUME);
- const int rpcbind = !getaddr;
- rdc_config_t parms;
- int ret;
- spcs_s_info_t ustatus;
- struct hostent *hp;
- char fromname[MAXHOSTNAMELEN], toname[MAXHOSTNAMELEN];
- struct t_info tinfo;
- int i;
-
- conf = &nconf;
- bzero(&fromname, MAXHOSTNAMELEN);
- bzero(&toname, MAXHOSTNAMELEN);
-
- hp = gethost_byname(fromhost);
- if (hp == NULL) {
- spcs_log("sndr", NULL,
- gettext("%s gethost_byname failed for %s"),
- program, fromhost);
- }
- if (strcmp(hp->h_name, fromhost) == 0)
- (void) strncpy(fromname, hp->h_name, MAXHOSTNAMELEN);
- else {
- for (i = 0; hp->h_aliases[i] != NULL; i++) {
- if (strcmp(hp->h_aliases[i], fromhost) == 0)
- (void) strncpy(fromname, hp->h_aliases[i],
- MAXHOSTNAMELEN);
- }
- }
- if (fromname[0] == '\0') {
- spcs_log("sndr", NULL,
- gettext("%s host %s is not local"),
- program, fromhost);
- rdc_err(NULL, gettext("Host %s is not local"),
- fromhost);
- }
- hp = gethost_byname(tohost);
- if (hp == NULL) {
- spcs_log("sndr", NULL,
- gettext("%s gethost_byname failed for %s"),
- program, tohost);
- }
- if (strcmp(hp->h_name, tohost) == 0)
- (void) strncpy(toname, hp->h_name, MAXHOSTNAMELEN);
- else {
- for (i = 0; hp->h_aliases[i] != NULL; i++) {
- if (strcmp(hp->h_aliases[i], tohost) == 0)
- (void) strncpy(toname, hp->h_aliases[i],
- MAXHOSTNAMELEN);
- }
- }
- if (toname[0] == '\0') {
- spcs_log("sndr", NULL,
- gettext("%s host %s is not local"),
- program, tohost);
- rdc_err(NULL, gettext("Host %s is not local"),
- tohost);
- }
-
- if (self_check(fromname) && self_check(toname)) {
- spcs_log("sndr", NULL,
- gettext("%s Both %s and %s are local"),
- program, fromhost, tohost);
- rdc_err(NULL, gettext("Both %s and %s are local"),
- fromhost, tohost);
- }
-
- /*
- * Now build up the address for each host including port and transport
- */
- if (getaddr) {
- svp = get_addr(toname, RDC_PROGRAM, RDC_VERS_MIN,
- &conf, proto_test?NC_UDP: NULL, "rdc", &tinfo, rpcbind);
-
- if (svp == NULL) {
-#ifdef DEBUG
- (void) printf("get_addr failed for Ver 4 %s\n", toname);
-#endif
- spcs_log("sndr", NULL,
- gettext("%s get_addr failed for Ver 4"),
- program);
- return (-1);
- }
- svaddr = *svp;
- } else {
- bzero(&svaddr, sizeof (svaddr));
- }
-
- parms.rdc_set->secondary.addr.len = svaddr.len;
- parms.rdc_set->secondary.addr.maxlen = svaddr.maxlen;
- parms.rdc_set->secondary.addr.buf = (void *)svaddr.buf;
-
-#ifdef DEBUG_ADDR
- (void) fprintf(stderr,
- "secondary buf %x len %d\n", svaddr.buf, svaddr.len);
-
- for (i = 0; i < svaddr.len; i++)
- (void) printf("%u ", svaddr.buf[i]);
- (void) printf("\n");
-#endif
-
- if (getaddr) {
- svp = get_addr(fromname, RDC_PROGRAM, RDC_VERS_MIN,
- &conf, proto_test?NC_UDP: NULL, "rdc", &tinfo, rpcbind);
- if (svp == NULL) {
-#ifdef DEBUG
- (void) printf("get_addr failed for Ver 4 %s\n",
- fromname);
-#endif
- return (-1);
- }
- svaddr = *svp;
- } else {
- ;
- /*EMPTY*/
- }
- parms.rdc_set->primary.addr.len = svaddr.len;
- parms.rdc_set->primary.addr.maxlen = svaddr.maxlen;
- parms.rdc_set->primary.addr.buf =
- (void *)svaddr.buf;
-
-#ifdef DEBUG_ADDR
- (void) fprintf(stderr, "primary buf %x len %d\n",
- svaddr.buf, svaddr.len);
- for (i = 0; i < svaddr.len; i++)
- (void) printf("%u ", svaddr.buf[i]);
- (void) printf("\n");
-#endif
-
- if (getaddr) {
- (void) convert_nconf_to_knconf(conf, &knconf);
-#ifdef DEBUG_ADDR
- (void) printf("knconf %x %s %s %x\n", knconf.knc_semantics,
- knconf.knc_protofmly, knconf.knc_proto, knconf.knc_rdev);
-#endif
- parms.rdc_set->netconfig = &knconf;
- } else {
- parms.rdc_set->netconfig = NULL;
- }
- if (!clustered && !self_check(fromname) && !self_check(toname)) {
- spcs_log("sndr", NULL,
- gettext("%s Neither %s nor %s is local"),
- program, fromhost, tohost);
- rdc_err(NULL, gettext("Neither %s nor %s is local"),
- fromhost, tohost);
- }
- (void) strncpy(parms.rdc_set->primary.intf, fromhost,
- MAX_RDC_HOST_SIZE);
- (void) strncpy(parms.rdc_set->primary.file, fromfile, NSC_MAXPATH);
- (void) strncpy(parms.rdc_set->primary.bitmap, frombitmap, NSC_MAXPATH);
-
- (void) strncpy(parms.rdc_set->secondary.intf, tohost,
- MAX_RDC_HOST_SIZE);
- (void) strncpy(parms.rdc_set->secondary.file, tofile, NSC_MAXPATH);
- (void) strncpy(parms.rdc_set->secondary.bitmap, tobitmap, NSC_MAXPATH);
-
- (void) strncpy(parms.rdc_set->group_name, group, NSC_MAXPATH);
- (void) strncpy(parms.rdc_set->disk_queue, diskqueue, NSC_MAXPATH);
-
- parms.rdc_set->maxqfbas = maxqfbas;
- parms.rdc_set->maxqitems = maxqitems;
- parms.rdc_set->autosync = autosync;
- parms.rdc_set->asyncthr = asyncthr;
- parms.rdc_set->setid = setid;
-
- /* gethostid(3c) is defined to return a 32bit value */
- parms.rdc_set->syshostid = (int32_t)gethostid();
-
- parms.command = 0;
- parms.options = 0;
- parms.command = flag;
-
- if (flag == RDC_CMD_RESUME) {
- if (doasync)
- parms.options |= RDC_OPT_ASYNC;
- else
- parms.options |= RDC_OPT_SYNC;
- }
- if (clustered) {
- if (!ctag)
- goto noconfig;
- if (strcmp(ctag, "-") == 0)
- goto noconfig;
-
-#ifdef DEBUG
- (void) fprintf(stderr, "logical hostname: %s\n", lhost);
-#endif
-
- if (strcmp(lhost, fromname) == 0) {
- parms.options |= RDC_OPT_PRIMARY;
- (void) strncpy(parms.rdc_set->direct_file, directfile,
- NSC_MAXPATH);
-
- } else {
- parms.options |= RDC_OPT_SECONDARY;
- parms.rdc_set->direct_file[0] = 0; /* no fcal direct */
- }
- } else {
-noconfig:
- /*
- * If not clustered, don't resume sndr sets with lhost
- */
- if ((flag == RDC_CMD_RESUME) && lhost && strlen(lhost))
- return (0);
-
- if (self_check(fromname)) {
- parms.options |= RDC_OPT_PRIMARY;
- (void) strncpy(parms.rdc_set->direct_file, directfile,
- NSC_MAXPATH);
- } else {
- parms.options |= RDC_OPT_SECONDARY;
- parms.rdc_set->direct_file[0] = 0; /* no fcal direct */
- }
- }
-
- ustatus = spcs_s_ucreate();
-
- errno = 0;
- ret = RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, ustatus);
- if (ret != SPCS_S_OK) {
-
- /* Surpress error messages for suspend on cluster elements */
- if ((flag == RDC_CMD_SUSPEND) && (errno == RDC_EALREADY) &&
- !clustered && lhost && strlen(lhost)) {
- spcs_s_ufree(&ustatus);
- return (0);
- }
-
- (void) fprintf(stderr,
- gettext("Remote Mirror: %s %s %s %s %s %s\n"),
- fromhost, fromfile,
- frombitmap, tohost, tofile, tobitmap);
-
- if (errno == RDC_EEINVAL) {
- spcs_log("sndr", NULL,
- gettext("%s %s %s %s %s %s %s %s\n%s"),
- program, rdc_decode_flag(flag, parms.options),
- fromhost, fromfile, frombitmap,
- tohost, tofile, tobitmap,
- gettext("invalid command option"));
- rdc_err(&ustatus,
- gettext("Remote Mirror: invalid command option "
- "'%s'"), rdc_decode_flag(flag,
- parms.options));
- } else {
- spcs_log("sndr", &ustatus,
- gettext("%s %s %s %s %s %s %s %s"),
- program, rdc_decode_flag(flag, parms.options),
- fromhost, fromfile, frombitmap,
- tohost, tofile, tobitmap);
- rdc_err(&ustatus, 0);
- }
- }
-
- spcs_log("sndr", NULL,
- gettext("%s %s %s %s %s %s %s %s\nSuccessful"),
- program, rdc_decode_flag(flag, parms.options),
- fromhost, fromfile, frombitmap, tohost, tofile, tobitmap);
-
- spcs_s_ufree(&ustatus);
- return (0);
-}
-/*
- * assign setid's to any existing
- * sets without setids, making sure of course NOT to re-use a setid
- */
-int
-update_setids(CFGFILE *cfg, int *no_id, int highest)
-{
- int setid;
- char buf[CFG_MAX_BUF];
- char key[CFG_MAX_KEY];
- char *ctag;
-
- /* If in a Sun Cluster, SetIDs need to have a ctag */
- if ((ctag = cfg_get_resource(cfg)) != NULL) {
- ctag = strdup(ctag);
- cfg_resource(cfg, "setid-ctag");
- }
-
- /*
- * Paranoia. IF there are any sets with setids, we don't
- * want to re-use their number.
- */
- if (highest > get_new_cfg_setid(cfg)) {
- bzero(&buf, sizeof (buf));
- (void) sprintf(buf, "%d", highest);
- if (cfg_put_cstring(cfg, "setid.set1.value", buf,
- sizeof (buf)) < 0)
- rdc_warn(NULL, gettext("sndrboot: Unable to store "
- "new setid"));
- }
-
- for (setid = 0; no_id[setid]; setid++) {
- bzero(&buf, sizeof (buf));
- bzero(&key, sizeof (key));
- (void) sprintf(buf, "%d", get_new_cfg_setid(cfg));
- (void) sprintf(key, "sndr.set%d.options", no_id[setid]);
- if (cfg_put_options(cfg, CFG_SEC_CONF, key, "setid", buf) < 0)
- rdc_warn(NULL, gettext("sndrboot: Unable to store "
- "unique setid"));
-
- pair_list[no_id[setid] - 1].setid = atoi(buf);
- }
-
- /* Restore old ctag if in a Sun Cluster */
- if (ctag) {
- cfg_resource(cfg, ctag);
- free(ctag);
- }
-
- if (cfg_commit(cfg) < 0)
- rdc_err(NULL, gettext("sndrboot: Failed to commit setids"));
-
- return (setid);
-}
-
-/*
- * this is called when the option lghn is no available in libdscfg
- * that should only happen on an upgrade.
- * cfg write lock must be held across this function
- */
-char *
-get_lghn(CFGFILE *cfg, char *ctag, int setnum, int flag)
-{
- FILE *pipe;
- char rsgrp[SCCONF_MAXSTRINGLEN];
- char cmd[SCCONF_MAXSTRINGLEN];
- static char lhostname[MAX_RDC_HOST_SIZE];
- char key[CFG_MAX_KEY];
- int rc;
-
- if (ctag == NULL)
- goto fail;
-
- bzero(&lhostname, sizeof (lhostname));
-
- (void) sprintf(rsgrp, "%s-stor-rg", ctag);
-/* BEGIN CSTYLED */
- rc = snprintf(cmd, SCCONF_MAXSTRINGLEN,
- "/usr/cluster/bin/scrgadm -pvv | fgrep HostnameList \
-| fgrep %s | fgrep value | awk -F: '{ print $4 }'", rsgrp);
-/* END CSTYLED */
-
- if (rc < 0) {
- rdc_err(NULL, gettext("Error getting scrgadm output"));
- }
-
- pipe = popen(cmd, "r");
-
- if (pipe == NULL) {
- rdc_err(NULL, gettext("Error opening pipe"));
- }
- rc = fscanf(pipe, "%s", lhostname);
- (void) pclose(pipe);
-
- if (rc != 1) {
- rdc_err(NULL, gettext("Unable to get logical host"));
- }
-
- /* not really failing, but suspend does not have the config lock */
- if (flag == RDC_CMD_SUSPEND)
- goto fail;
-
- bzero(&key, sizeof (key));
- (void) snprintf(key, sizeof (key), "sndr.set%d.options", setnum);
- if (cfg_put_options(cfg, CFG_SEC_CONF, key, "lghn", lhostname) < 0)
- rdc_warn(NULL, gettext("sndrboot: Unable to store logical "
- "host name in configuration database"));
-
- if (cfg_commit(cfg) < 0)
- rdc_err(NULL,
- gettext("sndrboot: Failed to commit logical host name"));
-
-fail:
- return (lhostname);
-
-}
-
-/*
- * read_libcfg()
- *
- * DESCRIPTION: Read the relevant config info via libcfg
- *
- * Outputs:
- * int i Number of pairs of devices
- *
- * Side Effects: The 0 to i-1 entries in the pair_list are filled.
- *
- */
-static int
-read_libcfg(int flag)
-{
- char fromhost[MAX_RDC_HOST_SIZE];
- char fromfile[NSC_MAXPATH];
- char frombitmap[NSC_MAXPATH];
- char tohost[MAX_RDC_HOST_SIZE];
- char tofile[NSC_MAXPATH];
- char tobitmap[NSC_MAXPATH];
- char directfile[NSC_MAXPATH];
- char diskqueue[NSC_MAXPATH];
- char group[NSC_MAXPATH];
- char lhost[MAX_RDC_HOST_SIZE];
- char sync[16];
- char setid[64];
- int doasync;
- CFGFILE *cfg;
- int i, j = 0;
- int rc;
- char buf[CFG_MAX_BUF];
- char key[CFG_MAX_KEY];
- char dummy[NSC_MAXPATH];
- int setnumber;
- int numsets;
- int highest = 0;
- char lghn[5];
- int *no_id;
-
-
- if ((cfg = cfg_open("")) == NULL)
- rdc_err(NULL, gettext("Error opening config"));
-
- /*
- * If RDC_CMD_FIXSETIDS, we were called during post-patch install
- * Acquire a write-lock on the cfg_lock(), so the code can attempt
- * to fix setIDs
- */
- if (flag == RDC_CMD_FIXSETIDS) {
- if (!cfg_lock(cfg, CFG_WRLOCK))
- rdc_err(NULL, gettext("Error write locking config"));
- cfg_resource(cfg, NULL);
- } else {
- if (!cfg_lock(cfg, CFG_RDLOCK))
- rdc_err(NULL, gettext("Error locking config"));
- cfg_resource(cfg, ctag);
- }
-
- if ((numsets = cfg_get_num_entries(cfg, "sndr")) < 0)
- rdc_err(NULL, gettext("Unable to get set info from config"));
-
- no_id = (int *)calloc(numsets + 1, sizeof (int));
- if (!no_id)
- rdc_err(NULL, gettext("No memory"));
-
-
- (void) snprintf(lghn, sizeof (lghn), "lghn");
-
- for (i = 0; i < rdc_maxsets; i++) {
- setnumber = i + 1;
-
- bzero(buf, CFG_MAX_BUF);
- (void) snprintf(key, sizeof (key), "sndr.set%d", setnumber);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
- break;
-
- rc = sscanf(buf, "%s %s %s %s %s %s %s %s %s %s %s %s",
- fromhost, fromfile, frombitmap, tohost, tofile, tobitmap,
- directfile, sync, group, dummy, dummy, diskqueue);
- if (rc != 12)
- rdc_err(NULL, gettext("cfg input error (%d)"), rc);
-
- if (strcmp(directfile, "ip") == 0)
- (void) strcpy(directfile, "");
-
- if (strcmp(group, "-") == 0)
- (void) strcpy(group, "");
-
- if (strcmp(diskqueue, "-") == 0)
- (void) strcpy(diskqueue, "");
-
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.options", setnumber);
-
- if (cfg_get_single_option(cfg, CFG_SEC_CONF, key,
- lghn, lhost, MAX_RDC_HOST_SIZE) < 0)
- (void) strcpy(lhost,
- get_lghn(cfg, ctag, setnumber, flag));
-
- if (strcmp(sync, "sync") == 0)
- doasync = 0;
- else if (strcmp(sync, "async") == 0)
- doasync = 1;
- else {
- cfg_close(cfg);
- rdc_err(NULL,
- gettext("Set %s:%s neither sync nor async"),
- tohost, tofile);
- }
-
- (void) strncpy(pair_list[i].fhost, fromhost,
- MAX_RDC_HOST_SIZE);
- (void) strncpy(pair_list[i].ffile, fromfile, NSC_MAXPATH);
- (void) strncpy(pair_list[i].fbitmap, frombitmap, NSC_MAXPATH);
- (void) strncpy(pair_list[i].thost, tohost, MAX_RDC_HOST_SIZE);
- (void) strncpy(pair_list[i].tfile, tofile, NSC_MAXPATH);
- (void) strncpy(pair_list[i].tbitmap, tobitmap, NSC_MAXPATH);
- (void) strncpy(pair_list[i].directfile, directfile,
- NSC_MAXPATH);
- (void) strncpy(pair_list[i].diskqueue, diskqueue,
- NSC_MAXPATH);
- (void) strncpy(pair_list[i].group, group, NSC_MAXPATH);
- (void) strncpy(pair_list[i].lhost, lhost, MAX_RDC_HOST_SIZE);
- pair_list[i].doasync = doasync;
-
- if (cfg_get_single_option(cfg, CFG_SEC_CONF, key, "setid",
- setid, sizeof (setid)) < 0) {
- no_id[j++] = setnumber;
- }
- pair_list[i].setid = atoi(setid);
-
- if (pair_list[i].setid > highest)
- highest = pair_list[i].setid;
-
- if (gethost_netaddrs(fromhost, tohost,
- (char *)pair_list[i].fnetaddr,
- (char *)pair_list[i].tnetaddr) < 0) {
- cfg_close(cfg);
- spcs_log("sndr", NULL,
- gettext("%s unable to determine IP addresses "
- "for hosts %s %s"), program, fromhost, tohost);
- rdc_err(NULL, gettext("unable to determine IP "
- "addresses for hosts %s, %s"), fromhost, tohost);
- }
- }
- /*
- * fix any lost set ids if possible, also deal with upgrade
- */
- if (j > 0 && flag == RDC_CMD_FIXSETIDS) {
- (void) update_setids(cfg, no_id, highest);
- i = j; /* Set number of fixups */
- }
- free(no_id);
- cfg_close(cfg);
- return (i);
-}
-
-
-int
-parseopts(argc, argv, flag)
-int argc;
-char **argv;
-int *flag;
-{
- int errflag = 0;
- char c;
- char inval = 0;
-#ifdef DEBUG
- while ((c = getopt(argc, argv, "C:Urs")) != -1) {
-#else
- while ((c = getopt(argc, argv, "C:rs")) != -1) {
-#endif
- switch (c) {
- case 'C':
- clustered = TRUE;
- ctag = optarg;
- break;
-#ifdef DEBUG
- case 'U':
- proto_test = 1;
- break;
-#endif
- case 'r':
- if (*flag)
- inval = 1;
- *flag = RDC_CMD_RESUME;
- break;
- case 's':
- if (*flag)
- inval = 1;
- *flag = RDC_CMD_SUSPEND;
- break;
- case '?':
- errflag++;
- }
- }
-
- /*
- * Special fix to address no SetIds in AVS 3.1 to 3.2 install + patch
- * Adjust set IDs, if someone invokes the following invalid command
- *
- * /use/sbin/sndrboot -C post-patch-setids -r -s
- *
- * Command will be called in post-install of the patch containing fix
- *
- */
- if (clustered && (strcmp(ctag, "post-patch-setids") == 0) &&
- *flag && inval) {
- *flag = RDC_CMD_FIXSETIDS;
- return (0);
- }
-
- if (inval) {
- rdc_warn(NULL, gettext("Invalid argument combination"));
- errflag = 1;
- }
-
- if (!*flag || errflag) {
- usage();
- return (-1);
- }
-
- return (0);
-}
-
-static void
-usage()
-{
- (void) fprintf(stderr, gettext("usage:\n"));
- (void) fprintf(stderr,
- gettext("\t%s -r [-C tag]\t\t"
- "resume\n"), program);
-
- (void) fprintf(stderr,
- gettext("\t%s -s [-C tag]\t\t"
- "suspend\n"), program);
-}
diff --git a/usr/src/cmd/avs/rdc/sndrd.c b/usr/src/cmd/avs/rdc/sndrd.c
deleted file mode 100644
index aa04f19127..0000000000
--- a/usr/src/cmd/avs/rdc/sndrd.c
+++ /dev/null
@@ -1,2013 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-/*
- * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
- * Copyright 2014 Gary Mills
- */
-
-/*
- * Network SNDR/ncall-ip server - based on nfsd
- */
-#include <sys/types.h>
-#include <rpc/types.h>
-#include <errno.h>
-#include <netdb.h>
-#include <sys/socket.h>
-#include <netconfig.h>
-#include <stropts.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <strings.h>
-#include <signal.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <netdir.h>
-#include <rpc/rpc_com.h>
-#include <rpc/rpc.h>
-#include <tiuser.h>
-#include <netinet/tcp.h>
-#include <netinet/in.h>
-#include <syslog.h>
-#include <locale.h>
-#include <langinfo.h>
-#include <libintl.h>
-#include <libgen.h>
-#include <deflt.h>
-#include <sys/resource.h>
-
-#include <sys/nsctl/nsctl.h>
-
-#ifdef __NCALL__
-
-#include <sys/ncall/ncall.h>
-#include <sys/ncall/ncall_ip.h>
-#include <sys/nsctl/libncall.h>
-
-#define RDC_POOL_CREATE NC_IOC_POOL_CREATE
-#define RDC_POOL_RUN NC_IOC_POOL_RUN
-#define RDC_POOL_WAIT NC_IOC_POOL_WAIT
-#define RDC_PROGRAM NCALL_PROGRAM
-#define RDC_SERVICE "ncall"
-#undef RDC_SVCPOOL_ID /* We are overloading this value */
-#define RDC_SVCPOOL_ID NCALL_SVCPOOL_ID
-#define RDC_SVC_NAME "NCALL"
-#define RDC_VERS_MIN NCALL_VERS_MIN
-#define RDC_VERS_MAX NCALL_VERS_MAX
-
-#else /* !__NCALL__ */
-
-#include <sys/nsctl/rdc_ioctl.h>
-#include <sys/nsctl/rdc_io.h>
-#include <sys/nsctl/librdc.h>
-
-#define RDC_SERVICE "rdc"
-#define RDC_SVC_NAME "RDC"
-
-#endif /* __NCALL__ */
-
-#define RDCADMIN "/etc/default/sndr"
-
-#include <nsctl.h>
-
-struct conn_ind {
- struct conn_ind *conn_next;
- struct conn_ind *conn_prev;
- struct t_call *conn_call;
-};
-
-struct conn_entry {
- bool_t closing;
- struct netconfig nc;
-};
-
-static char *progname;
-static struct conn_entry *conn_polled;
-static int num_conns; /* Current number of connections */
-static struct pollfd *poll_array; /* array of poll descriptors for poll */
-static size_t num_fds = 0; /* number of transport fds opened */
-static void poll_for_action();
-static void remove_from_poll_list(int);
-static int do_poll_cots_action(int, int);
-static int do_poll_clts_action(int, int);
-static void add_to_poll_list(int, struct netconfig *);
-static int bind_to_provider(char *, char *, struct netbuf **,
- struct netconfig **);
-static int set_addrmask(int, struct netconfig *, struct netbuf *);
-static void conn_close_oldest(void);
-static boolean_t conn_get(int, struct netconfig *, struct conn_ind **);
-static void cots_listen_event(int, int);
-static int discon_get(int, struct netconfig *, struct conn_ind **);
-static int nofile_increase(int);
-static int is_listen_fd_index(int);
-#if !defined(_SunOS_5_6) && !defined(_SunOS_5_7) && !defined(_SunOS_5_8)
-static int sndrsvcpool(int);
-static int svcwait(int id);
-#endif
-
-
-/*
- * RPC protocol block. Useful for passing registration information.
- */
-struct protob {
- char *serv; /* ASCII service name, e.g. "RDC" */
- int versmin; /* minimum version no. to be registered */
- int versmax; /* maximum version no. to be registered */
- int program; /* program no. to be registered */
- struct protob *next; /* next entry on list */
-};
-
-
-
-static size_t end_listen_fds;
-static int debugflg = 0;
-static int max_conns_allowed = -1;
-static int listen_backlog = 10;
-static char *trans_provider = (char *)NULL;
-static int rdcsvc(int, struct netbuf, struct netconfig *);
-
-/* used by cots_listen_event() */
-static int (*Mysvc)(int, struct netbuf, struct netconfig *) = rdcsvc;
-
-/*
- * Determine valid semantics for rdc.
- */
-#define OK_TPI_TYPE(_nconf) \
- (_nconf->nc_semantics == NC_TPI_CLTS || \
- _nconf->nc_semantics == NC_TPI_COTS || \
- _nconf->nc_semantics == NC_TPI_COTS_ORD)
-
-#define BE32_TO_U32(a) \
- ((((uint32_t)((uchar_t *)a)[0] & 0xFF) << (uint32_t)24) |\
- (((uint32_t)((uchar_t *)a)[1] & 0xFF) << (uint32_t)16) |\
- (((uint32_t)((uchar_t *)a)[2] & 0xFF) << (uint32_t)8) |\
- ((uint32_t)((uchar_t *)a)[3] & 0xFF))
-
-#ifdef DEBUG
-/*
- * Only support UDP in DEBUG mode for now
- */
-static char *defaultproviders[] = { "/dev/tcp", "/dev/tcp6", "/dev/udp",
- "/dev/udp6", NULL };
-#else
-static char *defaultproviders[] = { "/dev/tcp6", "/dev/tcp", NULL };
-#endif
-
-/*
- * Number of elements to add to the poll array on each allocation.
- */
-#define POLL_ARRAY_INC_SIZE 64
-#define NOFILE_INC_SIZE 64
-
-#ifdef __NCALL__
-const char *rdc_devr = "/dev/ncallip";
-#else
-const char *rdc_devr = "/dev/rdc";
-#endif
-
-static int rdc_fdr;
-static int
-
-open_rdc(void)
-{
- int fd = open(rdc_devr, O_RDONLY);
-
- if (fd < 0)
- return (-1);
-
- return (rdc_fdr = fd);
-}
-
-static int
-sndrsys(int type, void *arg)
-{
- int ret = -1;
- if (!rdc_fdr && open_rdc() < 0) { /* open failed */
- syslog(LOG_ERR, "open_rdc() failed: %m\n");
- } else {
- if ((ret = ioctl(rdc_fdr, type, arg)) < 0) {
- syslog(LOG_ERR, "ioctl(rdc_ioctl) failed: %m\n");
- }
- }
- return (ret);
-}
-
-int
-rdc_transport_open(struct netconfig *nconf)
-{
- int fd;
- struct strioctl strioc;
-
- if ((nconf == (struct netconfig *)NULL) ||
- (nconf->nc_device == (char *)NULL)) {
- syslog(LOG_ERR, "No netconfig device");
- return (-1);
- }
-
- /*
- * Open the transport device.
- */
- fd = t_open(nconf->nc_device, O_RDWR, (struct t_info *)NULL);
- if (fd == -1) {
- if (t_errno == TSYSERR && errno == EMFILE &&
- (nofile_increase(0) == 0)) {
- /* Try again with a higher NOFILE limit. */
- fd = t_open(nconf->nc_device, O_RDWR, NULL);
- }
- if (fd == -1) {
- if (t_errno == TSYSERR) {
- syslog(LOG_ERR, "t_open failed: %m");
- } else {
- syslog(LOG_ERR, "t_open failed: %s",
- t_errlist[t_errno]);
- }
- return (-1);
- }
- }
-
- /*
- * Pop timod because the RPC module must be as close as possible
- * to the transport.
- */
- if (ioctl(fd, I_POP, 0) < 0) {
- syslog(LOG_ERR, "I_POP of timod failed: %m");
- if (t_close(fd) == -1) {
- if (t_errno == TSYSERR) {
- syslog(LOG_ERR, "t_close failed on %d: %m", fd);
- } else {
- syslog(LOG_ERR, "t_close failed on %d: %s",
- fd, t_errlist[t_errno]);
- }
- }
- return (-1);
- }
-
- if (nconf->nc_semantics == NC_TPI_CLTS) {
- /*
- * Push rpcmod to filter data traffic to KRPC.
- */
- if (ioctl(fd, I_PUSH, "rpcmod") < 0) {
- syslog(LOG_ERR, "I_PUSH of rpcmod failed: %m");
- (void) t_close(fd);
- return (-1);
- }
- } else {
- if (ioctl(fd, I_PUSH, "rpcmod") < 0) {
- syslog(LOG_ERR, "I_PUSH of CONS rpcmod failed: %m");
- if (t_close(fd) == -1) {
- if (t_errno == TSYSERR) {
- syslog(LOG_ERR,
- "t_close failed on %d: %m", fd);
- } else {
- syslog(LOG_ERR,
- "t_close failed on %d: %s",
- fd, t_errlist[t_errno]);
- }
- }
- return (-1);
- }
-
- strioc.ic_cmd = RPC_SERVER;
- strioc.ic_dp = (char *)0;
- strioc.ic_len = 0;
- strioc.ic_timout = -1;
- /* Tell CONS rpcmod to act like a server stream. */
- if (ioctl(fd, I_STR, &strioc) < 0) {
- syslog(LOG_ERR, "CONS rpcmod set-up ioctl failed: %m");
- if (t_close(fd) == -1) {
- if (t_errno == TSYSERR) {
- syslog(LOG_ERR,
- "t_close failed on %d: %m", fd);
- } else {
- syslog(LOG_ERR,
- "t_close failed on %d: %s",
- fd, t_errlist[t_errno]);
- }
- }
- return (-1);
- }
- }
-
- /*
- * Re-push timod so that we will still be doing TLI
- * operations on the descriptor.
- */
- if (ioctl(fd, I_PUSH, "timod") < 0) {
- syslog(LOG_ERR, "I_PUSH of timod failed: %m");
- if (t_close(fd) == -1) {
- if (t_errno == TSYSERR) {
- syslog(LOG_ERR, "t_close failed on %d: %m", fd);
- } else {
- syslog(LOG_ERR, "t_close failed on %d: %s",
- fd, t_errlist[t_errno]);
- }
- }
- return (-1);
- }
-
- return (fd);
-}
-
-
-void
-rdcd_log_tli_error(char *tli_name, int fd, struct netconfig *nconf)
-{
- int error;
-
- /*
- * Save the error code across syslog(), just in case syslog()
- * gets its own error and, therefore, overwrites errno.
- */
- error = errno;
- if (t_errno == TSYSERR) {
- syslog(LOG_ERR, "%s(file descriptor %d/transport %s) %m",
- tli_name, fd, nconf->nc_proto);
- } else {
- syslog(LOG_ERR,
- "%s(file descriptor %d/transport %s) TLI error %d",
- tli_name, fd, nconf->nc_proto, t_errno);
- }
- errno = error;
-}
-
-/*
- * Called to set up service over a particular transport
- */
-void
-do_one(char *provider, char *proto, struct protob *protobp0,
- int (*svc)(int, struct netbuf, struct netconfig *))
-{
- struct netbuf *retaddr;
- struct netconfig *retnconf;
- struct netbuf addrmask;
- int vers;
- int sock;
-
- if (provider) {
- sock = bind_to_provider(provider, protobp0->serv, &retaddr,
- &retnconf);
- } else {
- (void) syslog(LOG_ERR,
- "Cannot establish %s service over %s: transport setup problem.",
- protobp0->serv, provider ? provider : proto);
- return;
- }
-
- if (sock == -1) {
- if ((Is_ipv6present() &&
- (strcmp(provider, "/dev/tcp6") == 0)) ||
- (!Is_ipv6present() && (strcmp(provider, "/dev/tcp") == 0)))
- (void) syslog(LOG_ERR,
- "Cannot establish %s service over %s: transport "
- "setup problem.",
- protobp0->serv, provider ? provider : proto);
- return;
- }
-
- if (set_addrmask(sock, retnconf, &addrmask) < 0) {
- (void) syslog(LOG_ERR,
- "Cannot set address mask for %s", retnconf->nc_netid);
- return;
- }
-
-
- /*
- * Register all versions of the programs in the protocol block list
- */
- for (vers = protobp0->versmin; vers <= protobp0->versmax; vers++) {
- (void) rpcb_unset(protobp0->program, vers, retnconf);
- (void) rpcb_set(protobp0->program, vers, retnconf, retaddr);
- }
-
- if (retnconf->nc_semantics == NC_TPI_CLTS) {
- /* Don't drop core if supporting module(s) aren't loaded. */
- (void) signal(SIGSYS, SIG_IGN);
-
- /*
- * svc() doesn't block, it returns success or failure.
- */
- if ((*svc)(sock, addrmask, retnconf) < 0) {
- (void) syslog(LOG_ERR, "Cannot establish %s service "
- "over <file desc. %d, protocol %s> : %m. Exiting",
- protobp0->serv, sock, retnconf->nc_proto);
- exit(1);
- }
- }
- /*
- * We successfully set up the server over this transport.
- * Add this descriptor to the one being polled on.
- */
- add_to_poll_list(sock, retnconf);
-}
-
-/*
- * Set up the SNDR/ncall-ip service over all the available transports.
- * Returns -1 for failure, 0 for success.
- */
-int
-do_all(struct protob *protobp,
- int (*svc)(int, struct netbuf, struct netconfig *))
-{
- struct netconfig *nconf;
- NCONF_HANDLE *nc;
-
- if ((nc = setnetconfig()) == (NCONF_HANDLE *)NULL) {
- syslog(LOG_ERR, "setnetconfig failed: %m");
- return (-1);
- }
- while (nconf = getnetconfig(nc)) {
- if ((nconf->nc_flag & NC_VISIBLE) &&
- strcmp(nconf->nc_protofmly, "loopback") != 0 &&
- OK_TPI_TYPE(nconf))
- do_one(nconf->nc_device, nconf->nc_proto, protobp, svc);
- }
- (void) endnetconfig(nc);
- return (0);
-}
-
-/*
- * Read the /etc/default/sndr configuration file to determine if the
- * client has been configured for number of threads, backlog or transport
- * provider.
- */
-
-static void
-read_default(void)
-{
- char *defval, *tmp_str;
- int errno;
- int tmp;
-
- /* Fail silently if error in opening the default rdc config file */
- if ((defopen(RDCADMIN)) == 0) {
- if ((defval = defread("SNDR_THREADS=")) != NULL) {
- errno = 0;
- tmp = strtol(defval, (char **)NULL, 10);
- if (errno == 0) {
- max_conns_allowed = tmp;
- }
- }
- if ((defval = defread("SNDR_LISTEN_BACKLOG=")) != NULL) {
- errno = 0;
- tmp = strtol(defval, (char **)NULL, 10);
- if (errno == 0) {
- listen_backlog = tmp;
- }
- }
- if ((defval = defread("SNDR_TRANSPORT=")) != NULL) {
- errno = 0;
- tmp_str = strdup(defval);
- if (errno == 0) {
- trans_provider = tmp_str;
- }
- }
- /* close defaults file */
- (void) defopen(NULL);
- }
-}
-#ifdef lint
-int
-sndrd_lintmain(int ac, char **av)
-#else
-int
-main(int ac, char **av)
-#endif
-{
- const char *dir = "/";
- int allflag = 0;
- int pid;
- int i, rc;
- struct protob *protobp0, *protobp;
- char **providerp;
- char *required;
-#if !defined(_SunOS_5_6) && !defined(_SunOS_5_7) && !defined(_SunOS_5_8)
- int maxservers;
-#endif
-
- (void) setlocale(LC_ALL, "");
-#ifdef __NCALL__
- (void) textdomain("ncall");
-#else
- (void) textdomain("rdc");
-#endif
-
- progname = basename(av[0]);
-
-#ifdef __NCALL__
- rc = ncall_check_release(&required);
-#else
- rc = rdc_check_release(&required);
-#endif
- if (rc < 0) {
- (void) fprintf(stderr,
- gettext("%s: unable to determine the current "
- "Solaris release: %s\n"), progname, strerror(errno));
- exit(1);
- } else if (rc == FALSE) {
- (void) fprintf(stderr,
- gettext("%s: incorrect Solaris release (requires %s)\n"),
- progname, required);
- exit(1);
- }
-
- openlog(progname, LOG_PID|LOG_CONS, LOG_DAEMON);
- read_default();
-
- /*
- * Usage: <progname> [-c <number of threads>] [-t protocol] \
- * [-d] [-l <listen backlog>]
- */
- while ((i = getopt(ac, av, "ac:t:dl:")) != EOF) {
- switch (i) {
- case 'a':
- allflag = 1;
- break;
- case 'c':
- max_conns_allowed = atoi(optarg);
- if (max_conns_allowed <= 0)
- max_conns_allowed = 16;
- break;
-
- case 'd':
- debugflg++;
- break;
-
- case 't':
- trans_provider = optarg;
- break;
-
- case 'l':
- listen_backlog = atoi(optarg);
- if (listen_backlog < 0)
- listen_backlog = 32;
- break;
-
- default:
- syslog(LOG_ERR,
- "Usage: %s [-c <number of threads>] "
- "[-d] [-t protocol] "
- "[-l <listen backlog>]\n", progname);
- exit(1);
- break;
- }
- }
-
- if (chroot(dir) < 0) {
- syslog(LOG_ERR, "chroot failed: %m");
- exit(1);
- }
-
- if (chdir(dir) < 0) {
- syslog(LOG_ERR, "chdir failed: %m");
- exit(1);
- }
-
- if (!debugflg) {
- pid = fork();
- if (pid < 0) {
- syslog(LOG_ERR, "Fork failed\n");
- exit(1);
- }
- if (pid != 0)
- exit(0);
-
- /*
- * Close existing file descriptors, open "/dev/null" as
- * standard input, output, and error, and detach from
- * controlling terminal.
- */
-#if !defined(_SunOS_5_6) && !defined(_SunOS_5_7) && !defined(_SunOS_5_8)
- /* use closefrom(3C) from PSARC/2000/193 when possible */
- closefrom(0);
-#else
- for (i = 0; i < _NFILE; i++)
- (void) close(i);
-#endif
- (void) open("/dev/null", O_RDONLY);
- (void) open("/dev/null", O_WRONLY);
- (void) dup(1);
- (void) setsid();
-
- /*
- * ignore all signals apart from SIGTERM.
- */
- for (i = 1; i < _sys_nsig; i++)
- (void) sigset(i, SIG_IGN);
-
- (void) sigset(SIGTERM, SIG_DFL);
- }
-
-#if !defined(_SunOS_5_6) && !defined(_SunOS_5_7) && !defined(_SunOS_5_8)
- /*
- * Set up kernel RPC thread pool for the SNDR/ncall-ip server.
- */
- maxservers = (max_conns_allowed < 0 ? 16 : max_conns_allowed);
- if (sndrsvcpool(maxservers)) {
- (void) syslog(LOG_ERR,
- "Can't set up kernel %s service: %m. Exiting", progname);
- exit(1);
- }
-
- /*
- * Set up blocked thread to do LWP creation on behalf of the kernel.
- */
- if (svcwait(RDC_SVCPOOL_ID)) {
- (void) syslog(LOG_ERR,
- "Can't set up %s pool creator: %m, Exiting", progname);
- exit(1);
- }
-#endif
-
- /*
- * Build a protocol block list for registration.
- */
- protobp0 = protobp = (struct protob *)malloc(sizeof (struct protob));
- protobp->serv = RDC_SVC_NAME;
- protobp->versmin = RDC_VERS_MIN;
- protobp->versmax = RDC_VERS_MAX;
- protobp->program = RDC_PROGRAM;
- protobp->next = (struct protob *)NULL;
-
- if (allflag) {
- if (do_all(protobp0, rdcsvc) == -1)
- exit(1);
- } else if (trans_provider)
- do_one(trans_provider, NULL, protobp0, rdcsvc);
- else {
- for (providerp = defaultproviders;
- *providerp != NULL; providerp++) {
- trans_provider = *providerp;
- do_one(trans_provider, NULL, protobp0, rdcsvc);
- }
- }
-
-done:
- free(protobp);
-
- end_listen_fds = num_fds;
- /*
- * Poll for non-data control events on the transport descriptors.
- */
- poll_for_action();
-
- syslog(LOG_ERR, "%s fatal server error\n", progname);
-
- return (-1);
-}
-
-static int
-reuseaddr(int fd)
-{
- struct t_optmgmt req, resp;
- struct opthdr *opt;
- char reqbuf[128];
- int *ip;
-
- /* LINTED pointer alignment */
- opt = (struct opthdr *)reqbuf;
- opt->level = SOL_SOCKET;
- opt->name = SO_REUSEADDR;
- opt->len = sizeof (int);
-
- /* LINTED pointer alignment */
- ip = (int *)&reqbuf[sizeof (struct opthdr)];
- *ip = 1;
-
- req.flags = T_NEGOTIATE;
- req.opt.len = sizeof (struct opthdr) + opt->len;
- req.opt.buf = (char *)opt;
-
- resp.flags = 0;
- resp.opt.buf = reqbuf;
- resp.opt.maxlen = sizeof (reqbuf);
-
- if (t_optmgmt(fd, &req, &resp) < 0 || resp.flags != T_SUCCESS) {
- if (t_errno == TSYSERR) {
- syslog(LOG_ERR, "reuseaddr() t_optmgmt failed: %m\n");
- } else {
- syslog(LOG_ERR, "reuseaddr() t_optmgmt failed: %s\n",
- t_errlist[t_errno]);
- }
- return (-1);
- }
- return (0);
-}
-
-/*
- * poll on the open transport descriptors for events and errors.
- */
-void
-poll_for_action(void)
-{
- int nfds;
- int i;
-
- /*
- * Keep polling until all transports have been closed. When this
- * happens, we return.
- */
- while ((int)num_fds > 0) {
- nfds = poll(poll_array, num_fds, INFTIM);
- switch (nfds) {
- case 0:
- continue;
-
- case -1:
- /*
- * Some errors from poll could be
- * due to temporary conditions, and we try to
- * be robust in the face of them. Other
- * errors (should never happen in theory)
- * are fatal (eg. EINVAL, EFAULT).
- */
- switch (errno) {
- case EINTR:
- continue;
-
- case EAGAIN:
- case ENOMEM:
- (void) sleep(10);
- continue;
-
- default:
- (void) syslog(LOG_ERR,
- "poll failed: %m. Exiting");
- exit(1);
- }
- default:
- break;
- }
-
- /*
- * Go through the poll list looking for events.
- */
- for (i = 0; i < num_fds && nfds > 0; i++) {
- if (poll_array[i].revents) {
- nfds--;
- /*
- * We have a message, so try to read it.
- * Record the error return in errno,
- * so that syslog(LOG_ERR, "...%m")
- * dumps the corresponding error string.
- */
- if (conn_polled[i].nc.nc_semantics ==
- NC_TPI_CLTS) {
- errno = do_poll_clts_action(
- poll_array[i].fd, i);
- } else {
- errno = do_poll_cots_action(
- poll_array[i].fd, i);
- }
-
- if (errno == 0)
- continue;
- /*
- * Most returned error codes mean that there is
- * fatal condition which we can only deal with
- * by closing the transport.
- */
- if (errno != EAGAIN && errno != ENOMEM) {
- (void) syslog(LOG_ERR,
- "Error (%m) reading descriptor %d"
- "/transport %s. Closing it.",
- poll_array[i].fd,
- conn_polled[i].nc.nc_proto);
- (void) t_close(poll_array[i].fd);
- remove_from_poll_list(poll_array[i].fd);
- } else if (errno == ENOMEM)
- (void) sleep(5);
- }
- }
- }
-
- (void) syslog(LOG_ERR,
- "All transports have been closed with errors. Exiting.");
-}
-
-/*
- * Allocate poll/transport array entries for this descriptor.
- */
-static void
-add_to_poll_list(int fd, struct netconfig *nconf)
-{
- static int poll_array_size = 0;
-
- /*
- * If the arrays are full, allocate new ones.
- */
- if (num_fds == poll_array_size) {
- struct pollfd *tpa;
- struct conn_entry *tnp;
-
- if (poll_array_size != 0) {
- tpa = poll_array;
- tnp = conn_polled;
- } else
- tpa = (struct pollfd *)0;
-
- poll_array_size += POLL_ARRAY_INC_SIZE;
-
- /*
- * Allocate new arrays.
- */
- poll_array = (struct pollfd *)
- malloc(poll_array_size * sizeof (struct pollfd) + 256);
- conn_polled = (struct conn_entry *)
- malloc(poll_array_size * sizeof (struct conn_entry) + 256);
- if (poll_array == (struct pollfd *)NULL ||
- conn_polled == (struct conn_entry *)NULL) {
- syslog(LOG_ERR, "malloc failed for poll array");
- exit(1);
- }
-
- /*
- * Copy the data of the old ones into new arrays, and
- * free the old ones.
- * num_fds is guaranteed to be less than
- * poll_array_size, so this memcpy is safe.
- */
- if (tpa) {
- (void) memcpy((void *)poll_array, (void *)tpa,
- num_fds * sizeof (struct pollfd));
- (void) memcpy((void *)conn_polled, (void *)tnp,
- num_fds * sizeof (struct conn_entry));
- free((void *)tpa);
- free((void *)tnp);
- }
- }
-
- /*
- * Set the descriptor and event list. All possible events are
- * polled for.
- */
- poll_array[num_fds].fd = fd;
- poll_array[num_fds].events = POLLIN|POLLRDNORM|POLLRDBAND|POLLPRI;
-
- /*
- * Copy the transport data over too.
- */
- conn_polled[num_fds].nc = *nconf; /* structure copy */
- conn_polled[num_fds].closing = 0;
-
- /*
- * Set the descriptor to non-blocking. Avoids a race
- * between data arriving on the stream and then having it
- * flushed before we can read it.
- */
- if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
- (void) syslog(LOG_ERR,
- "fcntl(file desc. %d/transport %s, F_SETFL, "
- "O_NONBLOCK): %m. Exiting",
- num_fds, nconf->nc_proto);
- exit(1);
- }
-
- /*
- * Count this descriptor.
- */
- ++num_fds;
-}
-
-static void
-remove_from_poll_list(int fd)
-{
- int i;
- int num_to_copy;
-
- for (i = 0; i < num_fds; i++) {
- if (poll_array[i].fd == fd) {
- --num_fds;
- num_to_copy = num_fds - i;
- (void) memcpy((void *)&poll_array[i],
- (void *)&poll_array[i+1],
- num_to_copy * sizeof (struct pollfd));
- (void) memset((void *)&poll_array[num_fds], 0,
- sizeof (struct pollfd));
- (void) memcpy((void *)&conn_polled[i],
- (void *)&conn_polled[i+1],
- num_to_copy * sizeof (struct conn_entry));
- (void) memset((void *)&conn_polled[num_fds], 0,
- sizeof (struct conn_entry));
- return;
- }
- }
- syslog(LOG_ERR, "attempt to remove nonexistent fd from poll list");
-
-}
-
-static void
-conn_close_oldest(void)
-{
- int fd;
- int i1;
-
- /*
- * Find the oldest connection that is not already in the
- * process of shutting down.
- */
- for (i1 = end_listen_fds; /* no conditional expression */; i1++) {
- if (i1 >= num_fds)
- return;
- if (conn_polled[i1].closing == 0)
- break;
- }
-#ifdef DEBUG
- (void) printf("too many connections (%d), releasing oldest (%d)\n",
- num_conns, poll_array[i1].fd);
-#else
- syslog(LOG_WARNING, "too many connections (%d), releasing oldest (%d)",
- num_conns, poll_array[i1].fd);
-#endif
- fd = poll_array[i1].fd;
- if (conn_polled[i1].nc.nc_semantics == NC_TPI_COTS) {
- /*
- * For politeness, send a T_DISCON_REQ to the transport
- * provider. We close the stream anyway.
- */
- (void) t_snddis(fd, (struct t_call *)0);
- num_conns--;
- remove_from_poll_list(fd);
- (void) t_close(fd);
- } else {
- /*
- * For orderly release, we do not close the stream
- * until the T_ORDREL_IND arrives to complete
- * the handshake.
- */
- if (t_sndrel(fd) == 0)
- conn_polled[i1].closing = 1;
- }
-}
-
-static boolean_t
-conn_get(int fd, struct netconfig *nconf, struct conn_ind **connp)
-{
- struct conn_ind *conn;
- struct conn_ind *next_conn;
-
- conn = (struct conn_ind *)malloc(sizeof (*conn));
- if (conn == NULL) {
- syslog(LOG_ERR, "malloc for listen indication failed");
- return (FALSE);
- }
-
- /* LINTED pointer alignment */
- conn->conn_call = (struct t_call *)t_alloc(fd, T_CALL, T_ALL);
- if (conn->conn_call == NULL) {
- free((char *)conn);
- rdcd_log_tli_error("t_alloc", fd, nconf);
- return (FALSE);
- }
-
- if (t_listen(fd, conn->conn_call) == -1) {
- rdcd_log_tli_error("t_listen", fd, nconf);
- (void) t_free((char *)conn->conn_call, T_CALL);
- free((char *)conn);
- return (FALSE);
- }
-
- if (conn->conn_call->udata.len > 0) {
- syslog(LOG_WARNING,
- "rejecting inbound connection(%s) with %d bytes "
- "of connect data",
- nconf->nc_proto, conn->conn_call->udata.len);
-
- conn->conn_call->udata.len = 0;
- (void) t_snddis(fd, conn->conn_call);
- (void) t_free((char *)conn->conn_call, T_CALL);
- free((char *)conn);
- return (FALSE);
- }
-
- if ((next_conn = *connp) != NULL) {
- next_conn->conn_prev->conn_next = conn;
- conn->conn_next = next_conn;
- conn->conn_prev = next_conn->conn_prev;
- next_conn->conn_prev = conn;
- } else {
- conn->conn_next = conn;
- conn->conn_prev = conn;
- *connp = conn;
- }
- return (TRUE);
-}
-
-static int
-discon_get(int fd, struct netconfig *nconf, struct conn_ind **connp)
-{
- struct conn_ind *conn;
- struct t_discon discon;
-
- discon.udata.buf = (char *)0;
- discon.udata.maxlen = 0;
- if (t_rcvdis(fd, &discon) == -1) {
- rdcd_log_tli_error("t_rcvdis", fd, nconf);
- return (-1);
- }
-
- conn = *connp;
- if (conn == NULL)
- return (0);
-
- do {
- if (conn->conn_call->sequence == discon.sequence) {
- if (conn->conn_next == conn)
- *connp = (struct conn_ind *)0;
- else {
- if (conn == *connp) {
- *connp = conn->conn_next;
- }
- conn->conn_next->conn_prev = conn->conn_prev;
- conn->conn_prev->conn_next = conn->conn_next;
- }
- free((char *)conn);
- break;
- }
- conn = conn->conn_next;
- } while (conn != *connp);
-
- return (0);
-}
-
-static void
-cots_listen_event(int fd, int conn_index)
-{
- struct t_call *call;
- struct conn_ind *conn;
- struct conn_ind *conn_head;
- int event;
- struct netconfig *nconf = &conn_polled[conn_index].nc;
- int new_fd;
- struct netbuf addrmask;
- int ret = 0;
-
- conn_head = NULL;
- (void) conn_get(fd, nconf, &conn_head);
-
- while ((conn = conn_head) != NULL) {
- conn_head = conn->conn_next;
- if (conn_head == conn)
- conn_head = NULL;
- else {
- conn_head->conn_prev = conn->conn_prev;
- conn->conn_prev->conn_next = conn_head;
- }
- call = conn->conn_call;
- free(conn);
-
- /*
- * If we have already accepted the maximum number of
- * connections allowed on the command line, then drop
- * the oldest connection (for any protocol) before
- * accepting the new connection. Unless explicitly
- * set on the command line, max_conns_allowed is -1.
- */
- if (max_conns_allowed != -1 && num_conns >= max_conns_allowed)
- conn_close_oldest();
-
- /*
- * Create a new transport endpoint for the same proto as
- * the listener.
- */
- new_fd = rdc_transport_open(nconf);
- if (new_fd == -1) {
- call->udata.len = 0;
- (void) t_snddis(fd, call);
- (void) t_free((char *)call, T_CALL);
- syslog(LOG_ERR, "Cannot establish transport over %s",
- nconf->nc_device);
- continue;
- }
-
- /* Bind to a generic address/port for the accepting stream. */
- if (t_bind(new_fd, NULL, NULL) == -1) {
- rdcd_log_tli_error("t_bind", new_fd, nconf);
- call->udata.len = 0;
- (void) t_snddis(fd, call);
- (void) t_free((char *)call, T_CALL);
- (void) t_close(new_fd);
- continue;
- }
-
- while (t_accept(fd, new_fd, call) == -1) {
- if (t_errno != TLOOK) {
- rdcd_log_tli_error("t_accept", fd, nconf);
- call->udata.len = 0;
- (void) t_snddis(fd, call);
- (void) t_free((char *)call, T_CALL);
- (void) t_close(new_fd);
- goto do_next_conn;
- }
- while (event = t_look(fd)) {
- switch (event) {
- case T_LISTEN:
- (void) conn_get(fd, nconf, &conn_head);
- continue;
-
- case T_DISCONNECT:
- (void) discon_get(fd, nconf,
- &conn_head);
- continue;
-
- default:
- syslog(LOG_ERR,
- "unexpected event 0x%x during "
- "accept processing (%s)",
- event, nconf->nc_proto);
- call->udata.len = 0;
- (void) t_snddis(fd, call);
- (void) t_free((char *)call, T_CALL);
- (void) t_close(new_fd);
- goto do_next_conn;
- }
- }
- }
-
- if (set_addrmask(new_fd, nconf, &addrmask) < 0) {
- (void) syslog(LOG_ERR, "Cannot set address mask for %s",
- nconf->nc_netid);
- (void) t_snddis(new_fd, NULL);
- (void) t_free((char *)call, T_CALL);
- (void) t_close(new_fd);
- continue;
- }
-
- /* Tell kRPC about the new stream. */
- ret = (*Mysvc)(new_fd, addrmask, nconf);
- if (ret < 0) {
- syslog(LOG_ERR,
- "unable to register with kernel rpc: %m");
- free(addrmask.buf);
- (void) t_snddis(new_fd, NULL);
- (void) t_free((char *)call, T_CALL);
- (void) t_close(new_fd);
- goto do_next_conn;
- }
-
- free(addrmask.buf);
- (void) t_free((char *)call, T_CALL);
-
- /*
- * Poll on the new descriptor so that we get disconnect
- * and orderly release indications.
- */
- num_conns++;
- add_to_poll_list(new_fd, nconf);
-
- /* Reset nconf in case it has been moved. */
- nconf = &conn_polled[conn_index].nc;
-do_next_conn:;
- }
-}
-
-static int
-do_poll_cots_action(int fd, int conn_index)
-{
- char buf[256];
- int event;
- int i1;
- int flags;
- struct conn_entry *connent = &conn_polled[conn_index];
- struct netconfig *nconf = &(connent->nc);
- const char *errorstr;
-
- while (event = t_look(fd)) {
- switch (event) {
- case T_LISTEN:
- cots_listen_event(fd, conn_index);
- break;
-
- case T_DATA:
- /*
- * Receive a private notification from CONS rpcmod.
- */
- i1 = t_rcv(fd, buf, sizeof (buf), &flags);
- if (i1 == -1) {
- syslog(LOG_ERR, "t_rcv failed");
- break;
- }
- if (i1 < sizeof (int))
- break;
- i1 = BE32_TO_U32(buf);
- if (i1 == 1 || i1 == 2) {
- /*
- * This connection has been idle for too long,
- * so release it as politely as we can. If we
- * have already initiated an orderly release
- * and we get notified that the stream is
- * still idle, pull the plug. This prevents
- * hung connections from continuing to consume
- * resources.
- */
- if (nconf->nc_semantics == NC_TPI_COTS ||
- connent->closing != 0) {
- (void) t_snddis(fd, (struct t_call *)0);
- goto fdclose;
- }
- /*
- * For NC_TPI_COTS_ORD, the stream is closed
- * and removed from the poll list when the
- * T_ORDREL is received from the provider. We
- * don't wait for it here because it may take
- * a while for the transport to shut down.
- */
- if (t_sndrel(fd) == -1) {
- syslog(LOG_ERR,
- "unable to send orderly release %m");
- }
- connent->closing = 1;
- } else
- syslog(LOG_ERR,
- "unexpected event from CONS rpcmod %d", i1);
- break;
-
- case T_ORDREL:
- /* Perform an orderly release. */
- if (t_rcvrel(fd) == 0) {
- /* T_ORDREL on listen fd's should be ignored */
- if (!is_listen_fd_index(fd)) {
- (void) t_sndrel(fd);
- goto fdclose;
- }
- break;
-
- } else if (t_errno == TLOOK) {
- break;
- } else {
- rdcd_log_tli_error("t_rcvrel", fd, nconf);
- /*
- * check to make sure we do not close
- * listen fd
- */
- if (!is_listen_fd_index(fd))
- break;
- else
- goto fdclose;
- }
-
- case T_DISCONNECT:
- if (t_rcvdis(fd, (struct t_discon *)NULL) == -1)
- rdcd_log_tli_error("t_rcvdis", fd, nconf);
-
- /*
- * T_DISCONNECT on listen fd's should be ignored.
- */
- if (!is_listen_fd_index(fd))
- break;
- else
- goto fdclose;
-
- default:
- if (t_errno == TSYSERR) {
- if ((errorstr = strerror(errno)) == NULL) {
- (void) snprintf(buf, sizeof (buf),
- "Unknown error num %d", errno);
- errorstr = (const char *)buf;
- }
- } else if (event == -1)
- errorstr = t_strerror(t_errno);
- else
- errorstr = "";
-#ifdef DEBUG
- syslog(LOG_ERR,
- "unexpected TLI event (0x%x) on "
- "connection-oriented transport(%s, %d):%s",
- event, nconf->nc_proto, fd, errorstr);
-#endif
-
-fdclose:
- num_conns--;
- remove_from_poll_list(fd);
- (void) t_close(fd);
- return (0);
- }
- }
-
- return (0);
-}
-
-
-/*
- * Called to read and interpret the event on a connectionless descriptor.
- * Returns 0 if successful, or a UNIX error code if failure.
- */
-static int
-do_poll_clts_action(int fd, int conn_index)
-{
- int error;
- int ret;
- int flags;
- struct netconfig *nconf = &conn_polled[conn_index].nc;
- static struct t_unitdata *unitdata = NULL;
- static struct t_uderr *uderr = NULL;
- static int oldfd = -1;
- struct nd_hostservlist *host = NULL;
- struct strbuf ctl[1], data[1];
- /*
- * We just need to have some space to consume the
- * message in the event we can't use the TLI interface to do the
- * job.
- *
- * We flush the message using getmsg(). For the control part
- * we allocate enough for any TPI header plus 32 bytes for address
- * and options. For the data part, there is nothing magic about
- * the size of the array, but 256 bytes is probably better than
- * 1 byte, and we don't expect any data portion anyway.
- *
- * If the array sizes are too small, we handle this because getmsg()
- * (called to consume the message) will return MOREDATA|MORECTL.
- * Thus we just call getmsg() until it's read the message.
- */
- char ctlbuf[sizeof (union T_primitives) + 32];
- char databuf[256];
-
- /*
- * If this is the same descriptor as the last time
- * do_poll_clts_action was called, we can save some
- * de-allocation and allocation.
- */
- if (oldfd != fd) {
- oldfd = fd;
-
- if (unitdata) {
- (void) t_free((char *)unitdata, T_UNITDATA);
- unitdata = NULL;
- }
- if (uderr) {
- (void) t_free((char *)uderr, T_UDERROR);
- uderr = NULL;
- }
- }
-
- /*
- * Allocate a unitdata structure for receiving the event.
- */
- if (unitdata == NULL) {
- /* LINTED pointer alignment */
- unitdata = (struct t_unitdata *)t_alloc(fd, T_UNITDATA, T_ALL);
- if (unitdata == NULL) {
- if (t_errno == TSYSERR) {
- /*
- * Save the error code across
- * syslog(), just in case
- * syslog() gets its own error
- * and therefore overwrites errno.
- */
- error = errno;
- (void) syslog(LOG_ERR,
- "t_alloc(file descriptor %d/transport %s, "
- "T_UNITDATA) failed: %m",
- fd, nconf->nc_proto);
- return (error);
- }
- (void) syslog(LOG_ERR, "t_alloc(file descriptor %d/"
- "transport %s, T_UNITDATA) failed TLI error %d",
- fd, nconf->nc_proto, t_errno);
- goto flush_it;
- }
- }
-
-try_again:
- flags = 0;
-
- /*
- * The idea is we wait for T_UNITDATA_IND's. Of course,
- * we don't get any, because rpcmod filters them out.
- * However, we need to call t_rcvudata() to let TLI
- * tell us we have a T_UDERROR_IND.
- *
- * algorithm is:
- * t_rcvudata(), expecting TLOOK.
- * t_look(), expecting T_UDERR.
- * t_rcvuderr(), expecting success (0).
- * expand destination address into ASCII,
- * and dump it.
- */
-
- ret = t_rcvudata(fd, unitdata, &flags);
- if (ret == 0 || t_errno == TBUFOVFLW) {
- (void) syslog(LOG_WARNING, "t_rcvudata(file descriptor %d/"
- "transport %s) got unexpected data, %d bytes",
- fd, nconf->nc_proto, unitdata->udata.len);
-
- /*
- * Even though we don't expect any data, in case we do,
- * keep reading until there is no more.
- */
- if (flags & T_MORE)
- goto try_again;
-
- return (0);
- }
-
- switch (t_errno) {
- case TNODATA:
- return (0);
- case TSYSERR:
- /*
- * System errors are returned to caller.
- * Save the error code across
- * syslog(), just in case
- * syslog() gets its own error
- * and therefore overwrites errno.
- */
- error = errno;
- (void) syslog(LOG_ERR,
- "t_rcvudata(file descriptor %d/transport %s) %m",
- fd, nconf->nc_proto);
- return (error);
- case TLOOK:
- break;
- default:
- (void) syslog(LOG_ERR,
- "t_rcvudata(file descriptor %d/transport %s) TLI error %d",
- fd, nconf->nc_proto, t_errno);
- goto flush_it;
- }
-
- ret = t_look(fd);
- switch (ret) {
- case 0:
- return (0);
- case -1:
- /*
- * System errors are returned to caller.
- */
- if (t_errno == TSYSERR) {
- /*
- * Save the error code across
- * syslog(), just in case
- * syslog() gets its own error
- * and therefore overwrites errno.
- */
- error = errno;
- (void) syslog(LOG_ERR,
- "t_look(file descriptor %d/transport %s) %m",
- fd, nconf->nc_proto);
- return (error);
- }
- (void) syslog(LOG_ERR,
- "t_look(file descriptor %d/transport %s) TLI error %d",
- fd, nconf->nc_proto, t_errno);
- goto flush_it;
- case T_UDERR:
- break;
- default:
- (void) syslog(LOG_WARNING, "t_look(file descriptor %d/"
- "transport %s) returned %d not T_UDERR (%d)",
- fd, nconf->nc_proto, ret, T_UDERR);
- }
-
- if (uderr == NULL) {
- /* LINTED pointer alignment */
- uderr = (struct t_uderr *)t_alloc(fd, T_UDERROR, T_ALL);
- if (uderr == NULL) {
- if (t_errno == TSYSERR) {
- /*
- * Save the error code across
- * syslog(), just in case
- * syslog() gets its own error
- * and therefore overwrites errno.
- */
- error = errno;
- (void) syslog(LOG_ERR,
- "t_alloc(file descriptor %d/transport %s, "
- "T_UDERROR) failed: %m",
- fd, nconf->nc_proto);
- return (error);
- }
- (void) syslog(LOG_ERR, "t_alloc(file descriptor %d/"
- "transport %s, T_UDERROR) failed TLI error: %d",
- fd, nconf->nc_proto, t_errno);
- goto flush_it;
- }
- }
-
- ret = t_rcvuderr(fd, uderr);
- if (ret == 0) {
-
- /*
- * Save the datagram error in errno, so that the
- * %m argument to syslog picks up the error string.
- */
- errno = uderr->error;
-
- /*
- * Log the datagram error, then log the host that
- * probably triggerred. Cannot log both in the
- * same transaction because of packet size limitations
- * in /dev/log.
- */
- (void) syslog((errno == ECONNREFUSED) ? LOG_DEBUG : LOG_WARNING,
- "%s response over <file descriptor %d/transport %s> "
- "generated error: %m",
- progname, fd, nconf->nc_proto);
-
- /*
- * Try to map the client's address back to a
- * name.
- */
- ret = netdir_getbyaddr(nconf, &host, &uderr->addr);
- if (ret != -1 && host && host->h_cnt > 0 &&
- host->h_hostservs) {
- (void) syslog((errno == ECONNREFUSED) ? LOG_DEBUG : LOG_WARNING,
- "Bad %s response was sent to client with "
- "host name: %s; service port: %s",
- progname, host->h_hostservs->h_host,
- host->h_hostservs->h_serv);
- } else {
- int i, j;
- char *buf;
- char *hex = "0123456789abcdef";
-
- /*
- * Mapping failed, print the whole thing
- * in ASCII hex.
- */
- buf = (char *)malloc(uderr->addr.len * 2 + 1);
- for (i = 0, j = 0; i < uderr->addr.len; i++, j += 2) {
- buf[j] = hex[((uderr->addr.buf[i]) >> 4) & 0xf];
- buf[j+1] = hex[uderr->addr.buf[i] & 0xf];
- }
- buf[j] = '\0';
- (void) syslog((errno == ECONNREFUSED) ?
- LOG_DEBUG : LOG_WARNING,
- "Bad %s response was sent to client with "
- "transport address: 0x%s",
- progname, buf);
- free((void *)buf);
- }
-
- if (ret == 0 && host != NULL)
- netdir_free((void *)host, ND_HOSTSERVLIST);
- return (0);
- }
-
- switch (t_errno) {
- case TNOUDERR:
- goto flush_it;
- case TSYSERR:
- /*
- * System errors are returned to caller.
- * Save the error code across
- * syslog(), just in case
- * syslog() gets its own error
- * and therefore overwrites errno.
- */
- error = errno;
- (void) syslog(LOG_ERR,
- "t_rcvuderr(file descriptor %d/transport %s) %m",
- fd, nconf->nc_proto);
- return (error);
- default:
- (void) syslog(LOG_ERR,
- "t_rcvuderr(file descriptor %d/transport %s) TLI error %d",
- fd, nconf->nc_proto, t_errno);
- goto flush_it;
- }
-
-flush_it:
- /*
- * If we get here, then we could not cope with whatever message
- * we attempted to read, so flush it. If we did read a message,
- * and one isn't present, that is all right, because fd is in
- * nonblocking mode.
- */
- (void) syslog(LOG_ERR,
- "Flushing one input message from <file descriptor %d/transport %s>",
- fd, nconf->nc_proto);
-
- /*
- * Read and discard the message. Do this this until there is
- * no more control/data in the message or until we get an error.
- */
- do {
- ctl->maxlen = sizeof (ctlbuf);
- ctl->buf = ctlbuf;
- data->maxlen = sizeof (databuf);
- data->buf = databuf;
- flags = 0;
- ret = getmsg(fd, ctl, data, &flags);
- if (ret == -1)
- return (errno);
- } while (ret != 0);
-
- return (0);
-}
-
-/*
- * Establish service thread.
- */
-static int
-rdcsvc(int fd, struct netbuf addrmask, struct netconfig *nconf)
-{
-#ifdef __NCALL__
- struct ncall_svc_args nsa;
-#else /* !__NCALL__ */
- struct rdc_svc_args nsa;
- _rdc_ioctl_t rdc_args = { 0, };
-#endif /* __NCALL__ */
-
- nsa.fd = fd;
- nsa.nthr = (max_conns_allowed < 0 ? 16 : max_conns_allowed);
- (void) strncpy(nsa.netid, nconf->nc_netid, sizeof (nsa.netid));
- nsa.addrmask.len = addrmask.len;
- nsa.addrmask.maxlen = addrmask.maxlen;
- nsa.addrmask.buf = addrmask.buf;
-
-#ifdef __NCALL__
- return (sndrsys(NC_IOC_SERVER, &nsa));
-#else /* !__NCALL__ */
- rdc_args.arg0 = (long)&nsa;
- return (sndrsys(RDC_ENABLE_SVR, &rdc_args));
-#endif /* __NCALL__ */
-}
-
-
-
-static int
-nofile_increase(int limit)
-{
- struct rlimit rl;
-
- if (getrlimit(RLIMIT_NOFILE, &rl) == -1) {
- syslog(LOG_ERR,
- "nofile_increase() getrlimit of NOFILE failed: %m");
- return (-1);
- }
-
- if (limit > 0)
- rl.rlim_cur = limit;
- else
- rl.rlim_cur += NOFILE_INC_SIZE;
-
- if (rl.rlim_cur > rl.rlim_max && rl.rlim_max != RLIM_INFINITY)
- rl.rlim_max = rl.rlim_cur;
-
- if (setrlimit(RLIMIT_NOFILE, &rl) == -1) {
- syslog(LOG_ERR,
- "nofile_increase() setrlimit of NOFILE to %d failed: %m",
- rl.rlim_cur);
- return (-1);
- }
-
- return (0);
-}
-
-int
-rdcd_bindit(struct netconfig *nconf, struct netbuf **addr,
- struct nd_hostserv *hs, int backlog)
-{
- int fd;
- struct t_bind *ntb;
- struct t_bind tb;
- struct nd_addrlist *addrlist;
- struct t_optmgmt req, resp;
- struct opthdr *opt;
- char reqbuf[128];
-
- if ((fd = rdc_transport_open(nconf)) == -1) {
- syslog(LOG_ERR, "cannot establish transport service over %s",
- nconf->nc_device);
- return (-1);
- }
-
- addrlist = (struct nd_addrlist *)NULL;
- if (netdir_getbyname(nconf, hs, &addrlist) != 0) {
- if (strncmp(nconf->nc_netid, "udp", 3) != 0) {
- syslog(LOG_ERR, "Cannot get address for transport "
- "%s host %s service %s",
- nconf->nc_netid, hs->h_host, hs->h_serv);
- }
- (void) t_close(fd);
- return (-1);
- }
-
- if (strcmp(nconf->nc_proto, "tcp") == 0) {
- /*
- * If we're running over TCP, then set the
- * SO_REUSEADDR option so that we can bind
- * to our preferred address even if previously
- * left connections exist in FIN_WAIT states.
- * This is somewhat bogus, but otherwise you have
- * to wait 2 minutes to restart after killing it.
- */
- if (reuseaddr(fd) == -1) {
- syslog(LOG_WARNING,
- "couldn't set SO_REUSEADDR option on transport");
- }
- }
-
- if (nconf->nc_semantics == NC_TPI_CLTS)
- tb.qlen = 0;
- else
- tb.qlen = backlog;
-
- /* LINTED pointer alignment */
- ntb = (struct t_bind *)t_alloc(fd, T_BIND, T_ALL);
- if (ntb == (struct t_bind *)NULL) {
- syslog(LOG_ERR, "t_alloc failed: t_errno %d, %m", t_errno);
- (void) t_close(fd);
- netdir_free((void *)addrlist, ND_ADDRLIST);
- return (-1);
- }
-
- tb.addr = *(addrlist->n_addrs); /* structure copy */
-
- if (t_bind(fd, &tb, ntb) == -1) {
- syslog(LOG_ERR, "t_bind failed: t_errno %d, %m", t_errno);
- (void) t_free((char *)ntb, T_BIND);
- netdir_free((void *)addrlist, ND_ADDRLIST);
- (void) t_close(fd);
- return (-1);
- }
-
- /* make sure we bound to the right address */
- if (tb.addr.len != ntb->addr.len ||
- memcmp(tb.addr.buf, ntb->addr.buf, tb.addr.len) != 0) {
- syslog(LOG_ERR, "t_bind to wrong address");
- (void) t_free((char *)ntb, T_BIND);
- netdir_free((void *)addrlist, ND_ADDRLIST);
- (void) t_close(fd);
- return (-1);
- }
-
- *addr = &ntb->addr;
- netdir_free((void *)addrlist, ND_ADDRLIST);
-
- if (strcmp(nconf->nc_proto, "tcp") == 0 ||
- strcmp(nconf->nc_proto, "tcp6") == 0) {
- /*
- * Disable the Nagle algorithm on TCP connections.
- * Connections accepted from this listener will
- * inherit the listener options.
- */
-
- /* LINTED pointer alignment */
- opt = (struct opthdr *)reqbuf;
- opt->level = IPPROTO_TCP;
- opt->name = TCP_NODELAY;
- opt->len = sizeof (int);
-
- /* LINTED pointer alignment */
- *(int *)((char *)opt + sizeof (*opt)) = 1;
-
- req.flags = T_NEGOTIATE;
- req.opt.len = sizeof (*opt) + opt->len;
- req.opt.buf = (char *)opt;
- resp.flags = 0;
- resp.opt.buf = reqbuf;
- resp.opt.maxlen = sizeof (reqbuf);
-
- if (t_optmgmt(fd, &req, &resp) < 0 ||
- resp.flags != T_SUCCESS) {
- syslog(LOG_ERR, "couldn't set NODELAY option for "
- "proto %s: t_errno = %d, %m", nconf->nc_proto,
- t_errno);
- }
- }
-
- return (fd);
-}
-
-
-/* ARGSUSED */
-static int
-bind_to_provider(char *provider, char *serv, struct netbuf **addr,
- struct netconfig **retnconf)
-{
- struct netconfig *nconf;
- NCONF_HANDLE *nc;
- struct nd_hostserv hs;
-
- hs.h_host = HOST_SELF;
- hs.h_serv = RDC_SERVICE; /* serv_name_to_port_name(serv); */
-
- if ((nc = setnetconfig()) == (NCONF_HANDLE *)NULL) {
- syslog(LOG_ERR, "setnetconfig failed: %m");
- return (-1);
- }
- while (nconf = getnetconfig(nc)) {
- if (OK_TPI_TYPE(nconf) &&
- strcmp(nconf->nc_device, provider) == 0) {
- *retnconf = nconf;
- return (rdcd_bindit(nconf, addr, &hs, listen_backlog));
- }
- }
- (void) endnetconfig(nc);
- if ((Is_ipv6present() && (strcmp(provider, "/dev/tcp6") == 0)) ||
- (!Is_ipv6present() && (strcmp(provider, "/dev/tcp") == 0)))
- syslog(LOG_ERR, "couldn't find netconfig entry for provider %s",
- provider);
- return (-1);
-}
-
-
-/*
- * For listen fd's index is always less than end_listen_fds.
- * It's value is equal to the number of open file descriptors after the
- * last listen end point was opened but before any connection was accepted.
- */
-static int
-is_listen_fd_index(int index)
-{
- return (index < end_listen_fds);
-}
-
-
-/*
- * Create an address mask appropriate for the transport.
- * The mask is used to obtain the host-specific part of
- * a network address when comparing addresses.
- * For an internet address the host-specific part is just
- * the 32 bit IP address and this part of the mask is set
- * to all-ones. The port number part of the mask is zeroes.
- */
-static int
-set_addrmask(int fd, struct netconfig *nconf, struct netbuf *mask)
-{
- struct t_info info;
-
- /*
- * Find the size of the address we need to mask.
- */
- if (t_getinfo(fd, &info) < 0) {
- t_error("t_getinfo");
- return (-1);
- }
- mask->len = mask->maxlen = info.addr;
- if (info.addr <= 0) {
- syslog(LOG_ERR, "set_addrmask: address size: %ld", info.addr);
- return (-1);
- }
-
- mask->buf = (char *)malloc(mask->len);
- if (mask->buf == NULL) {
- syslog(LOG_ERR, "set_addrmask: no memory");
- return (-1);
- }
- (void) memset(mask->buf, 0, mask->len); /* reset all mask bits */
-
- if (strcmp(nconf->nc_protofmly, NC_INET) == 0) {
- /*
- * Set the mask so that the port is ignored.
- */
- /* LINTED pointer alignment */
- ((struct sockaddr_in *)mask->buf)->sin_addr.s_addr =
- (in_addr_t)~0;
- /* LINTED pointer alignment */
- ((struct sockaddr_in *)mask->buf)->sin_family = (sa_family_t)~0;
- }
-#ifdef NC_INET6
- else if (strcmp(nconf->nc_protofmly, NC_INET6) == 0) {
- /* LINTED pointer alignment */
- (void) memset(&((struct sockaddr_in6 *)mask->buf)->sin6_addr,
- (uchar_t)~0, sizeof (struct in6_addr));
- /* LINTED pointer alignment */
- ((struct sockaddr_in6 *)mask->buf)->sin6_family =
- (sa_family_t)~0;
- }
-#endif
- else {
- /*
- * Set all mask bits.
- */
- (void) memset(mask->buf, (uchar_t)~0, mask->len);
- }
- return (0);
-}
-
-#if !defined(_SunOS_5_6) && !defined(_SunOS_5_7) && !defined(_SunOS_5_8)
-
-static int
-sndrsvcpool(int maxservers)
-{
- struct svcpool_args npa;
-
- npa.id = RDC_SVCPOOL_ID;
- npa.maxthreads = maxservers;
- npa.redline = 0;
- npa.qsize = 0;
- npa.timeout = 0;
- npa.stksize = 0;
- npa.max_same_xprt = 0;
- return (sndrsys(RDC_POOL_CREATE, &npa));
-}
-
-
-/*
- * The following stolen from cmd/fs.d/nfs/lib/thrpool.c
- */
-
-#include <thread.h>
-
-/*
- * Thread to call into the kernel and do work on behalf of SNDR/ncall-ip.
- */
-static void *
-svcstart(void *arg)
-{
- int id = (int)arg;
- int err;
-
- while ((err = sndrsys(RDC_POOL_RUN, &id)) != 0) {
- /*
- * Interrupted by a signal while in the kernel.
- * this process is still alive, try again.
- */
- if (err == EINTR)
- continue;
- else
- break;
- }
-
- /*
- * If we weren't interrupted by a signal, but did
- * return from the kernel, this thread's work is done,
- * and it should exit.
- */
- thr_exit(NULL);
- return (NULL);
-}
-
-/*
- * User-space "creator" thread. This thread blocks in the kernel
- * until new worker threads need to be created for the service
- * pool. On return to userspace, if there is no error, create a
- * new thread for the service pool.
- */
-static void *
-svcblock(void *arg)
-{
- int id = (int)arg;
-
- /* CONSTCOND */
- while (1) {
- thread_t tid;
- int err;
-
- /*
- * Call into the kernel, and hang out there
- * until a thread needs to be created.
- */
- if (err = sndrsys(RDC_POOL_WAIT, &id)) {
- if (err == ECANCELED || err == EBUSY)
- /*
- * If we get back ECANCELED, the service
- * pool is exiting, and we may as well
- * clean up this thread. If EBUSY is
- * returned, there's already a thread
- * looping on this pool, so we should
- * give up.
- */
- break;
- else
- continue;
- }
-
- (void) thr_create(NULL, NULL, svcstart, (void *)id,
- THR_BOUND | THR_DETACHED, &tid);
- }
-
- thr_exit(NULL);
- return (NULL);
-}
-
-static int
-svcwait(int id)
-{
- thread_t tid;
-
- /*
- * Create a bound thread to wait for kernel LWPs that
- * need to be created.
- */
- if (thr_create(NULL, NULL, svcblock, (void *)id,
- THR_BOUND | THR_DETACHED, &tid))
- return (1);
-
- return (0);
-}
-#endif /* Solaris 9+ */
diff --git a/usr/src/cmd/avs/rdc/sndrsubr.c b/usr/src/cmd/avs/rdc/sndrsubr.c
deleted file mode 100644
index 3f3e30b307..0000000000
--- a/usr/src/cmd/avs/rdc/sndrsubr.c
+++ /dev/null
@@ -1,463 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <sys/mnttab.h>
-#include <errno.h>
-#include <limits.h>
-#include <fcntl.h>
-#include <strings.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <signal.h>
-
-#include <locale.h>
-#include <langinfo.h>
-#include <libintl.h>
-#include <stdarg.h>
-#include <sys/nsctl/rdc_io.h>
-#include <sys/nsctl/rdc_ioctl.h>
-#include <sys/nsctl/rdc_prot.h>
-
-#include <sys/nsctl/cfg.h>
-
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_u.h>
-#include <sys/unistat/spcs_errors.h>
-
-#include "rdcadm.h"
-
-
-int maxqfbas = MAXQFBAS;
-int maxqitems = MAXQITEMS;
-int autosync = AUTOSYNC;
-int asyncthr = ASYNCTHR;
-int qblock = QBLOCK;
-
-int
-mounted(char *device)
-{
- char target[NSC_MAXPATH];
- struct mnttab mntref;
- struct mnttab mntent;
- FILE *mntfp;
- int rdsk;
- char *s;
- int i;
-
- rdsk = i = 0;
- for (s = target; i < NSC_MAXPATH && (*s = *device++); i++) {
- if (*s == 'r' && rdsk == 0 && strncmp(device, "dsk/", 4) == 0)
- rdsk = 1;
- else
- s++;
- }
- *s = '\0';
-
- mntref.mnt_special = target;
- mntref.mnt_mountp = NULL;
- mntref.mnt_fstype = NULL;
- mntref.mnt_mntopts = NULL;
- mntref.mnt_time = NULL;
-
- mntfp = fopen(MNTTAB, "r");
-
- if (mntfp == NULL) {
- rdc_warn(NULL,
- gettext("can not check volume %s against mount table"),
- mntref.mnt_special);
- /* Assume the worst, that it is mounted */
- return (1);
- }
-
- if (getmntany(mntfp, &mntent, &mntref) != -1) {
- /* found something before EOF */
- (void) fclose(mntfp);
- return (1);
- }
-
- (void) fclose(mntfp);
- return (0);
-}
-
-
-/* Needs to match parsing code in rdcboot.c and rdcadm.c */
-char *
-rdc_decode_flag(int flag, int options)
-{
- static char str[32];
-
- switch (flag) {
- case (RDC_CMD_COPY):
- if (options & RDC_OPT_FULL)
- (void) strcpy(str, "-m");
- else
- (void) strcpy(str, "-u");
- if (options & RDC_OPT_REVERSE)
- (void) strcat(str, " -r");
- break;
-
- case (RDC_CMD_DISABLE):
- (void) strcpy(str, "-d");
- break;
-
- case (RDC_CMD_ENABLE):
- if (options & RDC_OPT_SETBMP)
- (void) strcpy(str, "-e");
- else
- (void) strcpy(str, "-E");
- break;
-
- case (RDC_CMD_LOG):
- (void) strcpy(str, "-l");
- break;
-
- case (RDC_CMD_HEALTH):
- (void) strcpy(str, "-H");
- break;
-
- case (RDC_CMD_WAIT):
- (void) strcpy(str, "-w");
- break;
-
- case (RDC_CMD_RECONFIG):
- (void) strcpy(str, "-R ...");
- break;
-
- case (RDC_CMD_TUNABLE):
- (void) strcpy(str, "");
- if (maxqfbas != MAXQFBAS)
- (void) strcat(str, " -F");
- if (maxqitems != MAXQITEMS)
- (void) strcat(str, " -W");
- if (autosync != AUTOSYNC)
- (void) strcat(str, " -a");
- if (asyncthr != ASYNCTHR)
- (void) strcat(str, " -A");
- if (qblock != QBLOCK)
- (void) strcat(str, " -D");
- break;
-
- case (RDC_CMD_SUSPEND):
- (void) strcpy(str, "-s");
- break;
-
- case (RDC_CMD_RESUME):
- (void) strcpy(str, "-r");
- break;
-
- case (RDC_CMD_RESET):
- (void) strcpy(str, "-R");
- break;
-
- case (RDC_CMD_ADDQ):
- (void) strcpy(str, "-q a");
- break;
-
- case (RDC_CMD_REMQ):
- (void) strcpy(str, "-q d");
- break;
-
- case (RDC_CMD_REPQ):
- (void) strcpy(str, "-q r");
- break;
-
- default:
- (void) strcpy(str, gettext("unknown"));
- break;
- }
-
- return (str);
-}
-
-
-static void
-rdc_msg(char *prefix, spcs_s_info_t *status, char *string, va_list ap)
-{
- if (status) {
- (void) fprintf(stderr, "Remote Mirror: %s\n", prefix);
- spcs_s_report(*status, stderr);
- } else {
- (void) fprintf(stderr, "%s: %s: ", program, prefix);
- }
-
- if (string && *string != '\0') {
- (void) vfprintf(stderr, string, ap);
- }
-
- (void) fprintf(stderr, "\n");
-}
-
-void
-rdc_err(spcs_s_info_t *status, char *string, ...)
-{
- va_list ap;
- va_start(ap, string);
-
- rdc_msg(gettext("Error"), status, string, ap);
-
- va_end(ap);
- exit(1);
-}
-
-void
-rdc_warn(spcs_s_info_t *status, char *string, ...)
-{
- va_list ap;
- va_start(ap, string);
-
- rdc_msg(gettext("warning"), status, string, ap);
-
- va_end(ap);
-}
-
-int
-rdc_get_maxsets(void)
-{
- rdc_status_t rdc_status;
- spcs_s_info_t ustatus;
- int rc;
-
- rdc_status.nset = 0;
- ustatus = spcs_s_ucreate();
-
- rc = RDC_IOCTL(RDC_STATUS, &rdc_status, 0, 0, 0, 0, ustatus);
- if (rc == SPCS_S_ERROR) {
- rdc_err(&ustatus, gettext("statistics error"));
- }
-
- spcs_s_ufree(&ustatus);
- return (rdc_status.maxsets);
-}
-
-/*
- * Look up a set in libcfg to find the setnumber.
- *
- * ASSUMPTIONS:
- * - a valid cfg handle
- *
- * INPUTS:
- * cfg - cfg handle
- * tohost - secondary hostname
- * tofile - secondary volume
- *
- * OUTPUTS:
- * set number if found, otherwise -1 for an error
- */
-int
-find_setnumber_in_libcfg(CFGFILE *cfg, char *ctag, char *tohost, char *tofile)
-{
- int setnumber;
- int entries, rc;
- char *buf, *secondary, *shost;
- char **entry;
- char *cnode;
- int offset = 0;
-
- if (cfg == NULL) {
-#ifdef DEBUG
- rdc_warn(NULL, "cfg is NULL while looking up set number");
-#endif
- return (-1);
- }
-
- entries = cfg_get_section(cfg, &entry, "sndr");
-
- rc = -1;
- for (setnumber = 1; setnumber <= entries; setnumber++) {
- buf = entry[setnumber - 1];
-
- (void) strtok(buf, " "); /* phost */
- (void) strtok(NULL, " "); /* primary */
- (void) strtok(NULL, " "); /* pbitmap */
- shost = strtok(NULL, " ");
- secondary = strtok(NULL, " ");
-
- if (ctag && *ctag) {
- (void) strtok(NULL, " "); /* sbitmap */
- (void) strtok(NULL, " "); /* type */
- (void) strtok(NULL, " "); /* mode */
- (void) strtok(NULL, " "); /* group */
- cnode = strtok(NULL, " ");
-
- if (ctag && strcmp(cnode, ctag) != 0) {
- /* filter this out */
- ++offset;
- continue;
- }
- }
-
- /* Check secondary volume name first, will get less hits */
- if (strcmp(secondary, tofile) != 0) {
- free(buf);
- continue;
- }
-
- if (strcmp(shost, tohost) == 0) {
- free(buf);
- rc = setnumber - offset;
- break;
- }
-
- free(buf);
- }
-
- while (setnumber < entries)
- free(entry[setnumber++]);
- if (entries)
- free(entry);
-
- return (rc);
-}
-
-void
-get_group_diskq(CFGFILE *cfg, char *group, char *diskq)
-{
- int i;
- char key[CFG_MAX_KEY];
- char buf[CFG_MAX_BUF];
-
- if (*group == '\0')
- return;
- for (i = 1; ; i++) {
- bzero(&key, sizeof (key));
- bzero(&buf, sizeof (buf));
- (void) sprintf(key, "sndr.set%d.group", i);
- if (cfg_get_cstring(cfg, key, &buf, sizeof (buf)) < 0)
- break;
- if (strncmp(group, buf, sizeof (buf)) == 0) {
- (void) sprintf(key, "sndr.set%d.diskq", i);
- if (cfg_get_cstring(cfg, key, diskq, CFG_MAX_BUF) < 0) {
- rdc_warn(NULL, gettext("unable to retrieve "
- "group %s's disk queue"), group);
- }
- }
- }
-}
-
-int
-get_cfg_setid(CFGFILE *cfg, char *ctag, char *tohost, char *tofile)
-{
- int setnum = 0;
- int close_cfg = 0;
- char key[CFG_MAX_KEY];
- char setid[64];
-
- if (cfg == NULL) {
- close_cfg = 1;
- if ((cfg = cfg_open(NULL)) == NULL) {
- return (-1); /* message printed by caller */
- }
- if (!cfg_lock(cfg, CFG_RDLOCK)) {
- cfg_close(cfg);
- return (-1);
- }
- }
- setnum = find_setnumber_in_libcfg(cfg, ctag, tohost, tofile);
- if (setnum < 0)
- return (setnum);
-
- (void) snprintf(key, CFG_MAX_KEY, "sndr.set%d.options", setnum);
- if (cfg_get_single_option(cfg, CFG_SEC_CONF, key, "setid",
- setid, sizeof (setid)) < 0) {
- if (close_cfg)
- cfg_close(cfg);
-
- spcs_log("sndr", NULL,
- gettext("%s unable to get unique setid "
- "for %s:%s"), program, tohost, tofile);
- return (-1);
-
- }
- if (close_cfg)
- cfg_close(cfg);
-
- return (atoi(setid));
-
-}
-
-int
-get_new_cfg_setid(CFGFILE *cfg)
-{
- int setid;
- char buf[CFG_MAX_BUF];
- char *ctag;
-
- /* If in a Sun Cluster, SetIDs need to have a ctag */
- if ((ctag = cfg_get_resource(cfg)) != NULL) {
- ctag = strdup(ctag);
- cfg_resource(cfg, "setid-ctag");
- }
-
- if (cfg_get_cstring(cfg, "setid.set1.value", buf, CFG_MAX_BUF) < 0) {
- setid = 1;
- if (cfg_put_cstring(cfg, "setid", "1", CFG_MAX_BUF) < 0) {
- rdc_err(NULL, "Unable to store new setid");
- }
- } else {
- setid = atoi(buf);
- setid++;
- if (setid <= 0) {
- setid = 1;
- }
- }
-
- bzero(&buf, CFG_MAX_BUF);
- (void) snprintf(buf, sizeof (buf), "%d", setid);
- if (cfg_put_cstring(cfg, "setid.set1.value", buf, CFG_MAX_BUF) < 0) {
- rdc_err(NULL, "Unable to store new setid");
- }
-
- /* Restore old ctag if in a Sun Cluster */
- if (ctag) {
- cfg_resource(cfg, ctag);
- free(ctag);
- }
-
- return (setid);
-}
-
-sigset_t origmask;
-
-void
-block_sigs(void)
-{
- sigset_t allsigs;
-
- (void) sigfillset(&allsigs);
- if (sigprocmask(SIG_BLOCK, &allsigs, &origmask) < 0)
- rdc_warn(NULL, gettext("Unable to block signals"));
-}
-
-void
-unblock_sigs(void)
-{
- if (sigprocmask(SIG_SETMASK, &origmask, NULL) < 0)
- rdc_warn(NULL, gettext("Unable to unblock signals"));
-
-}
diff --git a/usr/src/cmd/avs/rdc/sndrsyncd.c b/usr/src/cmd/avs/rdc/sndrsyncd.c
deleted file mode 100644
index 5f2c56d1b1..0000000000
--- a/usr/src/cmd/avs/rdc/sndrsyncd.c
+++ /dev/null
@@ -1,1695 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <stdio.h>
-#include <errno.h>
-#include <limits.h>
-#include <fcntl.h>
-#include <strings.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <pthread.h>
-#include <thread.h>
-
-#include <locale.h>
-#include <langinfo.h>
-#include <libintl.h>
-#include <stdarg.h>
-
-#include <sys/nsctl/rdc_io.h>
-#include <sys/nsctl/rdc_ioctl.h>
-#include <sys/nsctl/rdc_prot.h>
-
-#include <sys/nsctl/cfg.h>
-
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_u.h>
-#include <sys/unistat/spcs_errors.h>
-
-#include <sys/nsctl/librdc.h>
-
-#include "rdcadm.h"
-
-
-#define RDCADM "/usr/sbin/sndradm"
-#define IIADM "/usr/sbin/iiadm"
-
-#define UPDATE "update"
-#define NOUPDATE "noupdate"
-
-#define RESYNC_SLEEP (3 * 60) /* Three minutes */
-#define MAIN_SLEEP (5 * 60) /* Five minutes */
-#define CFG_WAIT_SLEEP (5) /* 5 sec */
-
-#define MAXHOSTS 1024
-mutex_t cfglock = DEFAULTMUTEX;
-#define LOCKCFG() (void) mutex_lock(&cfglock);
-#define UNLOCKCFG() (void) mutex_unlock(&cfglock);
-
-typedef struct host_list_s {
- char *hosts[MAXHOSTS];
- int numhosts;
- int configured[MAXHOSTS];
- mutex_t hosts_mutex;
-} host_list_t;
-
-host_list_t *host_list;
-
-extern char *basename(char *);
-int rdc_maxsets;
-char *program;
-
-static int clustered = 0;
-
-int isnewhost(char *host);
-void *wait_sync_event();
-void *wait_link_down(void *host);
-void rdc_sync(char *tohost);
-void remove_from_hostlist(char *host);
-void sync_start(char *master);
-void sync_complete(char *master);
-void cleanup_hostlist();
-void group_start(char *group);
-void group_complete(char *group);
-
-
-void
-init_host_list(void)
-{
- host_list = calloc(1, sizeof (host_list_t));
- if (host_list == NULL) {
- spcs_log("sndr", NULL,
- gettext("host list not initialized, cannot run"));
- rdc_err(NULL, gettext("host list not initialized, cannot run"));
- }
- (void) mutex_init(&host_list->hosts_mutex, USYNC_THREAD, NULL);
-}
-
-/* ARGSUSED */
-#ifdef lint
-void
-sndrsyncd_lintmain(argc, argv)
-#else
-int
-main(argc, argv)
-#endif
-int argc;
-char **argv;
-{
- rdc_status_t *rdc_info;
- int size;
- int i;
- pid_t pid;
- spcs_s_info_t ustatus;
- int rc, trc;
- int first = 0;
- char *required;
-
- (void) setlocale(LC_ALL, "");
- (void) textdomain("rdc");
-
- ustatus = spcs_s_ucreate();
-
- program = basename(argv[0]);
-
- init_host_list();
-
- rc = rdc_check_release(&required);
- if (rc < 0) {
- rdc_err(NULL,
- gettext("unable to determine the current "
- "Solaris release: %s\n"), strerror(errno));
- /* NOTREACHED */
- } else if (rc == FALSE) {
- rdc_err(NULL,
- gettext("incorrect Solaris release (requires %s)\n"),
- required);
- /* NOTREACHED */
- }
-
- clustered = cfg_iscluster();
- if (clustered < 0) {
- rdc_err(NULL, gettext("unable to ascertain environment"));
- }
-
- rdc_maxsets = rdc_get_maxsets();
- if (rdc_maxsets == -1) {
- spcs_log("sndr", NULL,
- gettext("%s: unable to get maxsets value from kernel"),
- program);
- rdc_err(NULL,
- gettext("unable to get maxsets value from kernel"));
- }
- size = sizeof (rdc_status_t) + (sizeof (rdc_set_t) * (rdc_maxsets - 1));
- rdc_info = malloc(size);
- if (rdc_info == NULL) {
- spcs_log("sndr", NULL,
- gettext("%s: unable to allocate %ld bytes"),
- program, size);
- rdc_err(NULL,
- gettext("unable to allocate %ld bytes"), size);
- }
- bzero(rdc_info, size);
-
- rdc_info->nset = rdc_maxsets;
-
- /*
- * Fork off a child that becomes the daemon.
- */
- if ((pid = fork()) > 0)
- exit(0);
- else if (pid < 0) {
- spcs_log("sndr", NULL,
- gettext("%s: cannot fork: %s"),
- program, strerror(errno));
- rdc_err(NULL, gettext("cannot fork: %s\n"),
- strerror(errno));
- }
-
- /*
- * In child - become daemon.
- */
-
- for (i = 0; i < 3; i++)
- (void) close(i);
-
- (void) open("/dev/console", O_WRONLY|O_APPEND);
- (void) dup(0);
- (void) dup(0);
- (void) close(0);
-
- (void) setpgrp();
-
- (void) setlocale(LC_ALL, "");
- (void) textdomain("rdc");
-
- /* launch a thread to wait for sync start and sync stop events */
-
- if ((trc = thr_create(NULL, 0, wait_sync_event, NULL,
- THR_BOUND|THR_DETACHED, NULL)) != 0) {
- spcs_log("sndr", NULL,
- gettext("%s: unable to create thread wait_sync_event"),
- program);
- rdc_warn(NULL,
- gettext("%s unable to create thread wait_sync_event"),
- program);
- } else {
-#ifdef DEBUG
- spcs_log("sndr", NULL,
- gettext("%s: thread wait_sync_event started"), program);
-#endif
- ;
- }
-
- for (;;) {
- if (!first) {
- first++;
- (void) sleep(15);
- } else
- (void) sleep(MAIN_SLEEP);
-
- bzero(rdc_info, size);
- rdc_info->nset = rdc_maxsets;
- if (RDC_IOCTL(RDC_STATUS, rdc_info, 0, 0, 0, 0, ustatus)
- != SPCS_S_OK) {
- spcs_log("sndr", &ustatus,
- gettext("%s: status ioctl"),
- program);
- rdc_warn(&ustatus, gettext("status ioctl"));
- continue;
- }
-
- cleanup_hostlist(rdc_info); /* remove non-existent hosts */
-
- /*
- * Check all enabled sets to see if a new remote host has
- * appeared.
- */
- for (i = 0; i < rdc_maxsets; i++) {
- if (!(rdc_info->rdc_set[i].flags & RDC_ENABLED))
- continue;
- /* spawn a new thread for each new host found */
- if (isnewhost(rdc_info->rdc_set[i].secondary.intf)) {
- /*
- * right now, we could be here before
- * the database did the write for this set
- * I could check the lock on the database
- * but I am just going to give up some time here
- * instead. Why do the allocations etc, etc
- * if the set is enabled in the kernel and not
- * in the config, we know that this set has the
- * lock. Why bother adding more contention to
- * the lock.
- * this is a daemon, afterall. its got time
- */
- (void) sleep(CFG_WAIT_SLEEP);
-
- spcs_log("sndr", NULL,
- gettext("%s: new host found (%s) starting "
- "its autosync thread"), program,
- rdc_info->rdc_set[i].secondary.intf);
-
- trc = thr_create(NULL, 0, wait_link_down,
- (void *) rdc_info->rdc_set[i].\
-secondary.intf, THR_BOUND|THR_DETACHED, NULL);
-
- if (trc != 0) {
- spcs_log("sndr", NULL,
- gettext(
- "%s create new autosync "
- "thread failed"), program);
- rdc_warn(NULL, gettext(
- "%s create new autosync "
- "thread failed"), program);
- }
- }
- }
- }
- /* NOTREACHED */
-}
-
-
-/*
- * The kernel wakes up this function every time it detects the link to the
- * specified host has dropped.
- */
-void *
-wait_link_down(void *thehost)
-{
- char *host = (char *)thehost;
- char tmphost[MAX_RDC_HOST_SIZE] = { '\0' };
- spcs_s_info_t ustatus;
-
- if (host)
- (void) strncpy(tmphost, host, MAX_RDC_HOST_SIZE);
-
- ustatus = spcs_s_ucreate();
-
- /* Never give up */
- for (;;) {
-#ifdef DEBUG
- spcs_log("sndr", NULL,
- gettext("%s: awaiting link down ioctl for %s"),
- program, host[0] == '\0' ? tmphost : host);
-#endif
- if (RDC_IOCTL(RDC_LINK_DOWN, host, 0, 0, 0, 0, ustatus)
- != SPCS_S_OK) {
- spcs_log("sndr", &ustatus,
- gettext("%s: link down ioctl"),
- program);
- rdc_warn(&ustatus, gettext("link down ioctl"));
- continue;
- }
-#ifdef DEBUG
-
- spcs_log("sndr", NULL,
- gettext("%s: received link down ioctl for %s"),
- program, host[0] == '\0' ? tmphost : host);
-#endif
- rdc_sync(host[0] == '\0' ? tmphost : host);
- }
- /* LINTED */
-}
-
-
-/*
- * Called when the link to the specified host has dropped.
- * For all Remote Mirror sets using the link that have autosync on,
- * issue rdcadm -u commands until they complete successfully.
- */
-void
-rdc_sync(char *tohost)
-{
- rdc_set_t *rdc_set = NULL;
- int *sync_done = NULL;
- int sets = 0;
- int syncs_done = 0;
- char cmd[256];
- rdc_config_t parms = { 0 };
- spcs_s_info_t ustatus;
- int i;
- int setnumber;
- int numfound = 0;
- char buf[CFG_MAX_BUF];
- char key[CFG_MAX_KEY];
- CFGFILE *cfg = NULL;
- int size;
- int first = 0;
- int death = 0;
- int cfglocked = 0;
-
- ustatus = spcs_s_ucreate();
-
- size = sizeof (rdc_set_t) * rdc_maxsets;
- rdc_set = malloc(size);
- if (rdc_set == NULL) {
- spcs_log("sndr", NULL,
- gettext("%s: unable to allocate %ld bytes"),
- program, size);
- rdc_warn(NULL,
- gettext("unable to allocate %ld bytes"), size);
- goto done;
- }
- bzero(rdc_set, size);
- size = sizeof (int) * rdc_maxsets;
- sync_done = malloc(size);
- if (sync_done == NULL) {
- spcs_log("sndr", NULL,
- gettext("%s: unable to allocate %ld bytes"),
- program, size);
- rdc_warn(NULL,
- gettext("unable to allocate %ld bytes"), size);
- goto done;
- }
- bzero(sync_done, size);
-
- /*
- * Get all sndr entries with shost matching tohost, and save the
- * details in an array.
- */
- for (i = 0; i < rdc_maxsets; i++) {
- setnumber = i + 1;
- bzero(buf, sizeof (buf));
- bzero(key, sizeof (key));
-
- (void) snprintf(key, sizeof (key), "sndr.set%d.shost",
- setnumber);
-
- if (!cfglocked) {
- LOCKCFG();
- if ((cfg = cfg_open(NULL)) == NULL) {
- spcs_log("sndr", NULL,
- gettext("%s: error opening config"),
- program);
-
- rdc_warn(NULL,
- gettext("error opening config"));
- UNLOCKCFG();
- goto done;
- }
-
- if (!cfg_lock(cfg, CFG_RDLOCK)) {
- spcs_log("sndr", NULL,
- gettext("%s: error locking config"),
- program);
- rdc_warn(NULL, gettext("error locking config"));
- goto done;
- }
- }
-
- cfglocked = 1;
-
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) {
- if (numfound == 0) /* no matching hosts */
- death = 1; /* thread will exit */
- break;
- }
- if (strcmp(buf, tohost) != 0)
- continue;
-
- numfound++;
- (void) strncpy(rdc_set[sets].secondary.intf, buf,
- MAX_RDC_HOST_SIZE);
-
- /* Got a matching entry */
-
- (void) snprintf(key, sizeof (key), "sndr.set%d.phost",
- setnumber);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
- break;
- (void) strncpy(rdc_set[sets].primary.intf, buf,
- MAX_RDC_HOST_SIZE);
-
- (void) snprintf(key, sizeof (key), "sndr.set%d.primary",
- setnumber);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
- break;
- (void) strncpy(rdc_set[sets].primary.file, buf, NSC_MAXPATH);
-
- (void) snprintf(key, sizeof (key), "sndr.set%d.secondary",
- setnumber);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
- break;
- (void) strncpy(rdc_set[sets].secondary.file, buf, NSC_MAXPATH);
-
- parms.command = RDC_CMD_STATUS;
- bcopy((void *)(&rdc_set[sets]), (void *)(&parms.rdc_set[0]),
- sizeof (rdc_set_t));
-
- /*
- * release cfg before diving into the kernel
- * this prevents a possible deadlock when doing
- * a reverse sync whick will wake up the sync_event
- * thread which will try and iiadm -c and hang
- * because we still have the cfg_lock. the timed
- * wait cv in the kernel will fail the sync and things
- * will undeadlock.
- */
-
- cfg_close(cfg);
- cfg = NULL;
- cfglocked = 0;
- UNLOCKCFG();
-
- if (RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, ustatus) < 0) {
- continue;
- }
- if ((parms.rdc_set[0].autosync == 0) ||
- (!(parms.rdc_set[0].flags & RDC_LOGGING))) {
- continue;
- }
-
- /* Found a suitable set with autosync on, in logging mode */
- sets++;
- }
-
- if (cfg) {
- cfg_close(cfg);
- cfg = NULL;
- UNLOCKCFG();
- }
-
- if (sets == 0) {
-#ifdef DEBUG
- spcs_log("sndr", NULL,
- gettext("%s: no sets requiring autosync found for %s"),
- program, tohost);
-#endif
- if (death) {
- spcs_log("sndr", NULL,
- gettext("%s: autosync thread stopping for %s "
- "(host deconfigured)"), program, tohost);
- }
- goto done;
- }
-
- /* Keep issuing rdcadm -u commands until they have all completed */
- for (;;) {
- if (!first)
- first++;
- else
- (void) sleep(RESYNC_SLEEP);
-
- /* Issue rdcadm -u commands for all remaining sets */
- for (i = 0; i < sets; i++) {
- if (sync_done[i])
- continue;
-
- /*
- * Need to check if autosync was turned off for a set
- * while we were sleeping. We could have the case where
- * an update sync failed and autosync was disabled
- * while we were sleeping and didn't detect the disable.
- * See BugID 4814213.
- */
- parms.command = RDC_CMD_STATUS;
- bcopy((void *)(&rdc_set[i]),
- (void *)(&parms.rdc_set[0]), sizeof (rdc_set_t));
- if (RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0,
- ustatus) < 0) {
- spcs_log("sndr", &ustatus, gettext("%s: "
- "status not available for %s:%s, stopping "
- "this autosync attempt"), program, tohost,
- rdc_set[i].secondary.file);
- sync_done[i] = 1;
- syncs_done++;
- continue;
- }
- if (!(parms.rdc_set[0].autosync)) {
-#ifdef DEBUG
- spcs_log("sndr", NULL, gettext("%s: autosync disabled during sleep, "
- "stopping attempt for set %s:%s"), program, tohost,
- rdc_set[i].secondary.file);
-#endif
- sync_done[i] = 1;
- syncs_done++;
- continue;
- }
-
- (void) sprintf(cmd, "%s -un %s:%s", RDCADM, tohost,
- rdc_set[i].secondary.file);
- spcs_log("sndr", NULL,
- gettext("%s: issuing update sync for %s:%s"),
- program, tohost, rdc_set[i].secondary.file);
- (void) system(cmd);
- }
-
- /* Issue rdcadm -w commands to wait for updates to finish */
- for (i = 0; i < sets; i++) {
- if (sync_done[i])
- continue;
-
- (void) sprintf(cmd, "%s -wn %s:%s", RDCADM, tohost,
- rdc_set[i].secondary.file);
- spcs_log("sndr", NULL,
- gettext("%s: issuing wait for %s:%s"),
- program, tohost, rdc_set[i].secondary.file);
-
- (void) system(cmd);
-
- parms.command = RDC_CMD_STATUS;
- bcopy((void *)(&rdc_set[i]),
- (void *)(&parms.rdc_set[0]), sizeof (rdc_set_t));
-
- if (RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0,
- ustatus) < 0) {
- spcs_log("sndr", &ustatus,
- gettext("%s: status not available for "
- "%s:%s, stopping this autosync attempt"),
- program, tohost, rdc_set[i].secondary.file);
- sync_done[i] = 1;
- syncs_done++;
- continue;
- }
- /* Check if completed OK, failed or autosync off */
- if (!(parms.rdc_set[0].autosync) ||
- !(parms.rdc_set[0].flags & RDC_LOGGING) &&
- !(parms.rdc_set[0].flags & RDC_SYNCING)) {
- sync_done[i] = 1;
- syncs_done++;
- }
- }
-
- if (syncs_done == sets)
- break; /* All completed OK */
- }
-
-done:
- if (cfg) {
- cfg_close(cfg);
- UNLOCKCFG();
- }
- spcs_s_ufree(&ustatus);
- if (sync_done)
- free(sync_done);
- if (rdc_set)
- free(rdc_set);
- if (death) { /* bye bye */
- /*
- * if perhaps we lost some race, lets remove this entry from
- * the list. Then, if something did go wrong, and we did kill
- * a valid thread, it will be detected on the next go around
- * of the thread who is looking for new hosts to spawn threads
- */
-
- remove_from_hostlist(tohost);
- thr_exit(0);
- }
-
- (void) sleep(RESYNC_SLEEP);
-}
-
-/*
- * Wait for notification by the kernel of a sync start or a sync completed OK
- */
-void *
-wait_sync_event()
-{
- spcs_s_info_t ustatus;
- char master[NSC_MAXPATH];
- char group[NSC_MAXPATH];
- int state;
-
- ustatus = spcs_s_ucreate();
-
- master[0] = '\0';
- group[0] = '\0';
-
- /* Never give up */
- for (;;) {
- /* Kernel tells us which volume and group the event is for */
- state = RDC_IOCTL(RDC_SYNC_EVENT, master, group, 0, 0, 0,
- ustatus);
- if (state < SPCS_S_OK) {
- if (errno != EAGAIN) {
- spcs_log("sndr", &ustatus,
- gettext("%s: update ioctl"),
- program);
- rdc_warn(&ustatus, gettext("update ioctl"));
- continue;
- }
- master[0] = '\0';
- continue;
- }
-
- /*
- * If target is mounted at the start of a sync or reverse sync,
- * return a negative ack.
- */
- if ((state == RDC_SYNC_START || state == RDC_RSYNC_START) &&
- mounted(master)) {
- spcs_log("sndr", NULL,
- gettext("%s: %s has a file system mounted"),
- program, master);
- rdc_warn(NULL,
- gettext("%s has a file system mounted"),
- master);
- master[0] = '\0'; /* negative ack */
- continue;
- }
-
- switch (state) {
- case RDC_SYNC_START:
- if (group[0])
- group_start(group);
- else
- sync_start(master);
- break;
-
- case RDC_SYNC_DONE:
- if (group[0])
- group_complete(group);
- else
- sync_complete(master);
- break;
-
- default:
- break;
- }
- }
- /* LINTED */
-}
-
-
-/*
- * A sync has completed OK to a volume not belonging to a group.
- * Set the state of the ndr_ii config entry to "update".
- */
-void
-sync_complete(char *master)
-{
- CFGFILE *cfg = NULL;
- char buf[CFG_MAX_BUF];
- char key[CFG_MAX_KEY];
- int i;
- int setnumber;
- int sev;
-
- LOCKCFG();
- if ((cfg = cfg_open(NULL)) == NULL) {
- spcs_log("sndr", NULL,
- gettext("%s: error opening config"),
- program);
- rdc_warn(NULL, gettext("error opening config"));
- UNLOCKCFG();
- return;
- }
- if (!cfg_lock(cfg, CFG_WRLOCK)) {
- spcs_log("sndr", NULL,
- gettext("%s: error locking config"),
- program);
- rdc_warn(NULL, gettext("error locking config"));
- cfg_close(cfg);
- UNLOCKCFG();
- return;
- }
-
- /* get ndr_ii entries until a match is found */
- for (i = 0; ; i++) {
- setnumber = i + 1;
-
- (void) snprintf(key, sizeof (key), "ndr_ii.set%d.secondary",
- setnumber);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
- break;
- if (strcmp(buf, master) != 0)
- continue;
-
- /* Found the matching entry */
-
- /*
- * Set state to "update" so that starting another sync will
- * cause a new Point-in-Time Copy snapshot to be taken.
- */
- (void) snprintf(key, sizeof (key), "ndr_ii.set%d.state",
- setnumber);
- if ((cfg_put_cstring(cfg, key, UPDATE, strlen(UPDATE)) < 0) ||
- (cfg_commit(cfg) < 0)) {
- spcs_log("sndr", NULL,
- gettext("%s: unable to update \"%s\" "
- "in configuration storage: %s"),
- program, buf, cfg_error(&sev));
- rdc_warn(NULL,
- gettext("unable to update \"%s\" "
- "in configuration storage: %s"),
- buf, cfg_error(&sev));
- }
- break;
- }
-
- cfg_close(cfg);
- UNLOCKCFG();
-}
-
-
-/*
- * Starting a sync to the specified master volume.
- * Check the ndr_ii config entries to see if a Point-in-Time Copy
- * snapshot should be taken.
- */
-void
-sync_start(char *master)
-{
- char cmd[256];
- char buf[CFG_MAX_BUF];
- char key[CFG_MAX_KEY];
- CFGFILE *cfg = NULL;
- int i;
- int setnumber;
- int found;
- int sev;
- char shadow[NSC_MAXPATH];
- char bitmap[NSC_MAXPATH];
- char *ctag = NULL;
-
- LOCKCFG();
- if ((cfg = cfg_open(NULL)) == NULL) {
- spcs_log("sndr", NULL,
- gettext("%s: error opening config"),
- program);
- rdc_warn(NULL,
- gettext("error opening config"));
- UNLOCKCFG();
- return;
- }
- if (!cfg_lock(cfg, CFG_RDLOCK)) {
- spcs_log("sndr", NULL,
- gettext("%s: error locking config"),
- program);
- rdc_warn(NULL, gettext("error locking config"));
- cfg_close(cfg);
- UNLOCKCFG();
- return;
- }
-
- found = 0;
- /* get ndr_ii entries until a match is found */
- for (i = 0; ; i++) {
- setnumber = i + 1;
-
- (void) snprintf(key, sizeof (key), "ndr_ii.set%d.secondary",
- setnumber);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
- break;
- if (strcmp(buf, master) != 0)
- continue;
-
- /* Got a matching entry */
-
- (void) snprintf(key, sizeof (key), "ndr_ii.set%d.shadow",
- setnumber);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
- break;
- (void) strncpy(shadow, buf, NSC_MAXPATH);
-
- (void) snprintf(key, sizeof (key), "ndr_ii.set%d.bitmap",
- setnumber);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
- break;
- (void) strncpy(bitmap, buf, NSC_MAXPATH);
-
- (void) snprintf(key, sizeof (key), "ndr_ii.set%d.state",
- setnumber);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
- break;
-
- /*
- * If an PIT snapshot has already been taken, and syncing did
- * not complete, the state will be "noupdate", to indicate we
- * should not take another one at this point.
- */
- if (strcmp(buf, NOUPDATE) != 0)
- found = 1;
-
- break;
- }
-
- if (!found) {
- cfg_close(cfg);
- UNLOCKCFG();
- return;
- }
-
- found = 0;
- /* get ii entries until a match is found */
- for (i = 0; ; i++) {
- setnumber = i + 1;
-
- (void) snprintf(key, sizeof (key), "ii.set%d.shadow",
- setnumber);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
- break;
- if (strcmp(buf, shadow) != 0)
- continue;
-
- /* Matching shadow found, so ii already enabled */
- found = 1;
- break;
- }
-
- if (found) {
- /* Already PIT enabled, so just take a snapshot */
-
- /* Get cluster tag of matching entry */
- (void) snprintf(key, sizeof (key), "ii.set%d.cnode", setnumber);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) >= 0)
- if ((strlen(buf) == 0) || (buf[0] == '-'))
- ctag = "-C local";
- else
- ctag = "";
- (void) sprintf(cmd, "%s %s -u s %s", IIADM, ctag, shadow);
- } else {
- /*
- * If clustered, need to enable PIT Copy sets in the same
- * cluster as the Remote Mirror set
- */
-
- if (clustered) {
- /* Find a RM set with master as the local volume */
-
- for (i = 0; i < rdc_maxsets; i++) {
- setnumber = i + 1;
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.phost", setnumber);
- if (cfg_get_cstring(cfg, key, buf,
- CFG_MAX_BUF) < 0)
- break;
-
- if (self_check(buf))
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.primary", setnumber);
- else
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.secondary", setnumber);
- if (cfg_get_cstring(cfg, key, buf,
- CFG_MAX_BUF) < 0)
- break;
-
- if (strcmp(buf, master) != 0)
- continue;
-
- /* Get cluster tag of matching entry */
-
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.cnode", setnumber);
- if (cfg_get_cstring(cfg, key, buf,
- CFG_MAX_BUF) < 0)
- break;
- if ((strlen(buf) == 0) || (buf[0] == '-'))
- ctag = strdup("local");
- else
- ctag = strdup(buf);
- break;
- }
- }
-
- /* Not already enabled, so enable a dependent */
- if (ctag) {
- (void) sprintf(cmd, "%s -C %s -e dep %s %s %s", IIADM,
- ctag, master, shadow, bitmap);
- free(ctag);
- } else
- (void) sprintf(cmd, "%s -e dep %s %s %s", IIADM, master,
- shadow, bitmap);
- }
-
- cfg_close(cfg);
-
- if (system(cmd) != 0) {
- spcs_log("sndr", NULL,
- gettext("Point-in-Time Copy snapshot failed for %s %s %s."
- " Please check validity of ndr_ii entry"),
- master, shadow, bitmap);
- cfg_close(cfg);
- UNLOCKCFG();
- return;
- }
-
- /*
- * PIT Copy enable or update was fine, so update the ndr_ii entry
- * to "noupdate", to prevent invalid point in time copies.
- */
-
- if ((cfg = cfg_open(NULL)) == NULL) {
- spcs_log("sndr", NULL,
- gettext("%s: error opening config"),
- program);
- rdc_warn(NULL,
- gettext("error opening config"));
- UNLOCKCFG();
- return;
- }
- if (!cfg_lock(cfg, CFG_WRLOCK)) {
- spcs_log("sndr", NULL,
- gettext("%s: error locking config"),
- program);
- rdc_warn(NULL, gettext("error locking config"));
- cfg_close(cfg);
- UNLOCKCFG();
- return;
- }
-
- /* get ndr_ii entries until a match is found */
- for (i = 0; ; i++) {
- setnumber = i + 1;
-
- (void) snprintf(key, sizeof (key), "ndr_ii.set%d.shadow",
- setnumber);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
- break;
- if (strcmp(buf, shadow) != 0)
- continue;
-
- /* Found the matching entry */
-
- (void) snprintf(key, sizeof (key), "ndr_ii.set%d.state",
- setnumber);
- if ((cfg_put_cstring(cfg, key, NOUPDATE,
- strlen(NOUPDATE)) < 0) || (cfg_commit(cfg) < 0)) {
- spcs_log("sndr", NULL,
- gettext("%s: unable to update \"%s\" "
- "in configuration storage: %s"),
- program, buf, cfg_error(&sev));
- rdc_warn(NULL,
- gettext("unable to update \"%s\" "
- "in configuration storage: %s"),
- buf, cfg_error(&sev));
- }
- break;
- }
- cfg_close(cfg);
- UNLOCKCFG();
-}
-
-void
-cleanup_hostlist(rdc_status_t *rdc_info)
-{
- int i, j, k;
- char *host, *exhost;
-
-
- (void) mutex_lock(&host_list->hosts_mutex);
- for (i = 0; i < host_list->numhosts; i++) {
- int found = 0;
- for (j = 0; (j < rdc_maxsets) && !found; j++) {
- if (!rdc_info->rdc_set[j].flags & RDC_ENABLED)
- continue;
- if ((!host_list->configured[i]) ||
- (host_list->hosts[i] == NULL)) {
- (void) mutex_unlock(&host_list->hosts_mutex);
- return;
- }
-
- host = rdc_info->rdc_set[j].secondary.intf;
- if (strcmp(host_list->hosts[i], host) == 0)
- found++;
- }
- if (j == rdc_maxsets) {
- /*
- * this set is not in the kernel, so remove from list
- */
- exhost = host_list->hosts[i];
- if (exhost) {
- free(exhost);
- exhost = NULL;
- }
-
- k = i;
- while (k < host_list->numhosts) {
- host_list->hosts[k] = k < host_list->numhosts - 1 ?
- host_list->hosts[k+1] : NULL;
- k++;
- }
- host_list->numhosts--;
-
- bcopy(&host_list->configured[i+1],
- &host_list->configured[i],
- (MAXHOSTS - i + 1) * sizeof (int));
- host_list->configured[MAXHOSTS - 1] = 0;
- }
- }
- (void) mutex_unlock(&host_list->hosts_mutex);
-}
-
-/*
- * explicity remove a host from the host list
- * also update the configured array
- * called in rdc_sync, just before exiting a thread.
- */
-void
-remove_from_hostlist(char *host)
-{
- int i, k;
- char *exhost;
-
- /* why bother? */
- if ((!host) || (host[0] == '\0'))
- return;
-
- (void) mutex_lock(&host_list->hosts_mutex);
- for (i = 0; i < host_list->numhosts; i++) {
- if (strcmp(host, host_list->hosts[i]) == 0) { /* found it */
- exhost = host_list->hosts[i];
- if (exhost) {
- free(exhost);
- exhost = NULL;
- }
- k = i;
- while (k < host_list->numhosts) {
- host_list->hosts[k] = k < host_list->numhosts - 1 ?
- host_list->hosts[k+1] : NULL;
- k++;
- }
- host_list->numhosts--;
- bcopy(&host_list->configured[i+1],
- &host_list->configured[i],
- (MAXHOSTS - i + 1) * sizeof (int));
- host_list->configured[MAXHOSTS - 1] = 0;
- }
-
- }
- (void) mutex_unlock(&host_list->hosts_mutex);
-}
-/*
- * Check to see if this host isn't in our list, so needs a new rdcsyncd proc
- */
-int
-isnewhost(char *host)
-{
- int i;
- int new;
-
- if (self_check(host)) {
- return (0);
- }
-
- (void) mutex_lock(&host_list->hosts_mutex);
- new = 1;
- for (i = 0; i < MAXHOSTS; i++) {
- if (host_list->configured[i] == 0) {
- host_list->configured[i] = 1;
- host_list->hosts[i] = strdup(host);
- host_list->numhosts++;
- break;
- }
- if (strcmp(host, host_list->hosts[i]) == 0) {
- new = 0;
- break;
- }
- }
- (void) mutex_unlock(&host_list->hosts_mutex);
- if (i == MAXHOSTS)
- new = 0;
- return (new);
-}
-
-
-/*
- * Look for a matching volume name in our remembered list.
- */
-int
-volume_match(char *buf, char **volume_list, int volumes)
-{
- int i;
- char *vol;
-
- for (i = 0; i < volumes; i++) {
- vol = volume_list[i];
- if (strcmp(buf, vol) == 0) {
- return (1);
- }
- }
- return (0);
-}
-
-
-/*
- * A sync has completed to a group. We can only update the ndr_ii entries
- * if all the members of the group have completed their syncs OK.
- * It would be bad to allow some members of the group to have PIT Copy snapshots
- * taken and others not, as they need to be consistent.
- */
-void
-group_complete(char *group)
-{
- char **volumes = NULL;
- spcs_s_info_t ustatus;
- rdc_config_t parms = { 0 };
- char buf[CFG_MAX_BUF];
- char key[CFG_MAX_KEY];
- CFGFILE *cfg = NULL;
- int i;
- int setnumber;
- int found;
- int replicating = 0;
- char primary[NSC_MAXPATH];
- char secondary[NSC_MAXPATH];
- char phost[MAX_RDC_HOST_SIZE];
- char shost[MAX_RDC_HOST_SIZE];
- rdc_set_t *rdc_set;
- int sev;
- char *local_file;
- int size;
-
- ustatus = spcs_s_ucreate();
-
- size = sizeof (char *) * rdc_maxsets;
- volumes = malloc(size);
- if (volumes == NULL) {
- spcs_log("sndr", NULL,
- gettext("%s: unable to allocate %ld bytes"),
- program, size);
- rdc_warn(NULL,
- gettext("unable to allocate %ld bytes"), size);
- goto done;
- }
- bzero(volumes, size);
-
- /*
- * If all members of this group are replicating
- * set ii_ndr state to "update". Otherwise leave them alone.
- */
- LOCKCFG();
- if ((cfg = cfg_open(NULL)) == NULL) {
- spcs_log("sndr", NULL,
- gettext("%s: error opening lconfig"),
- program);
- rdc_warn(NULL, gettext("error opening config"));
- UNLOCKCFG();
- goto done;
- }
-
- if (!cfg_lock(cfg, CFG_RDLOCK)) {
- spcs_log("sndr", NULL,
- gettext("%s: error locking config"),
- program);
- rdc_warn(NULL, gettext("error locking config"));
- goto done;
- }
-
- found = 0;
-
- /* get all RM entries, with a matching group, that are replicating */
- for (i = 0; i < rdc_maxsets; i++) {
- setnumber = i + 1;
-
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.group", setnumber);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
- break;
-
- if (strcmp(buf, group) != 0)
- continue;
-
- /* Found a matching entry */
-
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.primary", setnumber);
- if (cfg_get_cstring(cfg, key, primary, sizeof (primary)) < 0)
- break;
- (void) strcpy(parms.rdc_set->primary.file, primary);
-
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.phost", setnumber);
- if (cfg_get_cstring(cfg, key, phost, sizeof (phost)) < 0)
- break;
- (void) strcpy(parms.rdc_set->primary.intf, phost);
-
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.secondary", setnumber);
- if (cfg_get_cstring(cfg, key, secondary,
- sizeof (secondary)) < 0)
- break;
- (void) strcpy(parms.rdc_set->secondary.file, secondary);
-
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.shost", setnumber);
- if (cfg_get_cstring(cfg, key, shost, sizeof (shost)) < 0)
- break;
- (void) strcpy(parms.rdc_set->secondary.intf, shost);
-
- parms.command = RDC_CMD_STATUS;
- if (RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, ustatus) < 0) {
- continue;
- }
-
- /* We found a matching set */
- found++;
-
- if (self_check(phost))
- local_file = primary;
- else
- local_file = secondary;
-
- rdc_set = &parms.rdc_set[0];
- if (!(rdc_set->flags & RDC_LOGGING) &&
- !(rdc_set->flags & RDC_SYNCING)) {
- volumes[replicating] = strdup(local_file);
- if (volumes[replicating] == NULL) {
- size = strlen(local_file);
- spcs_log("sndr", NULL,
- gettext("%s: unable to allocate %ld bytes"),
- program, size);
- rdc_warn(NULL,
- gettext("unable to allocate %ld bytes"),
- size);
- goto done;
- }
- /* We remember all replicating sets */
- replicating++;
- } else
- break; /* Not all replicating, so done */
- }
-
- if (found != replicating)
- goto done;
-
- /* All replicating, so update ndr_ii state fields */
-
- cfg_unlock(cfg);
-
- if (!cfg_lock(cfg, CFG_WRLOCK)) {
- spcs_log("sndr", NULL,
- gettext("%s: error locking lconfig"),
- program);
- rdc_warn(NULL, gettext("error locking config"));
- goto done;
- }
-
- /*
- * Search through the ndr_ii entries for entries
- * that match the saved secondary volume names.
- * Set state to "update".
- */
-
- for (i = 0; ; i++) {
- setnumber = i + 1;
-
- (void) snprintf(key, sizeof (key), "ndr_ii.set%d.secondary",
- setnumber);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
- break;
-
- if (!volume_match(buf, volumes, found)) {
- continue;
- }
-
- /* Got a matching entry */
-
- (void) snprintf(key, sizeof (key),
- "ndr_ii.set%d.state", setnumber);
- if ((cfg_put_cstring(cfg, key, UPDATE, strlen(UPDATE)) < 0) ||
- (cfg_commit(cfg) < 0)) {
- spcs_log("sndr", NULL,
- gettext("%s: unable to update \"%s\" "
- "in configuration storage: %s"),
- program, buf, cfg_error(&sev));
- rdc_warn(NULL,
- gettext("unable to update \"%s\" "
- "in configuration storage: %s"),
- buf, cfg_error(&sev));
- }
- }
-
-
-done:
- if (cfg) {
- cfg_close(cfg);
- UNLOCKCFG();
- }
- spcs_s_ufree(&ustatus);
- if (volumes) {
- for (i = 0; i < replicating; i++)
- free(volumes[i]);
- free(volumes);
- }
-}
-
-
-/*
- * Sync started to a member of a group.
- * If all members of the group are in ndr_ii state "update" then take an PIT
- * snapshot on all of them. This will provide a consistent point-in-time
- * copy until whatever syncs take place are all completed.
- */
-void
-group_start(char *group)
-{
- char **masters = NULL;
- char **shadows = NULL;
- char **bitmaps = NULL;
- char cmd[256];
- char buf[CFG_MAX_BUF];
- char key[CFG_MAX_KEY];
- CFGFILE *cfg = NULL;
- int i;
- int j;
- int setnumber;
- int found;
- int sndr_sets = 0;
- int update_needed = 0;
- int sev;
- char *ctag = NULL;
- int commit = 0;
- int size;
-
- size = sizeof (char *) * rdc_maxsets;
- masters = malloc(size);
- if (masters == NULL) {
- spcs_log("sndr", NULL,
- gettext("%s: unable to allocate %ld bytes"),
- program, size);
- rdc_warn(NULL,
- gettext("unable to allocate %ld bytes"), size);
- goto done;
- }
- bzero(masters, size);
- shadows = malloc(size);
- if (shadows == NULL) {
- spcs_log("sndr", NULL,
- gettext("%s: unable to allocate %ld bytes"),
- program, size);
- rdc_warn(NULL,
- gettext("unable to allocate %ld bytes"), size);
- goto done;
- }
- bzero(shadows, size);
- bitmaps = malloc(size);
- if (bitmaps == NULL) {
- spcs_log("sndr", NULL,
- gettext("%s: unable to allocate %ld bytes"),
- program, size);
- rdc_warn(NULL,
- gettext("unable to allocate %ld bytes"), size);
- goto done;
- }
- bzero(bitmaps, size);
-
- LOCKCFG();
- if ((cfg = cfg_open(NULL)) == NULL) {
- spcs_log("sndr", NULL,
- gettext("%s: error opening config"),
- program);
- rdc_warn(NULL,
- gettext("error opening config"));
- UNLOCKCFG();
- goto done;
- }
-
- if (!cfg_lock(cfg, CFG_WRLOCK)) {
- spcs_log("sndr", NULL,
- gettext("%s: error locking config"),
- program);
- rdc_warn(NULL, gettext("error locking config"));
- goto done;
- }
-
- /* Now get all Remote Mirror entries with a matching group */
- for (i = 0; i < rdc_maxsets; i++) {
- setnumber = i + 1;
-
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.group", setnumber);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
- break;
-
- if (strcmp(buf, group) != 0)
- continue;
-
- /* Found a matching entry */
-
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.phost", setnumber);
- if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0)
- break;
-
- if (self_check(buf)) {
- (void) snprintf(key, sizeof (key), "sndr.set%d.primary",
- setnumber);
- } else {
- (void) snprintf(key, sizeof (key),
- "sndr.set%d.secondary", setnumber);
- }
- if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0)
- break;
-
- masters[sndr_sets] = strdup(buf);
- if (masters[sndr_sets] == NULL) {
- size = strlen(buf);
- spcs_log("sndr", NULL,
- gettext("%s: unable to allocate %ld bytes"),
- program, size);
- rdc_warn(NULL,
- gettext("unable to allocate %ld bytes"), size);
- goto done;
- }
- sndr_sets++;
-
- if (ctag == NULL && clustered) {
- /* Get cluster tag of matching entry */
-
- (void) snprintf(key, sizeof (key), "sndr.set%d.cnode",
- setnumber);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) >= 0)
- ctag = strdup(buf);
- }
- }
-
- /*
- * Search through the ndr_ii entries for entries
- * that match the saved local volume names and are in "update" state.
- */
-
- update_needed = 0;
-
- for (i = 0; ; i++) {
- setnumber = i + 1;
-
- (void) snprintf(key, sizeof (key), "ndr_ii.set%d.secondary",
- setnumber);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
- break;
-
- if (!volume_match(buf, masters, sndr_sets))
- continue;
-
- /* Got a matching entry */
-
- (void) snprintf(key, sizeof (key), "ndr_ii.set%d.shadow",
- setnumber);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
- break;
- shadows[update_needed] = strdup(buf);
- if (shadows[update_needed] == NULL) {
- size = strlen(buf);
- spcs_log("sndr", NULL,
- gettext("%s: unable to allocate %ld bytes"),
- program, size);
- rdc_warn(NULL,
- gettext("unable to allocate %ld bytes"), size);
- goto done;
- }
-
- (void) snprintf(key, sizeof (key), "ndr_ii.set%d.bitmap",
- setnumber);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) {
- break;
- }
- bitmaps[update_needed] = strdup(buf);
- if (bitmaps[update_needed] == NULL) {
- size = strlen(buf);
- spcs_log("sndr", NULL,
- gettext("%s: unable to allocate %ld bytes"),
- program, size);
- rdc_warn(NULL,
- gettext("unable to allocate %ld bytes"), size);
- goto done;
- }
-
- (void) snprintf(key, sizeof (key), "ndr_ii.set%d.state",
- setnumber);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) {
- break;
- }
- if (strcmp(buf, UPDATE) != 0) {
- break;
- }
-
- update_needed++;
- }
-
- if (update_needed != sndr_sets) {
-#ifdef DEBUG
- spcs_log("sndr", NULL,
- gettext("%s: group sync: no Point-in-Time Copy snapshot "
- "for %s"), program, group);
-#endif
- goto done;
- }
-
- /* All RM sets in the group have an ndr_ii entry in "update" state */
-
- /* Issue PIT Copy snapshot commands for all sets in the group */
- for (j = 0; j < sndr_sets; j++) {
- found = 0;
-
- /* get ii entries until a match is found */
- for (i = 0; ; i++) {
- setnumber = i + 1;
-
- (void) snprintf(key, sizeof (key), "ii.set%d.shadow",
- setnumber);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
- break;
- if (strcmp(buf, shadows[j]) != 0)
- continue;
-
- /* Matching shadow found, so ii already enabled */
- found = 1;
- break;
- }
-
- if (commit)
- if (cfg_commit(cfg) < 0)
- rdc_warn(NULL, gettext("commit config error"));
- cfg_close(cfg);
-
- if (found) {
- (void) sprintf(cmd, "%s -u s %s", IIADM, shadows[j]);
- } else {
- if (ctag) {
- (void) sprintf(cmd, "%s -C %s -e dep %s %s %s",
- IIADM, ctag, masters[j], shadows[j],
- bitmaps[j]);
- free(ctag);
- ctag = NULL;
- } else
- (void) sprintf(cmd, "%s -e dep %s %s %s", IIADM,
- masters[j], shadows[j], bitmaps[j]);
- }
-
- if (system(cmd) != 0) {
- spcs_log("sndr", NULL,
- gettext("%s: group sync: Point-in-Time Copy"
- " snapshot failed for %s"),
- program, masters[j]);
-
- goto done;
- }
-
- if ((cfg = cfg_open(NULL)) == NULL) {
- spcs_log("sndr", NULL,
- gettext("%s: error opening config"),
- program);
- rdc_warn(NULL,
- gettext("error opening config"));
- goto done;
- }
- if (!cfg_lock(cfg, CFG_WRLOCK)) {
- spcs_log("sndr", NULL,
- gettext("%s: error locking config"),
- program);
- rdc_warn(NULL, gettext("error locking config"));
- goto done;
- }
- commit = 0;
-
- /* PIT enable or update was fine, so update the ndr_ii entry */
-
- /* get ndr_ii entries until a match is found */
- for (i = 0; ; i++) {
- setnumber = i + 1;
-
- (void) snprintf(key, sizeof (key),
- "ndr_ii.set%d.shadow", setnumber);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
- break;
- if (strcmp(buf, shadows[j]) != 0)
- continue;
-
- /* Found the matching entry */
-
- (void) snprintf(key, sizeof (key), "ndr_ii.set%d.state",
- setnumber);
- if (cfg_put_cstring(cfg, key, NOUPDATE,
- strlen(NOUPDATE)) < 0) {
- spcs_log("sndr", NULL,
- gettext("%s: unable to update \"%s\" "
- "in configuration storage: %s"),
- program, buf, cfg_error(&sev));
- rdc_warn(NULL,
- gettext("unable to update \"%s\" "
- "in configuration storage: %s"),
- buf, cfg_error(&sev));
- } else
- commit = 1;
- break;
- }
- }
-
- if (commit)
- if (cfg_commit(cfg) < 0)
- rdc_warn(NULL, gettext("commit config error"));
-
- spcs_log("sndr", NULL,
- gettext("%s: group sync: Point-in-Time Copy snapshots completed "
- "for %s"), program, group);
-
-done:
- if (ctag)
- free(ctag);
-
- if (cfg) {
- cfg_close(cfg);
- UNLOCKCFG();
- }
-
- if (masters) {
- for (i = 0; i < sndr_sets; i++) {
- if (masters[i])
- free(masters[i]);
- }
- free(masters);
- }
-
- if (shadows) {
- for (i = 0; i < update_needed; i++) {
- if (shadows[i])
- free(shadows[i]);
- }
- free(shadows);
- }
-
- if (bitmaps) {
- for (i = 0; i < update_needed; i++) {
- if (bitmaps[i])
- free(bitmaps[i]);
- }
- free(bitmaps);
- }
-}
diff --git a/usr/src/cmd/avs/sdbc/Makefile b/usr/src/cmd/avs/sdbc/Makefile
deleted file mode 100644
index 97cc48f5a1..0000000000
--- a/usr/src/cmd/avs/sdbc/Makefile
+++ /dev/null
@@ -1,108 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#
-
-# must be before include of Makefile.cmd
-DYNPROG = scmadm \
- sd_stats \
- sd_diag
-
-include ../../Makefile.cmd
-include ../Makefile.com
-
-SUBDIRS= etc
-
-PROG = $(DYNPROG)
-
-scmadm := POBJS = scmadm.o sdbc_ioctl.o
-sd_stats := POBJS = sd_stats.o sd_trace.o sdbc_ioctl.o rdc_ioctl.o
-sd_diag := POBJS = sd_diag.o
-sdbc_dynmem := POBJS = sdbc_dynmem.o
-
-OBJS= scmadm.o\
- sdbc_ioctl.o\
- sd_diag.o\
- sd_stats.o\
- sd_trace.o\
- sdbc_dynmem.o
-
-XTRA_OBJS= \
- rdc_ioctl.o
-
-SRCS= $(OBJS:%.o=%.c)
-
-POFILE = scmadm.po
-
-scmadm := LDLIBS += -lnsctl -lunistat -ldscfg
-sd_stats := LDLIBS += -lunistat -lcurses
-sd_diag := LDLIBS += -lnsctl
-sdbc_dynmem := LDLIBS += -lkstat
-
-CFLAGS += $(CCVERBOSE) -D_SCM_ -D_SD_8K_BLKSIZE -D_SYSCALL32
-CPPFLAGS += -DNSC_MULTI_TERABYTE
-LINTFLAGS += -Xa -n -s -x -m -u -Dlint -errhdr=%user
-LINTFLAGS += -D_SCM_ -D_SD_8K_BLKSIZE -D_SYSCALL32
-LINTFLAGS += -erroff=E_SEC_PRINTF_VAR_FMT
-LINTFLAGS += -erroff=E_SEC_SPRINTF_UNBOUNDED_COPY
-LINTFLAGS += -erroff=E_SEC_SCANF_UNBOUNDED_COPY
-LINTFLAGS += -erroff=E_SEC_FORBIDDEN_WARN_ASCFTIME
-LINTFLAGS += -DDEBUG
-CERRWARN += -_gcc=-Wno-uninitialized
-ROOTLINK = $(ROOTUSRSBIN)/scmadm
-
-all := TARGET= all
-install := TARGET= install
-clean := TARGET= clean
-clobber := TARGET= clobber
-lint := TARGET= lint
-
-.KEEP_STATE:
-
-.PARALLEL: $(OBJS) $(XTRA_OBJS)
-
-all: $(SUBDIRS) $(PROG) $(POFILE)
-
-install: $(SUBDIRS) all $(ROOTPROG) $(ROOTLINK)
-
-lint: $(SUBDIRS) lint_SRCS
-
-clean: $(SUBDIRS)
- $(RM) *.o
-
-rdc_ioctl.o: ../rdc/rdc_ioctl.c
- $(COMPILE.c) ../rdc/rdc_ioctl.c
-
-$(PROG): $$(POBJS)
- $(LINK.c) $(POBJS) -o $@ $(LDLIBS)
- $(POST_PROCESS)
-
-$(SUBDIRS): FRC
- @cd $@; pwd; $(MAKE) $(TARGET)
-
-$(ROOTLINK): $(ROOTUSRSBIN) $(ROOTBIN)/scmadm
- -$(RM) $@; $(LN) $(ROOTBIN)/scmadm $@
-
-include ../../Makefile.targ
-
-FRC:
diff --git a/usr/src/cmd/avs/sdbc/etc/Makefile b/usr/src/cmd/avs/sdbc/etc/Makefile
deleted file mode 100644
index 0abbf70293..0000000000
--- a/usr/src/cmd/avs/sdbc/etc/Makefile
+++ /dev/null
@@ -1,62 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# cmd/ns/sdbc/etc/Makefile
-
-include ../../../Makefile.cmd
-include ../../Makefile.com
-
-INITPROGS = scm
-BINPROGS = dscfg_reconfigure.cluster
-SHFILES = $(INITPROGS) $(BINPROGS)
-ROOTINIT_D = $(ROOTETC)/init.d
-
-ROOTBINPROGS= $(BINPROGS:%=$(ROOTBIN)/%)
-ROOTINITPROGS= $(INITPROGS:%=$(ROOTINIT_D)/%)
-
-# scm is mode 744, dscfg_reconfigure.cluster is mode 555
-$(ROOTINITPROGS) := FILEMODE= 744
-$(ROOTBINPROGS) := FILEMODE= 555
-
-.KEEP_STATE:
-
-all: $(SHFILES) $(INITPROGS) $(BINPROGS)
-
-install: $(ROOTBINPROGS) $(ROOTINITPROGS) $(ROOTLIBSVCMETHOD) $(CLUSTERSBINDIR)
- -$(RM) $(ROOTLIBSVCMETHOD)/svc-scm
- -$(RM) $(CLUSTERSBINDIR)/dscfg_reconfigure
- $(LN) $(ROOTINIT_D)/scm $(ROOTLIBSVCMETHOD)/svc-scm
- $(LN) $(ROOTBIN)/$(BINPROGS) $(CLUSTERSBINDIR)/dscfg_reconfigure
-
-$(ROOTINIT_D)/%: %
- $(INS.file)
-
-clean:
- $(RM) $(SHFILES)
-
-clobber: clean
- $(RM) $(ROOTBINPROGS) $(ROOTINITPROGS)
-
-lint:
-
-FRC:
diff --git a/usr/src/cmd/avs/sdbc/etc/dscfg_reconfigure.cluster.sh b/usr/src/cmd/avs/sdbc/etc/dscfg_reconfigure.cluster.sh
deleted file mode 100644
index 5dfb40768b..0000000000
--- a/usr/src/cmd/avs/sdbc/etc/dscfg_reconfigure.cluster.sh
+++ /dev/null
@@ -1,425 +0,0 @@
-#!/usr/bin/ksh
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# NWS DataServices within SunCluster reconfiguration script.
-#
-# Description:
-#
-# This script is called from /usr/cluster/lib/sc/run_reserve at
-# appropriate times to start and stop the NWS DataServices as SunCluster
-# disk device groups are brought online or taken offline.
-#
-# SNDR configuration requires that a resource group to be configured.
-# 1. The resource group name should be same as device group name with -stor-rg
-# added. e.g. if device group name is abc-dg then resource group name
-# would be abc-dg-stor-rg.
-# 2. It should have 2 resources in it, unless one of the resource types is the
-# SUNW.GeoCtlAVS. One of type SUNW.LogicalHostname and either SUNW.HAStorage
-# or SUNW.HAStoragePlus types. Resource type versioning is ignored.
-# HAStorage type resource, should have ServicePaths property set to
-# device group name. HAStoragePlus type resource, should have either the
-# FilesystemMountPoints pointing to a files system associated with the
-# device group name, or GlobalDevicePaths property set to device group name.
-# LogicalHostname type resource should have a failoverIP address in it and
-# it will be used by SNDR to communicate with the secondary side.
-#
-# As SNDR requires that the LogicalHost (failover) IP address which is a
-# part of resource group for SNDR, to be hosted on the same node where the
-# device group is, it tries to move the resource group also alongwith the
-# device group, in become_primary case of run_reserve script. While
-# in primary_to_secondary case, it will try to kill the switchover function
-# if it is still running in background, after stopping NWS data services.
-#
-# Usage:
-#
-# /usr/cluster/sbin/dscfg_reconfigure { start | stop } diskgroup
-#
-# Configuration:
-#
-# Scripts to be run should have been symlinked into $NWS_START_DIR and
-# $NWS_STOP_DIR. Note that the scripts are processed in lexical order,
-# and that unlike /etc/rc?.d/ there is no leading S or K character.
-#
-# Exit status:
-#
-# 0 - success
-# 1 - error
-#
-
-#
-# Global variables
-#
-
-# this program
-typeset -r ARGV0=$(basename $0)
-
-# directory full of start scripts
-typeset -r NWS_START_DIR=/usr/cluster/lib/dscfg/start
-
-# directory full of stop scripts
-typeset -r NWS_STOP_DIR=/usr/cluster/lib/dscfg/stop
-
-# the syslog facility to use.
-# - conceptually this should be based on the output of
-# "scha_cluster_get -O SYSLOG_FACILITY", but that won't work early
-# during boot.
-typeset -r SYSLOG_FACILITY=daemon
-
-PATH=$PATH:/usr/cluster/bin:/etc
-
-# Variables for retrying scswitch of Resource group for SNDR
-retry_num=12
-retry_interval=10
-rgname=
-rgstat=
-skip_resource=0
-count_LogicalHostname=0
-count_HAStoragePlus=0
-
-# Since the switchover of the resource group is called in background,
-# the stop action of the reconfig script will kill the background switchover
-# if it is running. Since we are stopping the NWS services on the node, there
-# is no need to switch the resource group, so it is killed.
-# The pid of the process is kept in file /var/run/scnws/$dg.pid.
-# Input: dg - device group
-# Output: Nothing, kills the process
-
-function kill_scswitch
-{
- dg=$1
- if [ -f /var/run/scnws/$dg.pid ]
- then
- for i in `cat /var/run/scnws/$dg.pid`
- do
- pid=$i
- kill -9 $pid
- done
- rm -f /var/run/scnws/$dg.pid
- fi
-}
-
-# Get the status of the resource group on this node, using scha commands.
-# Input: resource group - $1
-# Output: Status
-
-function get_rgstat
-{
- rg=$1
- rgstat=`scha_resourcegroup_get -O RG_STATE -G $rg`
-}
-
-# This function is called in background from do_scswitch function, to
-# switch the resource group to this node, which is becoming primary for
-# the diskgroup. If the status of resource group is Offline, it will use
-# scswitch command to switch the resource group to this node. If it has
-# become Online, cleanup pid file. If it is Pending, the resource group
-# is in the state of becoming online, so wait for sometime to become Online..
-# scswitch may fail, so the function retries $retry_num times, waiting for
-# $retry_interval seconds.
-# Input: resource group - $1, Diskgroup/Diskset - $2
-# Output: 0 - success, 1 - failure
-
-function switchfunc
-{
- rg=$1
- dg=$2
- how_many=0
- sleep 2
- while [ $how_many != $retry_num ]
- do
- get_rgstat $rg
- case "$rgstat" in
- "ONLINE")
- rm -f /var/run/scnws/$dg.pid
- return 0
- ;;
-
- "OFFLINE")
- logger -p ${SYSLOG_FACILITY}.notice \
- -t "NWS.[$ARGV0]" `gettext "scswitch of resource group"` "$rg"
-
- scswitch -z -g $rg -h $(hostname)
- retval=$?
- if [ $retval != 0 ]
- then
- sleep $retry_interval
- how_many=$(($how_many + 1))
- fi
- ;;
-
- "PENDING_ONLINE")
- logger -p ${SYSLOG_FACILITY}.notice \
- -t "NWS.[$ARGV0]" `gettext "pending online of resource group"` "$rg"
- sleep $retry_interval
- how_many=$(($how_many + 1))
- ;;
-
- *)
- logger -p ${SYSLOG_FACILITY}.notice \
- -t "NWS.[$ARGV0]" `gettext "Improper resource group status for Remote Mirror"` "$rgstat"
- rm -f /var/run/scnws/$dg.pid
- return 1
- ;;
- esac
- done
- logger -p ${SYSLOG_FACILITY}.err \
- -t "NWS.[$ARGV0]" "Did not switch resource group for Remote Mirror. System Administrator intervention required"
- rm -f /var/run/scnws/$dg.pid
- return 1
-}
-
-
-# This function calls switchfunc function in background, to switch the
-# resource group for SNDR. It validates the diskgroup/diskset is configured
-# for SNDR, checks if the resource group is in Managed state etc.
-# If it detects a mis-configuration, it will disable SNDR for the
-# device group being processed. This is to prevent cluster hangs and panics.
-#
-# The ServicePaths extension property of HAStorage type resource or the
-# GlobalDevicePaths extension property of HAStoragePlus, both of which
-# specify the device group, serve as a link or mapping to retrieve the
-# resource group associated with the SNDR configured device group.
-# Switchfunc is called in the background to avoid the deadlock situation arising
-# out of switchover of resource group from within device group switchover.
-#
-# In run_reserve context, we are doing the device group switchover, trying to
-# bring it online on the node. Device group is not completely switched online,
-# until the calling script run_reserve returns. In the process, we are calling
-# the associated SNDR resource group switchover using scswitch command.
-# Resource group switchover will trigger the switchover of device group also.
-#
-# If resource group switchover is called in foreground, before the device
-# group has become online, then it will result in switching the device group
-# again, resulting in deadlock. Resource group can not become online until
-# the device group is online and the device group can not become online until the
-# script returns, causing this circular dependency resulting in deadlock.
-#
-# Calling the resource group switch in background allows current run_reserve
-# script to return immediately, allowing device group to become online.
-# If the device group is already online on the node, then the resource group
-# does not cause the device group switchover again.
-#
-# Input: Device group dg - $1
-# Output: 0 - success
-# 1 - either dg not applicable for SNDR or error
-# 2 - SNDR mis-configuration
-
-function do_scswitch
-{
- dg=$1
-
- if [ ! -x /usr/cluster/bin/scha_resource_get \
- -o ! -x /usr/cluster/bin/scha_resourcegroup_get ]
- then
- return 1
- fi
-
-# hard coded rg name from dg
- rgname="$dg-stor-rg"
- scha_resourcegroup_get -O rg_description -G $rgname > /dev/null
- if [ $? != 0 ]
- then
-# There is no device group configured in cluster for SNDR with this cluster tag
- return 1
- fi
-
-# Check the state of resource group
-
- get_rgstat $rgname
- if [ -z "$rgstat" \
- -o "$rgstat" = "UNMANAGED" -o "$rgstat" = "ERROR_STOP_FAILED" ]
- then
- logger -p ${SYSLOG_FACILITY}.notice \
- -t "NWS.[$ARGV0]" \
- `gettext "Improper Remote Mirror resource group state"` "$rgstat"
- return 2
- fi
-
-# Check whether resources are of proper type and they are enabled
-
- rs_list=`scha_resourcegroup_get -O resource_list -G $rgname`
- if [ -z "$rs_list" ]
- then
- logger -p ${SYSLOG_FACILITY}.notice \
- -t "NWS.[$ARGV0]" \
- `gettext "No resources in Remote Mirror resource group <$rgname>"`
- return 2
- fi
- for rs in $rs_list
- do
- rs_type=`scha_resource_get -O type -R $rs -G $rgname | cut -d':' -f1`
- case "$rs_type" in
- SUNW.LogicalHostname)
- rs_enb=`scha_resource_get -O ON_OFF_SWITCH -R $rs -G $rgname`
- if [ "$rs_enb" = "ENABLED" ]
- then
- count_LogicalHostname=$(($count_LogicalHostname + 1))
- fi
- ;;
- SUNW.HAStoragePlus)
- rs_enb=`scha_resource_get -O ON_OFF_SWITCH -R $rs -G $rgname`
- if [ "$rs_enb" = "ENABLED" ]
- then
- count_HAStoragePlus=$(($count_HAStoragePlus + 1))
- fi
- ;;
- esac
- done
- if [ $count_LogicalHostname -lt 1 ]
- then
- logger -p ${SYSLOG_FACILITY}.notice \
- -t "NWS.[$ARGV0]" `gettext "Missing Enabled Logical Host in resource group <$rgname> for Remote Mirror"`
- return 2
- elif [ $count_LogicalHostname -gt 1 ]
- then
- logger -p ${SYSLOG_FACILITY}.notice \
- -t "NWS.[$ARGV0]" `gettext "Too Many Enabled Logical Host in resource group <$rgname> for Remote Mirror"`
- return 2
- fi
-
- if [ $count_HAStoragePlus -lt 1 ]
- then
- logger -p ${SYSLOG_FACILITY}.notice \
- -t "NWS.[$ARGV0]" `gettext "Missing Enabled HAStoragePlus in resource group <$rgname> for Remote Mirror"`
- return 2
- elif [ $count_HAStoragePlus -gt 1 ]
- then
- logger -p ${SYSLOG_FACILITY}.notice \
- -t "NWS.[$ARGV0]" `gettext "Too Many Enabled HAStoragePlus in resource group <$rgname> for Remote Mirror"`
- return 2
- fi
-
-# Invoke switchfunc to switch the resource group.
-
- switchfunc $rgname $dg &
- pid=$!
- mkdir -p /var/run/scnws/
- rm -f /var/run/scnws/$dg.pid
- echo $pid > /var/run/scnws/$dg.pid
-
- return 0
-}
-
-
-#
-# Functions
-#
-
-usage()
-{
- logger -p ${SYSLOG_FACILITY}.err \
- -t "NWS.[$ARGV0]" "usage: $ARGV0 { start | stop } diskgroup"
- exit 1
-}
-
-
-# Input: arg1) $NWS_START_DIR - location of NWS scripts
-# arg2) start / stop
-# arg3 ) device group - $2
-# arg4) sndr_ena / sndr_dis
-# Output: Nothing. Log error if seen
-
-process_dir()
-{
- typeset dir=$1
- typeset arg1=$2
- typeset dg=$3
- typeset arg2=$4
- typeset RDC=$dir/10rdc
-
- if [[ -d $dir ]]
- then
- for f in $dir/*
- do
- # process scripts in the directories in lexical order
- # note - no leading S or K unlike /etc/rc?.d/
-
- if [ -s $f ] && [ $arg2 != "sndr_dis" ]
- then
- # run script and pipe output through
- # logger into syslog
-
- /usr/bin/ksh $f $arg1 $dg 2>&1 |
- logger -p ${SYSLOG_FACILITY}.notice \
- -t "NWS.[${ARGV0}:$(basename $f)]"
- else
- # SNDR misconfigured - prevent start
- if [ -s $f ] && [ $f != $RDC ]
- then
- # run script and pipe output through
- # logger into syslog
- /usr/bin/ksh $f $arg1 $dg 2>&1 |
- logger -p ${SYSLOG_FACILITY}.notice \
- -t "NWS.[${ARGV0}:$(basename $f)]"
- fi
- fi
- done
- else
- logger -p ${SYSLOG_FACILITY}.err \
- -t "NWS.[$ARGV0]" "no directory: $dir"
- fi
-}
-
-
-#
-# main
-#
-
-if [ $# -ne 2 ]
-then
- usage
- # not reached
-fi
-
-
-case "$1" in
-start)
- logger -p ${SYSLOG_FACILITY}.notice -t "NWS.[$ARGV0]" "starting: $ARGV0 $*"
- do_scswitch $2
- retval=$?
- if [ $retval == 2 ]
- then
- logger -p ${SYSLOG_FACILITY}.err \
- -t "NWS.[$ARGV0]" "**FATAL ERROR** Remote Mirror is mis-configured and DISABLED for devicegroup <"$2"> "
- # Disable SNDR
- process_dir $NWS_START_DIR start "$2" sndr_dis
- else
- process_dir $NWS_START_DIR start "$2" sndr_ena
- fi
- ;;
-stop)
- logger -p ${SYSLOG_FACILITY}.notice -t "NWS.[$ARGV0]" "stopping: $ARGV0 $*"
- process_dir $NWS_STOP_DIR stop "$2" sndr_ena
- kill_scswitch $2
- ;;
-
-*)
- usage
- # not reached
- ;;
-esac
-
-logger -p ${SYSLOG_FACILITY}.notice -t "NWS.[$ARGV0]" "completed: $ARGV0 $*"
-
-exit 0
diff --git a/usr/src/cmd/avs/sdbc/etc/scm.sh b/usr/src/cmd/avs/sdbc/etc/scm.sh
deleted file mode 100644
index f5ce4b1a78..0000000000
--- a/usr/src/cmd/avs/sdbc/etc/scm.sh
+++ /dev/null
@@ -1,348 +0,0 @@
-#!/bin/ksh
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#######################################################################
-#
-# This file contains system setup requirements for scm.
-#
-# For systems before Solaris 10 it should be located in /etc/init.d
-# directory with the following links:
-#
-# ln /etc/init.d/scm /etc/rc0.d/K84scm
-# ln /etc/init.d/scm /etc/rc2.d/S002scm
-#
-# For Solaris 10 or later systems this script is run as part of SVC by
-# svc.startd and should be located in /lib/svc/method
-#
-#USAGE="Usage: $0 { start | stop }
-#
-#######################################################################
-
-SVCS=/usr/bin/svcs
-DSCFG_DEPEND_NOCHK="/tmp/.dscfgadm_pid"
-OS_MINOR=`/usr/bin/uname -r | /usr/bin/cut -d '.' -f2`
-
-. /lib/svc/share/smf_include.sh
-
-# Make sure prior SMF dependents are not 'online'
-# $1 = name of SMF service to validate dependents
-#
-do_smf_depends ()
-{
- times=0
- count=1
-
- if [ $OS_MINOR -ge 11 ]
- then
- return 0
- elif [ -f $DSCFG_DEPEND_NOCHK ]
- then
- for pid in `pgrep dscfgadm`
- do
- if [ `grep -c $pid $DSCFG_DEPEND_NOCHK` -gt 0 ]
- then
- return 0
- fi
- done
- elif [ `ps -ef | grep preremove | grep -c SUNWscmu` -gt 0 ]
- then
- return 0
-
- fi
-
- while [ $count -ne 0 ]
- do
- count=`$SVCS -o STATE -D $1 2>>/dev/null | grep "^online" | wc -l`
- if [ $count -ne 0 ]
- then
- # Output banner after waiting first 5 seconds
- #
- if [ $times -eq 1 ]
- then
- echo "Waiting for $1 dependents to be 'offline'"
- $SVCS -D $1 2>>/dev/null | grep "^online"
- fi
-
- # Has it been longer then 5 minutes? (60 * 5 secs.)
- #
- if [ $times -eq 60 ]
- then
- echo "Error: Failed waiting for $1 dependents to be 'offline'"
- $SVCS -D $1 2>>/dev/null | grep "^online"
- exit $SMF_EXIT_ERR_FATAL
- fi
-
- # Now sleep, giving other services time to stop
- #
- sleep 5
- times=`expr $times + 1`
- fi
- done
- return 0
-}
-
-set_system_type()
-{
- CLINFO=/usr/sbin/clinfo
- ESMSBIN=/usr/sbin
- SCMBIN=/usr/sbin
- ESMSCMLIB=/usr/lib
- SCMLIB=/usr/lib
- DSCFG_LOCKDB=/etc/dscfg_lockdb
-}
-
-do_stopsdbc ()
-{
- if [ ! -r /dev/sdbc ]
- then
- return
- fi
-
- ${SCMBIN}/scmadm -d
- if [ $? -ne 0 ] ; then
- # If the disable failed that means we have pinned data.
- echo "Cache Not Deconfigured"
- fi
-}
-
-do_stopnskernd ()
-{
- ps -e | grep -w nskernd > /dev/null 2>&1
- if [ $? -eq 0 ] ; then
- # make sure that all data services are unloaded before stopping
- # nskernd - cannot stop nskernd when its threads could be in use
- # Note: sv is unloadable, but its threadset is shutdown in the
- # final close(9e) call.
- stop=1
- for m in ste rdc rdcsrv ii sdbc ; do
- mid=`/usr/sbin/modinfo | grep -w $m | awk '{print $1}' -`
- if [ -z "$mid" ] ; then
- continue # not loaded
- fi
- /usr/sbin/modunload -i $mid > /dev/null 2>&1
- if [ $? -ne 0 ] ; then
- stop=0
- break
- fi
- done
-
- # kill nskernd if we can
- pid=`ps -e | grep -w nskernd | sed -e 's/^ *//' -e 's/ .*//'`
- if [ $stop -eq 1 ] ; then
- if [ -n "$pid" ] ; then
- kill -15 $pid
- fi
- fi
- fi
-
- if [ -r /dev/ncall -a -x $ESMSCMLIB/ncalladm ]
- then
- $ESMSCMLIB/ncalladm -d
- fi
-}
-
-do_stopdscfglockd ()
-{
- pid=`ps -e | grep -w dscfgloc | sed -e 's/^ *//' -e 's/ .*//'`
- if [ -n "$pid" ] ; then
- kill -15 $pid
- fi
-}
-
-do_stop ()
-{
- do_smf_depends "system/nws_scm"
- do_stopsdbc
- do_stopnskernd
- do_stopdscfglockd
-}
-
-do_nskernd ()
-{
- if [ -x $ESMSCMLIB/ncalladm ]
- then
- $ESMSCMLIB/ncalladm -e
- fi
-
- ps -e | grep -w nskernd > /dev/null 2>&1
- if [ $? -ne 0 ] ; then
- ${SCMLIB}/nskernd
- if [ $? -ne 0 ] ; then
- echo "Error: Unable to start nskernd"
- exit $SMF_EXIT_ERR_FATAL
- fi
- fi
-}
-
-do_dscfglockd ()
-{
- ps -e | grep -w dscfgloc > /dev/null 2>&1
- if [ $? -ne 0 ]
- then
- rm -f /var/tmp/.cfglockd.pid
- else
- # dscfglockd already running
- return
- fi
-
- if ${CLINFO}
- then
- #
- # create or update the dscfg_lockdb file
- #
-
- # create clean tmpnodelist
- NODELIST=/tmp/$$.dscfg_nodelist
- rm -f $NODELIST >/dev/null 2>&1
- touch $NODELIST
-
- if [ -x /usr/cluster/bin/scstat ]
- then
- # get valid names in cluster
- /usr/cluster/bin/scstat -n | grep node: | \
- awk '{print $3}' >> $NODELIST
- if [ ! -f $DSCFG_LOCKDB ]
- then
- printf "In clustered environment.\n"
- printf "creating per node dscfg_lockdb database"
- printf " with following nodenames:\n"
- cat $NODELIST
- cp $NODELIST $DSCFG_LOCKDB
- else
- # check if there are any changes
- diff $NODELIST $DSCFG_LOCKDB > /dev/null
- if [ $? != 0 ]
- then
- printf "The cluster node names have "
- printf "changed. Updating dscfg_lockdb "
- printf "database.\n"
- printf "Previous node names:\n"
- cat $DSCFG_LOCKDB
- printf "New node names:\n"
- cat $NODELIST
- rm -f $DSCFG_LOCKDB
- cp $NODELIST $DSCFG_LOCKDB
- fi
- fi
- else
- # we're in a cluster, but scstat is not available
- printf "In clustered environment.\n"
- printf "Required configuration file, $DSCFG_LOCKDB\n"
- printf "was not properly populated with the cluster "
- printf "nodenames.\nThis file needs to be manually"
- printf "updated with the cluster\nnodenames before "
- printf "reboot. Refer to Sun Storage Availability\n"
- printf "Suite Installation Guide for details.\n"
- fi
-
- # clustered start of dscfglockd
- if [ -f $DSCFG_LOCKDB ]
- then
- printf "Starting dscfglockd\n"
- ${SCMLIB}/dscfglockd -f $DSCFG_LOCKDB
- else
- printf "WARNING: Mis-Configuration of Availability "
- printf "Suite for Sun Cluster\n"
- printf "WARNING: Can't find configuration file for "
- printf "dscfglockd\n"
- fi
-
- rm -f $NODELIST
- fi
-
-}
-
-do_sdbc ()
-{
- ${SCMBIN}/scmadm -e
-}
-
-
-do_start ()
-{
- # do nothing if we do not have a dscfg
- if [ ! -f /etc/dscfg_local ]
- then
- echo "Cannot find Availability Suite configuration location"
- exit $SMF_EXIT_ERR_NOSMF
- fi
-
- #
- # Ordering:
- # dscfglockd -- locking must be present before any dscfg access
- # nskernd -- starts infrastructure (nskernd, ncall).
- # sdbc -- start the cache itself
- #
- do_dscfglockd
- do_nskernd
- do_sdbc
-}
-
-
-do_usage ()
-{
- echo "Usage: $0"
- echo " start"
- echo " stop"
- exit 1
-}
-
-set_system_type
-
-USED=0
-ACTION=
-CLUSTERTAG=
-
-case $# in
-'0')
- do_usage
- ;;
-'1')
- ACTION=$1
- USED=1
- ;;
-'2')
- ACTION=$1
- CLUSTERTAG="$2"
- USED=1
- exit 0
- ;;
-'*')
- do_usage
- ;;
-esac
-
-if [ $USED = 0 ] ; then
- do_usage
-fi
-
-if [ $ACTION = "start" ] ; then
- do_start
-elif [ $ACTION = "stop" ] ; then
- do_stop
-else
- do_usage
-fi
-
-exit $SMF_EXIT_OK
diff --git a/usr/src/cmd/avs/sdbc/scmadm.c b/usr/src/cmd/avs/sdbc/scmadm.c
deleted file mode 100644
index f0a28bbf81..0000000000
--- a/usr/src/cmd/avs/sdbc/scmadm.c
+++ /dev/null
@@ -1,2156 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * Utility for cache configuration
- */
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <strings.h>
-#include <locale.h>
-#include <langinfo.h>
-#include <libintl.h>
-#include <time.h>
-#include <sys/nsctl/sd_bcache.h>
-#include <sys/wait.h>
-#include <errno.h>
-#include <signal.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <stropts.h>
-#include <ctype.h>
-#include <libgen.h>
-
-#include <sys/nsctl/sdbc_ioctl.h>
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_u.h>
-#include <sys/unistat/spcs_errors.h>
-#include <nsctl.h>
-
-#include <sys/nsctl/cfg.h>
-#define STATS_PATH "/usr/bin/sd_stats"
-
-#define _SD_FNAME /* bring in function names from sd_trace.h */
-#include <sys/nsctl/sd_trace.h>
-#include <sys/syslog.h>
-
-/*
- * Since we no longer support nvram cards, the hints wrthru and nowrthru no
- * longer serve any purpose, and the system will always be in wrthru mode.
- * WRTHRU_HINTS, if defined still allows the setting and reporting of write
- * hints. This is defined by default on DEBUG builds.
- */
-#ifdef DEBUG
-#define WRTHRU_HINTS
-#endif
-
-static int sdbc_max_devices = 0;
-
-static char alert_file[200] = "/dev/console";
-
-/* Variables used to set up paramater block passed to kernel */
-static _sd_cache_param_t user_level_conf;
-static int myid;
-
-static int nodes_configured = 0;
-static int minidsp = 0; /* Is it a sp10 */
-static int forced_wrthru = -1; /* 0 clear, 1 set,-1 as is */
-static int no_forced_wrthru = -1;
-static short node_defined[MAX_SD_NODES];
-static short nodes_conf[MAX_SD_NODES];
-
-#define USAGELEN 1024
-char stats_usage[USAGELEN+128];
-char scmadmUsage[USAGELEN];
-
-static caddr_t progname;
-
-
-/*
- * Functions exported for fwcadm.
- */
-void enable_sdbc(void);
-void disable_sdbc(void);
-void sdbc_set_maxdev();
-
-static void buildusage(char *);
-
-void print_all_options(void);
-void get_cd_all(void);
-int toggle_flush(void);
-static void sd_gather_alert_dumps();
-static int get_cd(char *);
-static int get_hint(char *, int *, int *);
-static void check_and_set_mirrors(int, int);
-static void print_hint(const uint_t, const int);
-static char *get_device_name(char *arg);
-static void get_version();
-
-extern struct tm *localtime_r(const time_t *, struct tm *);
-
-#define PRINT_CACHE_SZ_ERR(sz) {\
- (void) fprintf(stderr, gettext("\n%s: desired cache size (%d) "\
- "set to system max (%d)\n"), \
- progname, (sz), MAX_CACHE_SIZE); \
- spcs_log("sdbc", NULL, \
- gettext("desired cache size (%d) "\
- "set to system max (%d)\n"), \
- (sz), MAX_CACHE_SIZE); \
-}
-
-void
-sdbc_report_error(spcs_s_info_t *ustatus)
-{
- if (*ustatus != NULL) {
- spcs_s_report(*ustatus, stderr);
- spcs_s_ufree(ustatus);
- } else
- (void) fprintf(stderr, "%s\n", strerror(errno));
-}
-
-
-/*
- * Return the per-cd hints for a cd.
- *
- * Since the global (no)wrthru and NSC_NOCACHE hints take precedence
- * over the per-cd hints, get them as well and OR the whole lot
- * together.
- */
-static int
-get_cd_hint(const int cd)
-{
- spcs_s_info_t ustats;
- int nodehint, cdhint;
-
- nodehint = SDBC_IOCTL(SDBC_GET_NODE_HINT, 0, 0, 0, 0, 0, &ustats);
- if (nodehint == SPCS_S_ERROR) {
- (void) fprintf(stderr,
- gettext("%s: get system options failed\n"), progname);
- sdbc_report_error(&ustats);
- exit(1);
- }
-
- cdhint = SDBC_IOCTL(SDBC_GET_CD_HINT, cd, 0, 0, 0, 0, &ustats);
- if (cdhint == SPCS_S_ERROR) {
- (void) fprintf(stderr,
- gettext("%s: get cd(%d) hint failed\n"), progname, cd);
- sdbc_report_error(&ustats);
- exit(1);
- }
-
-#ifdef WRTHRU_HINTS
- nodehint &= (NSC_FORCED_WRTHRU | NSC_NO_FORCED_WRTHRU | NSC_NOCACHE);
-#else
- nodehint &= (NSC_NOCACHE);
-#endif
- if (nodehint) {
- /* set the top bit to mark it as a system override */
- nodehint |= 0x80000000;
- }
-
- return (cdhint | nodehint);
-}
-
-
-
-/*
- * Check for a config.
- *
- * If no suitable config can be found, install the default config.
- *
- * Calling state:
- * libcfg locked (mode describes type of lock)
- */
-static void
-convert_config(CFGFILE *cfg, CFGLOCK mode)
-{
- char buf[CFG_MAX_BUF];
- char *default_cfg = "128 64";
-
-retry:
- if (cfg_get_cstring(cfg, "scm.set1", buf, sizeof (buf)) >= 0) {
- /* config exists, return */
- return;
- }
-
- cfg_rewind(cfg, CFG_SEC_CONF);
-
-#ifdef DEBUG
- (void) printf(gettext("%s: installing default config entry '%s'\n"),
- progname, default_cfg);
-#endif
- if (mode != CFG_WRLOCK) {
- cfg_unlock(cfg);
- if (!cfg_lock(cfg, CFG_WRLOCK)) {
- (void) fprintf(stderr,
- gettext("%s: unable to lock configuration: %s\n"),
- progname, cfg_error(NULL));
- exit(1);
- }
- mode = CFG_WRLOCK;
-#ifdef DEBUG
- (void) printf(gettext("%s: upgraded lock, retrying\n"),
- progname);
-#endif
- goto retry;
- }
-
- if (cfg_put_cstring(cfg, "scm", default_cfg, strlen(default_cfg)) < 0) {
- (void) fprintf(stderr,
- gettext("%s: unable to write configuration: %s\n"),
- progname, cfg_error(NULL));
- exit(1);
- }
-
- if (!cfg_commit(cfg)) {
- (void) fprintf(stderr,
- gettext("%s: unable to write to configuration: %s\n"),
- progname, cfg_error(NULL));
- }
-
- if (mode != CFG_WRLOCK) {
- if (!cfg_lock(cfg, mode)) {
- (void) fprintf(stderr,
- gettext("%s: unable to relock configuration: %s\n"),
- progname, cfg_error(NULL));
- exit(1);
- }
- }
-
- cfg_rewind(cfg, CFG_SEC_CONF);
-}
-
-
-static int
-iscluster(void)
-{
- int rc;
-
- rc = cfg_iscluster();
- if (rc == 0) {
- return (FALSE);
- } else if (rc > 0) {
- return (TRUE);
- } else {
- (void) fprintf(stderr,
- gettext("%s: unable to ascertain environment\n"), progname);
- exit(1);
- }
-
- /* NOTREACHED */
-}
-
-
-static void
-restore_hints()
-{
- CFGFILE *cfg;
- char key[CFG_MAX_KEY], buf[CFG_MAX_BUF];
- int setnumber;
- spcs_s_info_t ustatus;
- int cd;
-
- if ((cfg = cfg_open(NULL)) == NULL) {
- (void) fprintf(stderr,
- gettext("%s: unable to access configuration: %s\n"),
- progname, cfg_error(NULL));
- exit(1);
- }
- if (!cfg_lock(cfg, CFG_RDLOCK)) {
- (void) fprintf(stderr,
- gettext("%s: unable to lock configuration: %s\n"),
- progname, cfg_error(NULL));
- exit(1);
- }
-
- for (setnumber = 1; /*CONSTCOND*/ TRUE; setnumber++) {
- (void) snprintf(key, sizeof (key), "cache_hint.set%d.device",
- setnumber);
- if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0) {
- /* error or not found */
- break;
- }
-
- if (strcmp(buf, "system") == 0) {
- cd = -1;
- } else {
- cd = get_cd(buf);
- if (cd < 0)
- continue;
- }
-
- (void) snprintf(key, sizeof (key), "cache_hint.set%d.wrthru",
- setnumber);
- if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0)
- continue;
-
- if (atoi(buf) == 1) {
- if (cd == -1) {
- /* Node hint */
- if (SDBC_IOCTL(SDBC_SET_NODE_HINT, NSC_WRTHRU,
- 1, 0, 0, 0, &ustatus) == SPCS_S_ERROR) {
- (void) fprintf(stderr,
- gettext("%s: set system "
- "option failed\n"),
- progname);
- sdbc_report_error(&ustatus);
- exit(1);
- }
- } else if (SDBC_IOCTL(SDBC_SET_CD_HINT, cd,
- NSC_WRTHRU, 1, 0, 0, &ustatus) == SPCS_S_ERROR) {
- (void) fprintf(stderr,
- gettext("%s: set option failed\n"),
- progname);
- sdbc_report_error(&ustatus);
- exit(1);
- }
- }
-
- (void) snprintf(key, sizeof (key), "cache_hint.set%d.nordcache",
- setnumber);
- if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0)
- continue;
-
- if (atoi(buf) == 1) {
- if (cd == -1) {
- /* Node hint */
- if (SDBC_IOCTL(SDBC_SET_NODE_HINT, NSC_NOCACHE,
- 1, 0, 0, 0, &ustatus) == SPCS_S_ERROR) {
- (void) fprintf(stderr,
- gettext("%s: set system "
- "option failed\n"),
- progname);
- sdbc_report_error(&ustatus);
- exit(1);
- }
- } else if (SDBC_IOCTL(SDBC_SET_CD_HINT, cd, NSC_NOCACHE,
- 1, 0, 0, &ustatus) == SPCS_S_ERROR) {
- (void) fprintf(stderr,
- gettext("%s: set option failed\n"),
- progname);
- sdbc_report_error(&ustatus);
- exit(1);
- }
- }
- }
-
- cfg_close(cfg);
-}
-
-void
-sdbc_set_maxdev()
-{
- spcs_s_info_t ustats;
-
- if (SDBC_IOCTL(SDBC_MAXFILES, &sdbc_max_devices,
- 0, 0, 0, 0, &ustats) == SPCS_S_ERROR) {
- (void) fprintf(stderr, gettext("%s: get maxfiles failed\n"),
- progname);
- sdbc_report_error(&ustats);
- exit(1);
- }
-}
-
-static void
-bitmapfs_print(void)
-{
- CFGFILE *cfg;
- char key[CFG_MAX_KEY], buf[CFG_MAX_BUF];
- int setnumber;
-
- cfg = cfg_open(NULL);
- if (cfg == NULL) {
- (void) fprintf(stderr,
- gettext("%s: unable to access configuration: %s\n"),
- progname, cfg_error(NULL));
- exit(1);
- }
-
- if (!cfg_lock(cfg, CFG_RDLOCK)) {
- (void) fprintf(stderr,
- gettext("%s: unable to lock configuration: %s\n"),
- progname, cfg_error(NULL));
- exit(1);
- }
-
- for (setnumber = 1; /*CSTYLED*/; setnumber++) {
- (void) snprintf(key, sizeof (key),
- "bitmaps.set%d.bitmap", setnumber);
- buf[0] = 0;
-
- if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0) {
- if (errno == ESRCH) {
- /* end of list */
- break;
- }
-
- (void) fprintf(stderr,
- gettext("%s: error reading configuration: %s\n"),
- progname, cfg_error(NULL));
- exit(1);
- }
-
- (void) printf("%s\n", buf);
- }
-
- cfg_close(cfg);
-}
-
-
-static void
-bitmapfs_delete(char *bitmapfs)
-{
- CFGFILE *cfg;
- char key[CFG_MAX_KEY], buf[CFG_MAX_BUF];
- int setnumber;
- int commit = 0;
-
- cfg = cfg_open(NULL);
- if (cfg == NULL) {
- (void) fprintf(stderr,
- gettext("%s: unable to access configuration: %s\n"),
- progname, cfg_error(NULL));
- exit(1);
- }
-
- if (!cfg_lock(cfg, CFG_WRLOCK)) {
- (void) fprintf(stderr,
- gettext("%s: unable to lock configuration: %s\n"),
- progname, cfg_error(NULL));
- exit(1);
- }
-
- for (setnumber = 1; /*CSTYLED*/; setnumber++) {
- (void) snprintf(key, sizeof (key),
- "bitmaps.set%d.bitmap", setnumber);
- buf[0] = 0;
-
- if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0) {
- if (errno == ESRCH) {
- /* end of list */
- (void) fprintf(stderr,
- gettext("%s: %s not found "
- "in configuration\n"),
- progname, bitmapfs);
- break;
- }
-
- (void) fprintf(stderr,
- gettext("%s: error reading configuration: %s\n"),
- progname, cfg_error(NULL));
- exit(1);
- }
-
- if (strcmp(bitmapfs, buf) == 0) {
- (void) snprintf(key, sizeof (key),
- "bitmaps.set%d", setnumber);
-
- if (cfg_put_cstring(cfg, key, (char *)NULL, 0) < 0) {
- (void) fprintf(stderr,
- gettext("%s: unable to delete %s "
- "from configuration: %s\n"),
- progname, bitmapfs, cfg_error(NULL));
- } else
- commit++;
-
- break;
- }
- }
-
- if (commit) {
- if (!cfg_commit(cfg)) {
- (void) fprintf(stderr,
- gettext("%s: unable to write "
- "to configuration: %s\n"),
- progname, cfg_error(NULL));
- }
- commit = 0;
- }
-
- cfg_close(cfg);
-}
-
-
-/*
- * User visible configuration.
- */
-
-static const struct {
- const char *tag; /* libcfg tag */
- const char *name; /* user presented name */
- const char *help; /* explanation string */
-} sdbc_cfg_options[] = {
- { "thread", "nthreads", "number of threads" },
- { "size", "cache_size", "total cache size" },
-#ifdef DEBUG
- { "write_cache", "write_cache_size", "write cache size" },
- { "fill_pattern", "fill_pattern", "debug fill pattern" },
- { "reserved1", "reserved1", "unavailable, do not use" },
- { "iobuf", "niobuf", "number of io buffers" },
- { "tdemons", "ntdeamons", "number of sd_test daemons" },
- { "forced_wrthru", "forced_wrthru", "override wrthru detection" },
- { "no_forced_wrthru", "no_forced_wrthru", "override wrthru"},
-#endif
- { NULL }
-};
-
-
-static int
-configure_sdbc(int argc, char *argv[], int optind)
-{
- CFGFILE *cfg;
- char key[CFG_MAX_KEY], buf[CFG_MAX_BUF];
- char *cp, option[CFG_MAX_BUF], value[CFG_MAX_BUF];
- const int opt_width = 20;
- int error, found, commit;
- int i;
-
- error = commit = 0;
-
- cfg = cfg_open(NULL);
- if (cfg == NULL) {
- (void) fprintf(stderr, "%s: unable to open configuration: %s",
- progname, cfg_error(NULL));
- return (1);
- }
-
- if (argc == optind) {
- /* display current user visible config */
-
- if (!cfg_lock(cfg, CFG_RDLOCK)) {
- (void) fprintf(stderr,
- gettext("%s: unable to lock configuration: %s\n"),
- progname, cfg_error(NULL));
- error = 1;
- goto out;
- }
-
- convert_config(cfg, CFG_RDLOCK);
-
- for (i = 0; sdbc_cfg_options[i].tag != NULL; i++) {
- (void) snprintf(key, sizeof (key),
- "scm.set1.%s", sdbc_cfg_options[i].tag);
- if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0) {
- if (errno == ESRCH) {
- /* not found */
- (void) strcpy(buf, "");
- } else {
- (void) fprintf(stderr,
- gettext("%s: error reading "
- "configuration: %s\n"),
- progname, cfg_error(NULL));
- error = 1;
- goto out;
- }
- }
-
- (void) printf("%-*s: %-*s /* %s */\n",
- opt_width, sdbc_cfg_options[i].name,
- opt_width, buf, sdbc_cfg_options[i].help);
- }
- } else {
- if (!cfg_lock(cfg, CFG_WRLOCK)) {
- (void) fprintf(stderr,
- gettext("%s: unable to lock configuration: %s\n"),
- progname, cfg_error(NULL));
- error = 1;
- goto out;
- }
-
- convert_config(cfg, CFG_WRLOCK);
-
- for (/*CSTYLED*/; optind < argc; optind++) {
- (void) strncpy(option, argv[optind], sizeof (option));
- option[sizeof (option) - 1] = '\0'; /* terminate */
-
- cp = strchr(option, '=');
- if (cp != NULL) {
- *cp = '\0'; /* terminate option */
- cp++;
- (void) strncpy(value, cp, sizeof (value));
- value[sizeof (value) - 1] = '\0';
-
- if (*value == '\0')
- (void) strncpy(value, "-",
- sizeof (value));
- }
-
- found = 0;
- for (i = 0; sdbc_cfg_options[i].tag != NULL; i++) {
- if (strcmp(option,
- sdbc_cfg_options[i].name) == 0) {
- found = 1;
- break;
- }
- }
-
- if (!found) {
- (void) fprintf(stderr,
- gettext("%s: unknown configuration "
- "parameter: %s\n"), progname, option);
- continue;
- }
-
- (void) snprintf(key, sizeof (key),
- "scm.set1.%s", sdbc_cfg_options[i].tag);
- if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0) {
- (void) fprintf(stderr,
- gettext("%s: error reading "
- "configuration: %s\n"),
- progname, cfg_error(NULL));
- error = 1;
- goto out;
- }
-
- if (*buf == '\0')
- (void) strncpy(buf, "<default>", sizeof (buf));
-
- if (cp != NULL) {
- char *tmp;
- long val;
- /* set to new value */
-
- if (strcmp(value, "-")) { /* default ? */
-
- val = strtol(value, &tmp, 0);
- if (strcmp(value, tmp) == 0) {
- (void) fprintf(stderr,
- gettext(
- "%s: bad value (%s) "
- "for option %s\n"),
- progname, value, option);
- error = 1;
- goto out;
- }
-
- /* make sure cache size is valid */
- if (strcmp(key, "scm.set1.size") == 0) {
- if (val > MAX_CACHE_SIZE) {
- PRINT_CACHE_SZ_ERR(val);
-
- /*
- * Overwrite the
- * cache size with
- * the maximum cache
- * size.
- */
- (void) snprintf(value,
- sizeof (value),
- "%ld",
- (long)
- MAX_CACHE_SIZE);
- }
- }
- }
-
- if (cfg_put_cstring(cfg, key, value,
- strlen(value)) < 0) {
- (void) fprintf(stderr,
- gettext("\n%s: error writing "
- "configuration: %s\n"),
- progname, cfg_error(NULL));
- error = 1;
- goto out;
- }
-
- (void) snprintf(buf, sizeof (buf),
- "%s = %s", buf,
- (strcmp(value, "-") == 0) ?
- "<default>" : value);
-
- commit = 1;
- }
-
- (void) printf("%-*s: %-*s /* %s */\n",
- opt_width, sdbc_cfg_options[i].name,
- opt_width, buf, sdbc_cfg_options[i].help);
- } /* end command line args */
- }
-
-out:
- if (commit) {
- if (!cfg_commit(cfg)) {
- (void) fprintf(stderr,
- gettext("%s: unable to write "
- "to configuration: %s\n"),
- progname, cfg_error(NULL));
- }
- commit = 0;
-
- (void) printf("\n%s\n",
- gettext("Changed configuration parameters "
- "will take effect when the cache is restarted"));
- }
-
- cfg_close(cfg);
- return (error);
-}
-
-
-static char *
-cd_to_device(int cd)
-{
- static _sd_stats_t *cs_cur = NULL;
- spcs_s_info_t ustatus;
-
- if (cs_cur == NULL) {
- cs_cur = malloc(sizeof (_sd_stats_t) +
- (sdbc_max_devices - 1) * sizeof (_sd_shared_t));
-
- if (cs_cur == NULL) {
- (void) fprintf(stderr, gettext("%s malloc: %s\n"),
- progname, strerror(errno));
- exit(1);
- }
- }
-
- if (SDBC_IOCTL(SDBC_STATS, cs_cur, 0, 0, 0, 0,
- &ustatus) == SPCS_S_ERROR) {
- (void) fprintf(stderr,
- gettext("%s: stats ioctl failed\n"), progname);
- sdbc_report_error(&ustatus);
- exit(1);
- }
- if (cs_cur->st_cachesize == 0 || cd >= cs_cur->st_count)
- return ("");
-
- return (cs_cur->st_shared[cd].sh_filename);
-}
-
-/*
- * takes either either a string containing the cd or the device name, and
- * returns the device name.
- */
-static char *
-get_device_name(char *arg)
-{
- long cd = 0;
- char *device;
-
- /* if the arg has a leading '/', assume it's a valid device name */
- if (!arg || *arg == '/') {
- return (arg);
- }
-
- /* treat the "all" keyword as a valid device name */
- if (strcmp(arg, "all") == 0) {
- return (arg);
- }
-
- /*
- * Next, assume it's a cd, and try to convert it to an integer, and
- * subsequently convert that cd to its corresponding device name.
- *
- * Since strtol returns 0 on failure, we need to make a special case
- * for a cd of "0", which is valid.
- */
- if (((cd = strtol(arg, (char **)NULL, 10)) > 0) ||
- strcmp(arg, "0") == 0) {
- device = cd_to_device((int)cd);
-
- /* cd_to_device returns NULL or "" on failure--check both */
- if (device && (strcmp(device, ""))) {
- /* it seems to be a valid device name */
- return (device);
- }
- }
-
- return (NULL);
-}
-
-static void
-remove_hint(char *device)
-{
- CFGFILE *cfg;
- char key[CFG_MAX_KEY], buf[CFG_MAX_BUF];
- int setnumber;
- int rc;
-
- if ((cfg = cfg_open(NULL)) == NULL) {
- (void) fprintf(stderr,
- gettext("%s: unable to access configuration: %s\n"),
- progname, cfg_error(NULL));
- exit(1);
- }
- if (!cfg_lock(cfg, CFG_WRLOCK)) {
- (void) fprintf(stderr,
- gettext("%s: unable to lock configuration: %s\n"),
- progname, cfg_error(NULL));
- exit(1);
- }
-
- for (setnumber = 1; /*CONSTCOND*/ TRUE; setnumber++) {
- (void) snprintf(key, sizeof (key), "cache_hint.set%d.device",
- setnumber);
- if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0) {
- /* error or not found */
- break;
- }
-
- if (strcmp(device, buf) != 0)
- continue;
-
- /* remove config file entry */
- (void) snprintf(key, sizeof (key),
- "cache_hint.set%d", setnumber);
- rc = cfg_put_cstring(cfg, key, NULL, 0);
- if (rc < 0)
- (void) fprintf(stderr,
- gettext("%s: unable to update configuration "
- "storage: %s"),
- progname, cfg_error(NULL));
- else if (!cfg_commit(cfg))
- (void) fprintf(stderr,
- gettext("%s: unable to update configuration "
- "storage: %s"),
- progname, cfg_error(NULL));
- else
- (void) fprintf(stderr,
- gettext("%s: persistent hint for %s"
- " removed from configuration\n"),
- progname, device);
- break;
- }
- cfg_close(cfg);
-}
-
-
-static void
-save_hint(int cd, int hint, int flag)
-{
- char device[NSC_MAXPATH];
- CFGFILE *cfg;
- char key[CFG_MAX_KEY], buf[CFG_MAX_BUF];
- int setnumber;
- int found;
- int rc;
-
- if (hint != NSC_WRTHRU && hint != NSC_NOCACHE)
- return;
-
- if (flag != 0 && flag != 1)
- return;
-
- if ((cfg = cfg_open(NULL)) == NULL) {
- (void) fprintf(stderr,
- gettext("%s: unable to access configuration: %s\n"),
- progname, cfg_error(NULL));
- exit(1);
- }
- if (!cfg_lock(cfg, CFG_WRLOCK)) {
- (void) fprintf(stderr,
- gettext("%s: unable to lock configuration: %s\n"),
- progname, cfg_error(NULL));
- exit(1);
- }
-
- if (cd == -1)
- (void) strcpy(device, "system");
- else
- (void) strncpy(device, cd_to_device(cd), NSC_MAXPATH);
-
- found = 0;
- for (setnumber = 1; /*CONSTCOND*/ TRUE; setnumber++) {
- (void) snprintf(key, sizeof (key), "cache_hint.set%d.device",
- setnumber);
- if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0) {
- /* error or not found */
- break;
- }
-
- if (strcmp(device, buf) == 0) {
- found = 1;
- break;
- }
- }
-
- if (found) {
- if (hint == NSC_WRTHRU)
- (void) snprintf(key, sizeof (key),
- "cache_hint.set%d.wrthru", setnumber);
- else /* NSC_NOCACHE */
- (void) snprintf(key, sizeof (key),
- "cache_hint.set%d.nordcache", setnumber);
- if (flag == 0)
- rc = cfg_put_cstring(cfg, key, "0", 1);
- else
- rc = cfg_put_cstring(cfg, key, "1", 1);
- } else {
- (void) strncpy(buf, device, CFG_MAX_BUF);
- if (flag == 0)
- (void) strncat(buf, " 0 0", CFG_MAX_BUF);
- else if (hint == NSC_WRTHRU)
- (void) strncat(buf, " 1 0", CFG_MAX_BUF);
- else /* NSC_NOCACHE */
- (void) strncat(buf, " 0 1", CFG_MAX_BUF);
- rc = cfg_put_cstring(cfg, "cache_hint", buf, sizeof (buf));
- }
-
- if (rc < 0)
- (void) fprintf(stderr,
- gettext("%s: unable to update configuration storage: %s"),
- progname, cfg_error(NULL));
- else if (!cfg_commit(cfg))
- (void) fprintf(stderr,
- gettext("%s: unable to update configuration storage: %s"),
- progname, cfg_error(NULL));
- cfg_close(cfg);
-}
-
-#ifdef lint
-int
-scmadm_lintmain(int argc, char *argv[])
-#else
-int
-main(int argc, char *argv[])
-#endif
-{
- int o = 0;
- int c;
- int errflg = 0;
- int hflag = 0;
- int qflag = 1;
- extern int optind;
- extern char *optarg;
- int cd;
- int hint;
- int flag;
- int optflag = 0;
- spcs_s_info_t ustats;
- int Dopt, Lopt;
- int Oopt = 0;
- char *bitmapfs = NULL;
- const char *exclusive = gettext(
- "-d, -e, -m, -o, -C, -D, -L, and -v "
- "are mutually exclusive\n");
-
- (void) setlocale(LC_ALL, "");
- (void) textdomain("scm");
-
- progname = strdup(basename(argv[0]));
-
- sdbc_set_maxdev();
-
- buildusage(progname);
-
- Dopt = Lopt = 0;
-
- while ((c = getopt(argc, argv,
-#ifdef DEBUG
- "gi:t:S"
-#endif
- "CD:LOa:devqhm:o:")) != EOF) {
-
- switch (c) {
-
- case 'D':
- if (optflag) {
- (void) fprintf(stderr, exclusive);
- goto usage;
- }
-
- Dopt++;
- optflag++;
- bitmapfs = optarg;
- break;
-
- case 'L':
- if (optflag) {
- (void) fprintf(stderr, exclusive);
- goto usage;
- }
-
- Lopt++;
- optflag++;
- break;
-
-#ifdef DEBUG
- case 'S':
- if (optflag) {
- (void) fprintf(stderr, exclusive);
- goto usage;
- }
-
- if (putenv(stats_usage) != 0) {
- (void) fprintf(stderr,
- gettext("%s: unable to putenv()\n"),
- progname);
- exit(1);
- }
-
- argv[1] = "scmadm";
- if (execv(STATS_PATH, &argv[1]) == -1) {
- (void) fprintf(stderr,
- gettext("%s: failed to execute " STATS_PATH
- "\n"), progname);
- (void) fprintf(stderr,
- gettext("Please be sure to copy sd_stats"
- " from src/cmd/ns/sdbc in a development"
- " workspace\n"));
- }
- exit(0);
- break;
-#endif
- case 'a':
- (void) strcpy(alert_file, optarg);
- break;
- case 'q':
- qflag++;
- break;
- case 'O': /* restore hints */
- Oopt++;
- break;
- case 'C': /* configure */
- case 'e': /* enable */
- case 'd': /* disable */
- case 'v': /* get version */
- case 'o': /* get/set options */
- case 'm': /* get cd map */
-#ifdef DEBUG
- case 't': /* trace */
- case 'i': /* inject_ioerr */
- case 'c': /* clear_ioerr */
- case 'g': /* toggle_flush */
-#endif
- if (optflag) {
- (void) fprintf(stderr,
-#ifdef DEBUG
- "%s%s", gettext("-t, -i, -c, -g, "),
-#endif
- exclusive);
-
- errflg++;
- }
- optflag++;
- o = c;
- break;
- case 'h':
- hflag = 1;
- break;
- case '?':
- default:
- errflg++;
- break;
- }
- if (errflg || hflag)
- goto usage;
- }
-
- if (Oopt) {
- /* Set hints saved in persistent configuration */
- restore_hints();
- exit(0);
- }
- if (Dopt || Lopt) {
- /* bitmapfs control */
-
- if (iscluster()) {
- (void) fprintf(stderr,
- gettext("%s: bitmap filesystems are not "
- "allowed in a cluster\n"), progname);
- goto usage;
- }
-
- if ((Dopt + Lopt) > 1) {
- (void) fprintf(stderr, gettext("-D and -L are"
- "mutually exclusive\n"));
- goto usage;
- }
-
- if (Lopt)
- bitmapfs_print();
- else /* if (Dopt) */
- bitmapfs_delete(bitmapfs);
-
- exit(0);
- }
-
- if (!o) {
- if (argc > 1)
- goto usage;
- (void) printf(gettext("%s: Printing all cd's and options:\n"),
- progname);
- print_all_options();
- }
-
- /* Configure */
- if (o == 'C') {
- exit(configure_sdbc(argc, argv, optind));
- }
- /* enable */
- if (o == 'e') {
- enable_sdbc();
- if (qflag == 0)
- sd_gather_alert_dumps();
- exit(0);
- }
- /* disable */
- if (o == 'd') {
- disable_sdbc();
- exit(0);
- }
- /* get version */
- if (o == 'v') {
- get_version();
- exit(0);
- }
- /* node_hint or cd_hint */
- if (o == 'o') {
- if (!(strcoll(optarg, "system"))) { /* node_hint */
- if ((optind - 1) == (argc - 1)) { /* get */
- if ((hint = SDBC_IOCTL(SDBC_GET_NODE_HINT, 0, 0,
- 0, 0, 0, &ustats)) == SPCS_S_ERROR) {
- (void) fprintf(stderr,
- gettext("%s: get system "
- "options failed\n"),
- progname);
- sdbc_report_error(&ustats);
- exit(1);
- }
-#ifdef WRTHRU_HINTS
- (void) printf(gettext("System Status: "));
- print_hint(hint, 1);
-#endif
- (void) printf(gettext("System Options: "));
- print_hint(hint, 0);
- exit(0);
- } else { /* set, clear */
- if (get_hint(argv[optind], &hint, &flag) == -1)
- goto usage;
- if (hint == -1) {
- /* remove hint from config */
- remove_hint("system");
- exit(0);
- }
-
- if (SDBC_IOCTL(SDBC_SET_NODE_HINT, hint, flag,
- 0, 0, 0, &ustats) == SPCS_S_ERROR) {
- (void) fprintf(stderr,
- gettext("%s: set system "
- "option failed\n"),
- progname);
- sdbc_report_error(&ustats);
- exit(1);
- }
- save_hint(-1, hint, flag);
- (void) printf(gettext("%s: System option %s"
- " now set.\n"), progname, argv[optind]);
- exit(0);
- }
- } else { /* cd_hint */
- cd = get_cd(optarg);
- if ((optind - 1) == (argc - 1)) { /* get */
- if (cd < 0) {
- (void) fprintf(stderr,
- gettext("%s: device %s not "
- "found\n"),
- progname, optarg);
- exit(1);
- }
- hint = get_cd_hint(cd);
- (void) printf(gettext("%s: cd(%d) Current "
- "options are: "), progname, cd);
- print_hint(hint, 0);
- exit(0);
- } else { /* set, clear */
- if (get_hint(argv[optind], &hint, &flag) == -1)
- goto usage;
- if (hint == -1) {
- /* remove hint from config */
- if (cd < 0)
- remove_hint(optarg);
- else
- remove_hint(cd_to_device(cd));
- exit(0);
- }
- if (cd < 0) {
- (void) fprintf(stderr,
- gettext("%s: device %s not "
- "found\n"),
- progname, optarg);
- exit(1);
- }
-
- if (SDBC_IOCTL(SDBC_SET_CD_HINT, cd, hint,
- flag, 0, 0, &ustats) == SPCS_S_ERROR) {
- (void) fprintf(stderr,
- gettext("%s: set option "
- "failed\n"), progname);
- sdbc_report_error(&ustats);
- exit(1);
- }
- save_hint(cd, hint, flag);
- (void) printf(gettext("%s: cd %d option %s now"
- " set.\n"), progname, cd, argv[optind]);
- exit(0);
- }
- }
- }
-
- if (o == 'm') { /* "get_cd" = map */
- char *dev_name;
-
- if (!(strcoll(optarg, "all"))) /* all */
- (void) get_cd_all();
- else {
- cd = get_cd(optarg);
- if (cd < 0) {
- (void) fprintf(stderr,
- gettext("%s: device or cd %s not found\n"),
- progname, optarg);
- exit(1);
- }
-
- if ((dev_name = get_device_name(optarg)) == NULL) {
- (void) fprintf(stderr, gettext(
- "%s: device for cd %d not found\n"),
- progname, cd);
- exit(1);
- }
-
- (void) printf(gettext("%s: diskname %s; cd %d\n"),
- progname, dev_name, cd);
- exit(0);
- }
- }
-
-#ifdef DEBUG
- if (o == 't') { /* "trace" */
- int flag, value;
- _sdtr_table_t tt;
- if ((optind+1) != (argc-1))
- goto usage;
- cd = get_cd(argv[optind]);
- if (cd < 0) {
- (void) fprintf(stderr,
- gettext("%s: device or cd %s not found\n"),
- progname, argv[optind]);
- exit(1);
- }
-
- value = strtol(argv[optind+1], 0, 0);
- if (!(strcoll(optarg, gettext("size")))) {
- flag = SD_SET_SIZE;
- tt.tt_max = value;
- } else if (!(strcoll(optarg, gettext("mask")))) {
- flag = SD_SET_MASK;
- tt.tt_mask = value;
- } else if (!(strcoll(optarg, gettext("lbolt")))) {
- flag = SD_SET_LBOLT;
- tt.tt_lbolt = value;
- } else if (!(strcoll(optarg, gettext("good")))) {
- flag = SD_SET_GOOD;
- tt.tt_good = value;
- } else goto usage;
-
- if (SDBC_IOCTL(SDBC_ADUMP, (long)cd, &tt, NULL, 0L,
- (long)flag, &ustats) == SPCS_S_ERROR) {
- (void) fprintf(stderr,
- gettext("%s: trace %s failed\n"),
- progname, optarg);
- sdbc_report_error(&ustats);
- exit(1);
- }
- (void) printf(gettext("%s: trace %s processed\n"),
- progname, optarg);
- if (cd != -1)
- (void) printf(gettext(" cd %d; size %d; mask 0x%04x; "
- "lbolt %d; good %d;\n"),
- cd, tt.tt_max, tt.tt_mask,
- tt.tt_lbolt, tt.tt_good);
- exit(0);
- }
-
- if (o == 'i') { /* "inject_ioerr" */
- int ioj_err = EIO;
- int cd;
- int ioj_cnt = 0;
-
- /* a cd of "-1" represents all devices */
- if (strcmp(optarg, "-1") == 0) {
- cd = -1;
- } else if ((cd = get_cd(optarg)) < 0) {
- (void) fprintf(stderr,
- gettext("%s: device or cd %s not found\n"),
- progname, optarg);
- exit(1);
- }
- if (argc == 4)
- ioj_err = strtol(argv[optind], 0, 0);
- if (argc == 5)
- ioj_cnt = strtol(argv[optind+1], 0, 0);
-
- if (SDBC_IOCTL(SDBC_INJ_IOERR, cd, ioj_err, ioj_cnt, 0, 0,
- &ustats) == SPCS_S_ERROR) {
- (void) fprintf(stderr,
- gettext("%s: i/o error injection for cd %s "
- "failed\n"), progname, optarg);
- sdbc_report_error(&ustats);
- exit(1);
- }
- (void) printf(gettext("%s: i/o error injection cd %d errno %d "
- "processed\n"), progname, cd, ioj_err);
- exit(0);
- }
-
- if (o == 'c') { /* "clear_ioerr" */
- int cd;
-
- /* a cd of "-1" represents all devices */
- if (strcmp(optarg, "-1") == 0) {
- cd = -1;
- } else if ((cd = get_cd(optarg)) < 0) {
- (void) fprintf(stderr,
- gettext("%s: device or cd %s not found\n"),
- progname, optarg);
- exit(1);
- }
-
- if (SDBC_IOCTL(SDBC_CLR_IOERR, cd, 0, 0, 0, 0, &ustats)
- == SPCS_S_ERROR) {
- (void) fprintf(stderr,
- gettext("%s: i/o error clear %s failed\n"),
- progname, optarg);
- sdbc_report_error(&ustats);
- exit(1);
- }
- (void) printf(gettext("%s: i/o error clear for cd %d "
- "processed\n"), progname, cd);
- exit(0);
- }
-
- if (o == 'g') { /* "toggle_flush" */
- flag = toggle_flush();
- (void) printf(gettext("%s: sdbc cache flush now %s\n"),
- progname, flag ? "on" : "off");
- exit(0);
- }
-#endif /* DEBUG */
-
- return (0);
-usage:
- (void) fprintf(stderr, "%s\n", scmadmUsage);
- if (hflag) {
- return (0);
- }
- return (1);
-}
-
-
-#define addusage(f__) \
- (void) strncat(scmadmUsage, f__, sizeof (scmadmUsage));
-
-#define addusage1(f__, a__) \
- (void) snprintf(fmt, sizeof (fmt), "%s%s", scmadmUsage, f__); \
- (void) snprintf(scmadmUsage, sizeof (scmadmUsage), fmt, a__);
-
-#define addusage2(f__, a__, b__) \
- (void) snprintf(fmt, sizeof (fmt), "%s%s", scmadmUsage, f__); \
- (void) snprintf(scmadmUsage, sizeof (scmadmUsage), fmt, a__, b__);
-
-static void
-buildusage(char *p)
-{
- char fmt[USAGELEN];
-#ifdef WRTHRU_HINTS
- char *hints_str = "[nordcache|rdcache|wrthru|nowrthru|forget]\n";
-#else
- char *hints_str = "[nordcache|rdcache|forget]\n";
-#endif
-
- bzero(scmadmUsage, sizeof (scmadmUsage));
- bzero(fmt, sizeof (fmt));
-
- addusage(gettext("Usage :\n"));
- addusage1(gettext("\t%s\n"), p);
- addusage1(gettext("\t%s -h\n"), p);
- addusage1(gettext("\t%s -e\n"), p);
- addusage1(gettext("\t%s -d\n"), p);
- addusage1(gettext("\t%s -v\n"), p);
- addusage1(gettext("\t%s {-L | -D bitmapfs}\n"), p);
- addusage1(gettext("\t%s -C [parameter[=[value]] ...]\n"), p);
- addusage2(gettext("\t%s -o system %s"), p, hints_str);
- addusage2(gettext("\t%s -o <cd> %s"), p, hints_str);
- addusage2(gettext("\t%s -o <diskname> %s"), p, hints_str);
- addusage1(gettext("\t%s -m {<cd>|<diskname>|all}\n"), p);
-#ifdef DEBUG
- addusage1(gettext(
- "\t%s -S [-Mz] [-d delay_time] [-l logfile] [-r range]\n"), p);
- addusage1(gettext(
- "\t%s -t {size|mask|lbolt|good} <cd|diskname> <value>\n"), p);
- addusage1(gettext("\t%s -g\n"), p);
- addusage1(gettext(
- "\t%s -i {cd|diskname|-1 for all} [errno [countdown]]\n"), p);
- addusage1(gettext("\t%s -c {cd|diskname|-1 for all}\n"), p);
- addusage(gettext("\nt = trace\tg = toggle_flush\ti = inject ioerr\n"
- "c = clear ioerr\tS = stats\n"));
-#endif /* DEBUG */
- addusage(gettext(
- "e = enable\td = disable\tv=version\to = get/ set options\n"));
- addusage(gettext(
- "m = get cd map\n"));
- addusage1(gettext(
- "note: cd is a cache descriptor integer in the range [0-%d]\n"),
- sdbc_max_devices - 1);
- addusage(gettext(
- " bitmapfs is a block device or filesystem mount point\n"));
-
-#ifdef DEBUG
- (void) snprintf(stats_usage, sizeof (stats_usage),
- "SD_STATS_USAGE=%s", scmadmUsage);
-#endif
-}
-
-static int
-get_hint(char *str, int *hint, int *flag)
-{
-#ifdef WRTHRU_HINTS
- if (!(strcoll(str, gettext("wrthru")))) {
- *hint = NSC_WRTHRU;
- *flag = 1;
- return (0);
- } else if (!(strcoll(str, gettext("nowrthru")))) {
- *hint = NSC_WRTHRU;
- *flag = 0;
- return (0);
- } else
-#endif
- if (!(strcoll(str, gettext("nordcache")))) {
- *hint = NSC_NOCACHE;
- *flag = 1;
- return (0);
- } else if (!(strcoll(str, gettext("rdcache")))) {
- *hint = NSC_NOCACHE;
- *flag = 0;
- return (0);
- } else if (!(strcoll(str, gettext("forget")))) {
- *hint = -1;
- *flag = 0;
- return (0);
- }
- return (-1);
-}
-
-/*ARGSUSED*/
-void
-print_hint(const uint_t type, const int status)
-{
-#ifdef WRTHRU_HINTS
- if (status) {
- if (type & NSC_FORCED_WRTHRU) {
- (void) printf(gettext("Fast Writes Overridden\n"));
- } else {
- /* if (type & NSC_NO_FORCED_WRTHRU) */
- (void) printf(gettext("default\n"));
- }
- } else {
- (void) printf("%swrthru, %srdcache",
- (type & (NSC_FORCED_WRTHRU|NSC_WRTHRU)) ? "" : "no",
- (type & NSC_NOCACHE) ? "no" : "");
-#else
- {
- (void) printf("%srdcache", (type & NSC_NOCACHE) ? "no" : "");
-#endif
-
- if (type & 0x80000000)
- (void) printf(" (overridden by system)");
-
- (void) printf("\n");
- }
-}
-
-/*
- * Read the configuration via libcfg
- */
-
-int
-get_cache_config()
-{
- int i;
- int sysid;
- CFGFILE *cfg;
- char buf[CFG_MAX_BUF];
- char key[CFG_MAX_KEY];
-
-
- if ((cfg = cfg_open(NULL)) == NULL) {
- (void) fprintf(stderr,
- gettext("Cannot open configuration file\n"));
- exit(1);
- }
-
- if (!cfg_lock(cfg, CFG_RDLOCK)) {
- (void) fprintf(stderr,
- gettext("Cannot lock configuration file\n"));
- exit(1);
- }
-
- convert_config(cfg, CFG_RDLOCK);
- (void) memset((char *)&user_level_conf, 0, sizeof (_sd_cache_param_t));
-
- /* Get the system ID */
- if (nsc_getsystemid(&sysid) < 0) {
- (void) fprintf(stderr,
- gettext("%s Unable to obtain subsystem ID: %s\n"),
- progname, strerror(errno));
- exit(1);
- }
- myid = sysid;
-
- user_level_conf.blk_size = 8192; /* DEFAULT */
- user_level_conf.procs = 16; /* DEFAULT */
- user_level_conf.reserved1 = RESERVED1_DEFAULTS;
-
- bzero(buf, CFG_MAX_BUF);
- (void) snprintf(key, sizeof (key), "scm.set1.thread");
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) > 0) {
- user_level_conf.threads = atoi(buf);
- } else
- user_level_conf.threads = 128; /* DEFAULT */
-
- (void) snprintf(key, sizeof (key), "scm.set1.tdemons");
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) > 0) {
- user_level_conf.test_demons = atoi(buf);
- }
-
- (void) snprintf(key, sizeof (key), "scm.set1.write_cache");
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) > 0) {
- user_level_conf.write_cache = atoi(buf);
- }
-
- (void) snprintf(key, sizeof (key), "scm.set1.size");
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) > 0) {
- /*
- * We need to run strtol for backwards compatibility in 3.2.
- * A workaround for this bug was put in 3.2 which allowed
- * customers to set the cache size up to 1024 if it was
- * specified in hexadecimal. Decimal still had the limit
- * of 128. This change treats them both identically.
- */
- user_level_conf.cache_mem[0] = (int)strtol(buf, NULL, 0);
- if (user_level_conf.cache_mem[0] > MAX_CACHE_SIZE) {
- (void) fprintf(stderr, gettext(
- "The cache size of %ld is larger than "
- "the system maximum of %ld.\nUse \"scmadm -C "
- "cache_size=<size>\" to set the size to a proper "
- "value.\n"),
- user_level_conf.cache_mem[0], MAX_CACHE_SIZE);
- user_level_conf.cache_mem[0] = MAX_CACHE_SIZE;
- }
- }
-
- (void) snprintf(key, sizeof (key), "scm.set1.iobuf");
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) > 0) {
- user_level_conf.iobuf = atoi(buf);
- }
-
- (void) snprintf(key, sizeof (key), "scm.set1.fill_pattern");
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) > 0) {
- user_level_conf.fill_pattern = atoi(buf);
- user_level_conf.gen_pattern = 1;
- }
-
- (void) snprintf(key, sizeof (key), "scm.set1.no_forced_wrthru");
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) > 0) {
- no_forced_wrthru = atoi(buf);
- }
-
- (void) snprintf(key, sizeof (key), "scm.set1.forced_wrthru");
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) > 0) {
- forced_wrthru = atoi(buf);
- }
-
- (void) snprintf(key, sizeof (key), "scm.set1.reserved1");
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) > 0) {
- user_level_conf.reserved1 = atoi(buf);
- }
-
- cfg_close(cfg);
-
- /*
- * use the default minidsp configuration if no
- * node/mirror/remote-mirror/cluster line is in the sd.cf file
- */
- if (nodes_configured == 0)
- check_and_set_mirrors(myid, _SD_NO_HOST);
-
-
- /* Check if our sysid was defined */
- if (!node_defined[myid]) {
- (void) fprintf(stderr,
- gettext("This node(%d) is not defined in config.\n"), myid);
- exit(1);
- }
-
- /*
- * Save off number of nodes so we can calculate the point-to-point
- * segements. Code in kernel currently supports MAX_SD_NODES
- */
- if ((user_level_conf.num_nodes = nodes_configured) >
- MAX_SD_NODES) {
- (void) fprintf(stderr,
- gettext("Cache can support only %d nodes(%d).\n"),
- MAX_SD_NODES, nodes_configured);
- exit(1);
- }
-
- if ((nodes_configured % 2) && !minidsp) {
- if (nodes_configured == 1)
- (void) fprintf(stderr,
- gettext("Only one node configured, "
- "mirror node must be %d\n"), _SD_NO_HOST);
- else
- (void) fprintf(stderr,
- gettext("Cannot configure odd number of nodes.\n"));
- exit(1);
- }
-
-
- /* Pass List of Nodes Configured to Cache */
- for (i = 0; i < nodes_configured; i++)
- user_level_conf.nodes_conf[i] = nodes_conf[i];
-
- /* Place magic number in user_level_conf. Kernel will test for it */
- user_level_conf.magic = _SD_MAGIC;
- (void) sleep(1);
- return (0);
-}
-
-_sdtr_t hdr;
-
-/* function name string */
-char *
-_sd_fname(int f)
-{
- int fn = f & ST_FUNC;
- static char c[8];
- char *s;
-
- if (f & ST_BCACHE)
- s = _bcache_fname[fn];
- else if (f & ST_BSUB)
- s = _bsub_fname[fn];
- else if (f & ST_IO)
- s = _io_fname[fn];
- else if (f & ST_STATS)
- s = _stats_fname[fn];
- else if (f & ST_CCIO)
- s = _ccio_fname[fn];
- else if (f & ST_FT)
- s = _ft_fname[fn];
- else if (f & ST_INFO)
- s = _info_fname[fn];
- if (!s)
- (void) sprintf(s = c, "0x%04x", f & 0xffff);
- return (s);
-}
-
-int alerts = 0;
-
-/*
- * Background daemon to wait for alert (on any device)
- * Writes the traces to "sd_alert.CD.NUM",
- * and writes an information message to the alert_file.
- */
-
-void
-sd_gather_alert_dumps()
-{
- _sdtr_table_t tt;
- _sdtr_t *buf;
- int cd, count, size, flag;
- char filename[64];
- int fd;
- time_t tloc;
- struct tm tm_storage;
- struct tm *tm_ptr;
- char timebuf[80];
- spcs_s_info_t ustats;
-
- /* fork and detach daemon */
- if (fork())
- exit(0);
- (void) close(0);
- fd = open(alert_file, O_WRONLY|O_APPEND|O_CREAT, 0644);
- if (fd == -1)
- fd = open("/dev/console", O_WRONLY);
- if (fd != -1) {
- (void) dup2(fd, 1);
- (void) dup2(fd, 2);
- (void) close(fd);
- }
- (void) setsid();
-
- size = 10000;
- if (size < user_level_conf.trace_size)
- size = user_level_conf.trace_size;
-
- buf = (_sdtr_t *)malloc(size * sizeof (_sdtr_t));
- if (!buf) {
- (void) fprintf(stderr, gettext("%s malloc: %s\n"),
- progname, strerror(errno));
- exit(1);
- }
- tloc = time(NULL);
- tm_ptr = (struct tm *)localtime_r(&tloc, &tm_storage);
-
-loop:
- cd = SDT_ANY_CD; /* any device */
- flag = SD_ALERT_WAIT; /* block for alert */
- if ((count = SDBC_IOCTL(SDBC_ADUMP, cd, &tt, buf, size,
- flag, &ustats)) == SPCS_S_ERROR) {
- (void) fprintf(stderr, gettext("%s: sd_adump\n"), progname);
- sdbc_report_error(&ustats);
- if (errno == EIDRM) {
- (void) strftime(timebuf, 80, "%x %X", tm_ptr);
- (void) fprintf(stderr,
- gettext("%s: cache deconfigured at %s\n"),
- progname, timebuf);
- exit(0);
- }
- if (errno == ENOSYS)
- exit(0);
- exit(errno);
- }
- if (count == 0)
- goto loop;
- cd = tt.tt_cd;
- (void) sprintf(filename, "%s.%d.%d", "sd_alert", cd, alerts++);
- if ((fd = open(filename, O_CREAT | O_RDWR, 0444)) == -1) {
- (void) fprintf(stderr, gettext("%s: open: %s\n"),
- progname, strerror(errno));
- exit(errno);
- }
- /*
- * write header to identify device, write entries
- */
- hdr.t_func = SDF_CD;
- hdr.t_len = count;
- hdr.t_ret = tt.tt_cd;
- if (write(fd, &hdr, sizeof (_sdtr_t)) == -1) {
- (void) fprintf(stderr, gettext("%s: write: %s\n"),
- progname, strerror(errno));
- exit(errno);
- }
-
- if (write(fd, buf, sizeof (_sdtr_t)*count) == -1) {
- (void) fprintf(stderr, gettext("%s: write: %s\n"),
- progname, strerror(errno));
- exit(errno);
- }
- (void) close(fd);
-
- (void) strftime(timebuf, 80, "%x %X", tm_ptr);
- (void) printf("sd alert trace dump %s at %s\n", filename, timebuf);
- goto loop;
-}
-
-
-
-/*
- * print list of configured cd's, diskname, options and global options
- */
-void
-print_all_options()
-{
- static _sd_stats_t *cs_cur;
- spcs_s_info_t ustats;
- int cd;
- int hint;
- char *s1 = "device name";
- char *s2 = "option";
- char fn[19];
- int len;
-
- /* No corresponding free because this function exits */
- cs_cur = malloc(sizeof (_sd_stats_t) +
- (sdbc_max_devices - 1) * sizeof (_sd_shared_t));
- if (cs_cur == NULL) {
- (void) fprintf(stderr, gettext("%s malloc: %s\n"),
- progname, strerror(errno));
- exit(1);
- }
-
- /* node hints */
- if ((hint = SDBC_IOCTL(SDBC_GET_NODE_HINT, 0, 0, 0, 0, 0,
- &ustats)) == SPCS_S_ERROR) {
- (void) fprintf(stderr,
- gettext("%s: get system option failed\n"),
- progname);
- sdbc_report_error(&ustats);
- exit(1);
- }
-#ifdef WRTHRU_HINTS
- (void) printf(gettext("System Status: "));
- print_hint(hint, 1);
-#endif
- (void) printf(gettext("System Options: "));
- print_hint(hint, 0);
-
- /* get cds */
- if (SDBC_IOCTL(SDBC_STATS, cs_cur, 0, 0, 0, 0, &ustats)
- == SPCS_S_ERROR) {
- (void) fprintf(stderr,
- gettext("%s: get_cd failed in print_all options\n"),
- progname);
- sdbc_report_error(&ustats);
- exit(1);
- }
- if (cs_cur->st_cachesize == 0)
- (void) printf(gettext("Cache is disabled\n"));
- else if (cs_cur->st_count == 0)
- (void) printf(gettext("No devices are configured\n"));
- else {
- (void) printf(
- gettext("\nConfigured cd's, disknames and options: \n"));
- (void) printf(gettext("cd\t%-28s\t%-20s\n"), s1, s2);
- for (cd = 0; cd < cs_cur->st_count; cd++) {
- if (cs_cur->st_shared[cd].sh_alloc) {
- hint = get_cd_hint(cd);
- if ((len =
- strlen(cs_cur->st_shared[cd].sh_filename))
- > 23) {
- (void) strcpy(fn, "...");
- (void) strcat(fn,
- cs_cur->st_shared[cd].sh_filename +
- len - 20);
- } else {
- (void) strcpy(fn,
- cs_cur->st_shared[cd].sh_filename);
- }
-
- (void) printf(gettext("%d\t%-28.*s\t"), cd,
- NSC_MAXPATH, fn);
-
- print_hint(hint, 0);
- }
- }
- }
- exit(0);
-}
-
-
-/*
- * cache device -- lookup names and cache descriptors of all configured devices
- */
-void
-get_cd_all()
-{
- static _sd_stats_t *cs_cur;
- spcs_s_info_t ustats;
- int cd;
- char fn[19];
- int len;
-
- /* No corresponding free because this function exits */
- cs_cur = malloc(sizeof (_sd_stats_t) +
- (sdbc_max_devices - 1) * sizeof (_sd_shared_t));
- if (cs_cur == NULL) {
- (void) fprintf(stderr, gettext("%s malloc: %s\n"),
- progname, strerror(errno));
- exit(1);
- }
-
- if (SDBC_IOCTL(SDBC_STATS, cs_cur, 0, 0, 0, 0, &ustats)
- == SPCS_S_ERROR) {
- (void) fprintf(stderr, gettext("%s: get_cd_all"),
- progname);
- sdbc_report_error(&ustats);
- exit(1);
- }
- if (cs_cur->st_cachesize == 0)
- (void) printf(gettext("Cache is disabled\n"));
- else if (cs_cur->st_count == 0)
- (void) printf(gettext("No devices are configured\n"));
- else {
- (void) printf(gettext("\tcd\tdevice name\n"));
- for (cd = 0; cd < cs_cur->st_count; cd++) {
- if (cs_cur->st_shared[cd].sh_alloc) {
- if ((len = strlen(
- cs_cur->st_shared[cd].sh_filename)) > 15) {
- (void) strcpy(fn, "...");
- (void) strcat(fn,
- cs_cur->st_shared[cd].sh_filename +
- len - 12);
- } else {
- (void) strcpy(fn,
- cs_cur->st_shared[cd].sh_filename);
- }
- (void) printf(gettext("\t%d\t%s\n"),
- cd, fn);
- }
- }
- }
- exit(0);
-}
-
-/*
- * cache device -- specified by number or lookup name
- */
-static int
-get_cd(char *s)
-{
- static _sd_stats_t *cs_cur = NULL;
- spcs_s_info_t ustats;
- int cd, arg_cd = -1;
-
- if (cs_cur == NULL) {
- /*
- * No corresponding free because the memory is reused
- * every time the function is called.
- */
- cs_cur = malloc(sizeof (_sd_stats_t) +
- (sdbc_max_devices - 1) * sizeof (_sd_shared_t));
- if (cs_cur == NULL) {
- (void) fprintf(stderr, gettext("%s malloc: %s\n"),
- progname, strerror(errno));
- exit(1);
- }
- }
-
- if (SDBC_IOCTL(SDBC_STATS, cs_cur, 0, 0, 0, 0, &ustats)
- == SPCS_S_ERROR) {
- (void) fprintf(stderr, gettext("%s: get_cd\n"), progname);
- sdbc_report_error(&ustats);
- exit(1);
- }
- if (cs_cur->st_cachesize == 0) {
- (void) printf(gettext("Cache is disabled\n"));
- exit(0);
- }
-
- if (*s != '/') {
- /*
- * Since strtol returns 0 on failure, we need to make a
- * special case for a cd of "0", which is valid.
- *
- * This case also deals with the difference between
- * scmadm -o system and scmadm -o 0
- */
- if (((int)strtol(s, (char **)NULL, 10) == 0) &&
- strcmp(s, "0"))
- return (-1);
-
- /*
- * Only return failure at this point, in order to allow
- * checking arg_cd against st_count later on.
- */
- if ((arg_cd = strtol(s, 0, 0)) < 0) {
- return (arg_cd);
- }
- }
-
- /* make sure the cd passed as an argument is alloc'd and < st_count */
- if (arg_cd >= 0) {
- return (((arg_cd < cs_cur->st_count) &&
- (cs_cur->st_shared[arg_cd].sh_alloc)) ? arg_cd : -1);
- }
-
- for (cd = 0; cd < cs_cur->st_count; cd++) {
- if (cs_cur->st_shared[cd].sh_alloc &&
- strcmp(s, cs_cur->st_shared[cd].sh_filename) == 0)
- return (cd);
- }
- return (-1);
-}
-
-void
-check_and_set_mirrors(int node, int mirror)
-{
-
- if (minidsp) {
- (void) fprintf(stderr,
- gettext("%s: minidsp defined. "
- "Cannot define other nodes.\n"),
- progname);
- exit(1);
- }
-
- if (mirror == _SD_NO_HOST) {
- minidsp++;
- } else if ((!(node % 2) && !(node == mirror - 1)) ||
- (((node % 2) && !(node == mirror + 1)))) {
- (void) fprintf(stderr,
- gettext("%s: Node and Mirror identification values "
- "must be consecutive\n"
- "starting at an even number (Node = %d Mirror = %d)\n"),
- progname, node, mirror);
- exit(1);
- }
-
- node_defined[node]++;
-
- nodes_conf[nodes_configured] = node;
- nodes_configured++;
-
- if (node == myid) {
- user_level_conf.mirror_host = mirror;
- }
-}
-
-char *mem_string =
- "%-8s Structures use approx. %8d bytes (%5d pages) of memory\n";
-
-void
-enable_sdbc()
-{
- spcs_s_info_t ustats;
-
- if (get_cache_config()) {
- (void) fprintf(stderr,
- gettext("%s: unable to read configuration file\n"),
- progname);
- exit(1);
- }
-
- if (SDBC_IOCTL(SDBC_ENABLE, &user_level_conf, 0, 0, 0, 0,
- &ustats) == SPCS_S_ERROR) {
- (void) fprintf(stderr, gettext("%s: cache enable failed\n"),
- progname);
- spcs_log("scm", &ustats, gettext("%s cache enable failed"),
- progname);
- sdbc_report_error(&ustats);
- exit(1);
- }
- spcs_log("scm", NULL, gettext("%s cache enable succeeded"),
- progname);
-#ifdef DEBUG
- (void) printf(gettext("%s: cache has been configured\n"), progname);
-#endif
-#ifdef WRTHRU_HINTS
- if (iscluster()) {
- /* Must writethru on a cluster, even if nvram configured */
- forced_wrthru = 1;
- }
-
- if (minidsp && forced_wrthru != -1) {
- /* Have minidsp with forced_wrthru hint. Set / Clear hint */
- if (SDBC_IOCTL(SDBC_SET_NODE_HINT, NSC_FORCED_WRTHRU,
- forced_wrthru, 0, 0, 0, &ustats) == SPCS_S_ERROR) {
- (void) fprintf(stderr,
- gettext("%s: set/clear forced_wrthru failed\n"),
- progname);
- sdbc_report_error(&ustats);
- } else if (forced_wrthru) {
- (void) printf(gettext("%s: Node option forced_wrthru "
- "now set.\n"), progname);
- } else {
- (void) printf(gettext("%s: Node option forced_wrthru "
- "now cleared.\n"), progname);
- }
- }
- if (no_forced_wrthru != -1) {
- if (SDBC_IOCTL(SDBC_SET_NODE_HINT, NSC_NO_FORCED_WRTHRU,
- no_forced_wrthru, 0, 0, 0, &ustats) == SPCS_S_ERROR) {
- (void) fprintf(stderr,
- gettext("%s: set/clear no_forced_wrthru "
- "failed\n"), progname);
- sdbc_report_error(&ustats);
- } else if (no_forced_wrthru) {
- (void) printf(gettext("%s: Node option no_forced_wrthru"
- " now set.\n"), progname);
- } else {
- (void) printf(gettext("%s: Node option no_forced_wrthru"
- " now cleared.\n"), progname);
- }
- }
-#endif
-
- /* do scmadm -O to cater for manual cache disable then enable */
- restore_hints();
-}
-
-void
-disable_sdbc()
-{
- spcs_s_info_t ustats;
-
- if (SDBC_IOCTL(SDBC_DISABLE, 0, 0, 0, 0, 0, &ustats) != SPCS_S_OK) {
- /*
- * If it wasn't already enabled, don't appear to fail
- * or users of this program might think the cache is
- * configured, when it actually isn't.
- */
- if (errno != SDBC_EDISABLE) {
- spcs_log("scm", &ustats,
- gettext("%s cache disable failed"), progname);
- sdbc_report_error(&ustats);
- exit(1);
- }
- }
-#ifdef DEBUG
- (void) printf(gettext("%s: cache has been deconfigured\n"), progname);
-#endif
- spcs_log("scm", NULL, gettext("%s cache disable succeeded"),
- progname);
-}
-
-static void
-get_version()
-{
- cache_version_t version;
- spcs_s_info_t ustats;
-
- if (SDBC_IOCTL(SDBC_VERSION, &version, 0, 0, 0, 0, &ustats) ==
- SPCS_S_ERROR) {
- (void) fprintf(stderr,
- gettext("%s: get cache version failed\n"), progname);
- sdbc_report_error(&ustats);
- exit(1);
- }
-#ifdef DEBUG
- (void) printf(gettext("Cache version %d.%d.%d.%d\n"),
- version.major, version.minor, version.micro, version.baseline);
-#else
- if (version.micro) {
- (void) printf(gettext("Cache version %d.%d.%d\n"),
- version.major, version.minor, version.micro);
- } else {
- (void) printf(gettext("Cache version %d.%d\n"),
- version.major, version.minor);
- }
-#endif
-}
-
-#ifdef DEBUG
-int
-toggle_flush(void)
-{
- int rc;
- spcs_s_info_t ustats;
-
- if ((rc = SDBC_IOCTL(SDBC_TOGGLE_FLUSH, 0, 0, 0,
- 0, 0, &ustats)) == SPCS_S_ERROR) {
- (void) fprintf(stderr,
- gettext("%s: toggle sdbc cache flush failed\n"),
- progname);
- sdbc_report_error(&ustats);
- exit(1);
- }
- return (rc);
-}
-#endif
diff --git a/usr/src/cmd/avs/sdbc/sd_diag.c b/usr/src/cmd/avs/sdbc/sd_diag.c
deleted file mode 100644
index 706f547226..0000000000
--- a/usr/src/cmd/avs/sdbc/sd_diag.c
+++ /dev/null
@@ -1,1169 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/* #include <version.h> SKK */
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/param.h>
-#include <sys/inttypes.h>
-#include <stdio.h>
-#include <strings.h>
-#include <fcntl.h>
-#include <sys/shm.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <nsctl.h>
-
-#include <sys/nsctl/sd_cache.h>
-#include <sys/nsctl/sd_conf.h>
-
-#include <stdlib.h>
-#include <thread.h>
-#include <synch.h>
-
-#define MAXPARTS 100 /* Max disks */
-#define MAXBUF 65536 /* Max buffer size in long words */
-#define DISKLIST "disk_config" /* Default config file */
-#define DEF_SIZE 8192 /* Default buffer size */
-#define DEF_LOOP 1000 /* Loops for test */
-#define RAND_LOOPS DEF_LOOP /* # of random ios to do */
-
-/*
- * >>>>>>>>> USER LEVEL SD CACHE DIAGNOSTICS <<<<<<<<<<
- *
- * Write and read data blocks w/multiple processes
- * Starts one process for each partition specified in
- * the config file
- */
-
-int buf1[MAXBUF];
-int buf2[MAXBUF];
-char name[MAXPARTS][80];
-int pattern[MAXPARTS];
-int bufsize = DEF_SIZE;
-int fba_num_bufsize;
-nsc_size_t loops = DEF_LOOP;
-nsc_size_t r_loops = RAND_LOOPS;
-int fsize = -1;
-int readercount = 3;
-int Rflag = O_EXCL;
-char config_file[32];
-
-int
-read_parts()
-{
- FILE *dfile;
- int partitions = 0;
- int i;
-
- dfile = fopen(config_file, "r");
- if (dfile == NULL) {
- (void) printf("cannot open file: %s\n", config_file);
- perror("fopen");
- exit(errno);
- }
- for (i = 0; i < MAXPARTS; i++) {
- if (fscanf(dfile, "%s %x", name[i], (uint_t *)&pattern[i]) ==
- EOF) {
- break;
- } else
- if (name[i][0] == '#' || strchr(name[i], '/') == NULL) {
- i--;
- continue;
- }
- partitions++;
- }
- (void) fclose(dfile);
- (void) printf("No. of partitions listed in file '%s' = %d\n\n",
- config_file, partitions);
- return (partitions);
-}
-
-void
-print_usage()
-{
- (void) printf("Usage:\n");
- (void) printf(
-"sd_diag [-R] [-b <bufsize>] [-d <datasize>] [-l <loops>] [-r <readers>]\n");
- (void) printf(
-" [-f <disk_config_file>] <test#>\n");
- (void) printf(" test 1 = random read/write\n");
- (void) printf(" 2 = random read/write/verify, read after write\n");
- (void) printf(" 3 = random read/write/verify,");
- (void) printf(" all reads after all writes\n");
- (void) printf(" 4 = sequential read/write\n");
- (void) printf(" 5 = sequential write/read/verify,");
- (void) printf(" all reads after all writes\n");
- (void) printf(
- " 6 = altenating top/bottom sequential read/write/verify\n");
- (void) printf(" 7 = multiple readers/1 random writer\n");
- (void) printf(" 8 = random writes\n");
- (void) printf(" 9 = sequential write of known data\n");
- (void) printf(" 10 = sequential copy of datasize disk/verify\n");
- (void) printf(" 11 = sequential read/verify test 9 data -");
- (void) printf(" then clear data with timestamp\n");
- (void) printf(" 12 = sequential read/verify test 9 data -");
- (void) printf(" no clear data\n");
- (void) printf("\n");
- (void) printf(" <bufsize> in bytes (minimum is 512 bytes)\n");
- (void) printf(" <datasize> in Mbytes per disk\n");
- (void) printf(" <loops> is count of reads/writes,\n");
- (void) printf(" loops = 0 tests entire datasize disk");
- (void) printf(" for sequential tests.\n");
- (void) printf(" loops = 0 performs %d I/Os for the random "
- "tests\n", RAND_LOOPS);
- (void) printf(" <readers> is count of readers for test #7 (default "
- "is 3).\n");
- (void) printf(" [ defaults: bufsize = %d bytes, loops = %d,",
- DEF_SIZE, DEF_LOOP);
- (void) printf(" datasize = disksize ]\n");
- (void) printf("\n");
- (void) printf(" -R : do nsc_reserve(), nsc_release(0 around each "
- "I/O\n");
-}
-
-void
-parse_opts(int argc, char *argv[])
-{
- extern char *optarg;
- int c;
-
- while ((c = getopt(argc, argv, "b:d:l:r:Rf:")) != -1) {
- switch (c) {
- case 'f':
- /* printf("\n%s", optarg); */
- (void) strcpy(config_file, optarg);
- break;
- case 'b':
- /* bufsize between 1*512 and 512*512 */
- bufsize = strtol(optarg, 0, 0);
- if (bufsize > (MAXBUF*4))
- bufsize = MAXBUF*4;
- else if (bufsize < FBA_SIZE(1))
- bufsize = FBA_SIZE(1);
- break;
- case 'd':
- /* convert datasize from Mb's to fba */
- fsize = strtol(optarg, 0, 0) * FBA_NUM(1 << 20);
- break;
- case 'l':
- loops = (nsc_size_t)strtoll(optarg, 0, 0);
- break;
- case 'r':
- /* count of readers for test 7 */
- readercount = strtol(optarg, 0, 0);
- break;
- case 'R':
- /* do reserve, release on a per io basis */
- Rflag = 0;
- break;
- case '?':
- print_usage();
- exit(0);
- }
- }
- bufsize &= ~FBA_MASK; /* multiple of 512 bytes for SECTMODE I/O */
- fba_num_bufsize = FBA_NUM(bufsize);
-
- /* set #ios for random io tests */
- if (loops != 0)
- r_loops = loops;
-
-}
-
-nsc_size_t
-set_part_size(char *path, nsc_fd_t *sdfd)
-{
- nsc_size_t filesize;
- int rc;
-
- rc = nsc_partsize(sdfd, &filesize); /* partsize in FBAs (512 bytes) */
- if (rc < 0 || filesize == 0) {
- (void) fprintf(stderr,
- "set_part_size: cannot access partition size");
- (void) fprintf(stderr, " for %s\n", path);
- (void) nsc_close(sdfd);
- exit(1);
- }
-
- (void) printf("Partition %s, size:%" NSC_SZFMT " blocks\n", path,
- filesize);
-
- if (fsize != -1 && fsize < filesize)
- filesize = fsize;
- filesize -= fba_num_bufsize;
- if (filesize < fba_num_bufsize) {
- (void) printf("ERROR: Max block size %" NSC_SZFMT "\n",
- filesize);
- (void) nsc_close(sdfd);
- exit(0);
- }
-
- return (filesize);
-}
-
-int
-do_sdtest1(int fd, nsc_size_t loops, nsc_size_t filesize)
-{
- nsc_off_t seekpos;
- nsc_size_t i;
- ssize_t r;
-
- for (i = 0; i < loops; i++) {
- seekpos = (
-#ifdef NSC_MULTI_TERABYTE
- ((nsc_off_t)rand() << 48) | ((nsc_off_t)rand() << 32) |
-#endif
- (rand() << 16) | rand()) % filesize;
- r = pwrite(fd, buf1, bufsize, (off_t)(seekpos << SCTRSHFT));
- if (r <= 0) {
- perror("Test1: write");
- return (1);
- }
- seekpos = (
-#ifdef NSC_MULTI_TERABYTE
- ((nsc_off_t)rand() << 48) | ((nsc_off_t)rand() << 32) |
-#endif
- (rand() << 16) | rand()) % filesize;
- r = pread(fd, buf2, bufsize, (off_t)(seekpos << SCTRSHFT));
- if (r <= 0) {
- perror("Test1: read");
- return (1);
- }
- }
- return (0);
-}
-
-void
-gen_data(int *buffer, int size)
-{
- int i;
-
- size /= 4;
- for (i = 0; i < size; i++)
- buffer[i] = rand() << 16 | rand();
-}
-
-int
-do_sdtest2(int fd, nsc_size_t loops, nsc_size_t filesize, int h)
-{
- nsc_off_t seekpos;
- int err = 0;
- ssize_t r;
- nsc_size_t i;
-
- for (i = 0; i < loops; i++) {
- seekpos = (
-#ifdef NSC_MULTI_TERABYTE
- ((nsc_off_t)rand() << 48) | ((nsc_off_t)rand() << 32) |
-#endif
- (rand() << 16) | rand()) % filesize;
- gen_data(buf1, bufsize);
- r = pwrite(fd, buf1, bufsize, (off_t)(seekpos << SCTRSHFT));
- if (r <= 0) {
- perror("Test2: write");
- err++;
- return (err);
- }
- r = pread(fd, buf2, bufsize, (off_t)(seekpos << SCTRSHFT));
- if (r <= 0) {
- perror("Test2: read");
- err++;
- return (err);
- }
- if (memcmp(buf1, buf2, bufsize)) {
- (void) printf("Test2: Data corruption,"
- " fd:%s, fpos:%" PRId64 ", len:%d\n",
- name[h], (int64_t)(seekpos << SCTRSHFT),
- bufsize);
- err++;
- }
- }
- return (err);
-}
-
-int
-do_sdtest3(int fd, nsc_size_t loops, nsc_size_t filesize, int h, nsc_fd_t *sdfd)
-{
- nsc_off_t *seekpos;
- int err = 0;
- nsc_size_t i;
- ssize_t r;
-
- seekpos = malloc(loops*sizeof (nsc_off_t));
- if (seekpos == NULL) {
- perror("Test3: malloc");
- (void) nsc_close(sdfd);
- exit(errno);
- }
- gen_data(buf1, bufsize);
-
- for (i = 0; i < loops; i++) {
- seekpos[i] = (
-#ifdef NSC_MULTI_TERABYTE
- ((nsc_off_t)rand() << 48) | ((nsc_off_t)rand() << 32) |
-#endif
- (rand() << 16) | rand()) % filesize;
- seekpos[i] -= seekpos[i] % fba_num_bufsize;
- r = pwrite(fd, buf1, bufsize, (off_t)(seekpos[i] << SCTRSHFT));
- if (r <= 0) {
- perror("Test3: write");
- err++;
- goto cleanup;
- }
- }
- for (i = 0; i < loops; i++) {
- buf2[0] = '\0'; /* clear buf to make sure something is read */
- r = pread(fd, buf2, bufsize, (off_t)(seekpos[i] << SCTRSHFT));
- if (r <= 0) {
- perror("Test3: read");
- err++;
- goto cleanup;
- }
- if (memcmp(buf1, buf2, bufsize)) {
- (void) printf("Data corruption, fd:%s, fpos:%" PRId64
- ", len:%d\n", name[h],
- (int64_t)(seekpos[i] << SCTRSHFT), bufsize);
- err++;
- }
- }
-
-cleanup:
- free(seekpos);
- return (err);
-}
-
-int
-do_sdtest4(int fd, nsc_size_t loops, nsc_size_t filesize)
-{
- ssize_t r;
- nsc_size_t i;
-
- /*
- * Do sequential reads/writes for loops number
- * of bufsize chunks, unless loops == 0, then do
- * entire disk.
- * 1. sequential reads from the top down,
- * 2. sequential writes from the top down,
- * 3. sequential reads from the bottom up,
- * 4. sequential writes from the bottom up.
- */
- if ((loops > (filesize / fba_num_bufsize)) || (!loops))
- loops = filesize / fba_num_bufsize; /* entire disk */
-
- for (i = 0; i < loops; i++) {
- r = pread(fd, buf2, bufsize, (i*fba_num_bufsize) << SCTRSHFT);
- if (r <= 0) {
- perror("Test4: read");
- return (1);
- }
- }
- for (i = 0; i < loops; i++) {
- r = pwrite(fd, buf1, bufsize, (i*fba_num_bufsize) << SCTRSHFT);
- if (r <= 0) {
- perror("Test4: write");
- return (1);
- }
- }
- for (i = loops - 1; i + 1 > 0; i--) {
- r = pread(fd, buf2, bufsize, (i*fba_num_bufsize) << SCTRSHFT);
- if (r <= 0) {
- perror("Test4: read");
- return (1);
- }
- }
- for (i = loops - 1; i + 1 > 0; i--) {
- r = pwrite(fd, buf1, bufsize, (i*fba_num_bufsize) << SCTRSHFT);
- if (r <= 0) {
- perror("Test4: write");
- return (1);
- }
- }
- return (0);
-}
-
-int
-do_sdtest5(int fd, nsc_size_t loops, nsc_size_t filesize, int h)
-{
- int err = 0;
- ssize_t r;
- nsc_size_t i;
-
- /*
- * Do sequential writes with verify reads for loops number
- * of bufsize chunks, unless loops == 0, then do
- * entire disk.
- * 1. sequential writes from the top down,
- * 2. sequential reads from the top down with verify,
- * 3. sequential writes from the bottom up,
- * 4. sequential reads from the bottom up with verify.
- */
- if ((loops > (filesize / fba_num_bufsize)) || (!loops))
- loops = filesize / fba_num_bufsize; /* entire disk */
-
- gen_data(buf1, bufsize);
-
- for (i = 0; i < loops; i++) {
- r = pwrite(fd, buf1, bufsize, (i*fba_num_bufsize) << SCTRSHFT);
- if (r <= 0) {
- perror("Test5: write");
- err++;
- return (err);
- }
- }
- for (i = 0; i < loops; i++) {
- buf2[0] = '\0'; /* clear buf to make sure something is read */
- r = pread(fd, buf2, bufsize, (i*fba_num_bufsize) << SCTRSHFT);
- if (r <= 0) {
- perror("Test5: read");
- err++;
- return (err);
- }
- if (memcmp(buf1, buf2, bufsize)) {
- (void) printf("Test5: Data corruption,"
- " fd:%s, fpos:%" NSC_SZFMT ", len:%d\n",
- name[h], i, bufsize);
- err++;
- }
- }
-
- gen_data(buf1, bufsize);
-
- for (i = loops - 1; i + 1 > 0; i--) {
- r = pwrite(fd, buf1, bufsize, (i*fba_num_bufsize) << SCTRSHFT);
- if (r <= 0) {
- perror("Test5: write");
- err++;
- return (err);
- }
- }
- for (i = loops - 1; i + 1 > 0; i--) {
- buf2[0] = '\0'; /* clear buf to make sure something is read */
- r = pread(fd, buf2, bufsize, (i*fba_num_bufsize) << SCTRSHFT);
- if (r <= 0) {
- perror("Test5: read");
- err++;
- return (err);
- }
- if (memcmp(buf1, buf2, bufsize)) {
- (void) printf("Test5: Data corruption,"
- " fd:%s, fpos:%" NSC_SZFMT ", len:%d\n",
- name[h], i, bufsize);
- err++;
- }
- }
- return (err);
-}
-
-
-int
-do_sdtest6(int fd, nsc_size_t loops, nsc_size_t filesize, int h)
-{
- int err = 0;
- nsc_size_t i;
- ssize_t r;
- nsc_size_t endloop = filesize / fba_num_bufsize;
- int buf3[MAXBUF];
- int buf4[MAXBUF];
- nsc_off_t top_pos, bottom_pos;
-
- /*
- * Do alternating top down and bottom up sequential writes
- * (working towards middle) and verify with reads
- * for loops number of bufsize chunks, unless loops == 0, then do
- * entire disk.
- */
- if ((loops > (filesize / fba_num_bufsize)) || (!loops))
- loops = filesize / fba_num_bufsize; /* entire disk */
-
- for (i = 0; i < loops; i++) {
- gen_data(buf1, bufsize);
- bottom_pos = i*fba_num_bufsize;
- r = pwrite(fd, buf1, bufsize, (off_t)(bottom_pos << SCTRSHFT));
- if (r <= 0) {
- perror("Test6: write");
- err++;
- return (err);
- }
- gen_data(buf2, bufsize);
- top_pos = (endloop - i - 1)*fba_num_bufsize;
-
- /* Make sure we don't collide in the middle */
-
- if (abs(top_pos - bottom_pos) < fba_num_bufsize)
- top_pos = bottom_pos + fba_num_bufsize;
-
- r = pwrite(fd, buf2, bufsize, (off_t)(top_pos << SCTRSHFT));
- if (r <= 0) {
- perror("Test6: write");
- err++;
- return (err);
- }
- r = pread(fd, buf3, bufsize, (off_t)(bottom_pos << SCTRSHFT));
- if (r <= 0) {
- perror("Test6: read");
- err++;
- return (err);
- }
- if (memcmp(buf1, buf3, bufsize)) {
- (void) printf("Data corruption(1), fd:%s, fpos:%"
- PRId64 ", len:%d\n", name[h],
- (int64_t)(bottom_pos << SCTRSHFT), bufsize);
- err++;
- }
- r = pread(fd, buf4, bufsize, (off_t)(top_pos << SCTRSHFT));
- if (r <= 0) {
- perror("Test6: read");
- return (1);
- }
- if (memcmp(buf2, buf4, bufsize)) {
- (void) printf("Test6: Data corruption(2),"
- " fd:%s, fpos:%" PRId64 ", len:%d\n",
- name[h], (int64_t)(top_pos << SCTRSHFT), bufsize);
- err++;
- }
- }
- return (err);
-}
-
-int shmid;
-
-#define MAXREADERS 32
-
-struct shm_struct {
- int writebuf[MAXBUF];
- volatile nsc_off_t writepos;
- int quit;
- int err;
- mutex_t err_mutex;
- int rd_done[MAXREADERS];
- int rd_done_mask[MAXREADERS];
-} *shm;
-
-#define WRITEBUF (shm->writebuf)
-#define WRITEPOS (shm->writepos)
-
-#define QUIT (shm->quit)
-#define ERR (shm->err)
-#define ERRMUTEX (shm->err_mutex)
-#define RD_DONE (shm->rd_done)
-#define RD_DONE_MASK (shm->rd_done_mask)
-
-#define LOCKWRITE
-#define LOCKREAD(i)
-
-/* Clear RD_DONE and Set WRITEPOS */
-#define FREEWRITE { \
- bzero(RD_DONE, sizeof (RD_DONE)); \
- WRITEPOS = wr_pos; }
-
-/* Reader i+1 marks himself as finished */
-#define FREEREAD(i) (RD_DONE[(i)] = 1)
-
-
-int
-do_sdtest7read(int fd, int h, int which)
-{
- int err;
- ssize_t r_rd;
- nsc_off_t curr_pos;
- nsc_size_t loop_cnt;
- err = 0; curr_pos = 0; loop_cnt = 0;
- for (;;) {
- /* Already read this? */
- if (curr_pos == WRITEPOS) {
- if (!QUIT) {
- continue;
- } else {
- /* Time to go! */
- /* printf("Quitting [%d]\n", which+1); */
- break;
- }
- }
-
- /* get location to read from */
- curr_pos = WRITEPOS;
-
- r_rd = pread(fd, buf1, bufsize, (curr_pos << SCTRSHFT));
- loop_cnt += 1;
- if (r_rd <= 0) {
- FREEREAD(which);
- perror("Test7: read");
- err += 1;
- continue;
- }
-
- if (memcmp(buf1, WRITEBUF, bufsize)) {
- FREEREAD(which);
- (void) printf("\nTest7: Data corruption, reader #%d, "
- "fd:%s, \
- fpos:%" PRId64 ", len:%d\n", which + 1, name[h],
- (int64_t)(curr_pos << SCTRSHFT), bufsize);
- err += 1;
- continue;
- }
-
- FREEREAD(which);
- }
-
- (void) printf(
- "Partition %s, Test 7, reader #%d: %d errors %lld loops\n",
- name[h], which+1, err, loop_cnt);
-
- if (err > 0) {
- (void) mutex_lock(&ERRMUTEX);
- ERR += err;
- (void) mutex_unlock(&ERRMUTEX);
- }
-
- if (err)
- return (1);
- else
- return (0);
-}
-
-
-int
-do_sdtest7write(int fd, nsc_size_t filesize, int h)
-{
- int err = 0;
- ssize_t r;
- nsc_off_t wr_pos;
-
- /* Wait for readers to finish */
- while (memcmp(RD_DONE, RD_DONE_MASK, readercount*sizeof (int)))
- ;
-
- gen_data(WRITEBUF, bufsize);
- wr_pos = (
-#ifdef NSC_MULTI_TERABYTE
- ((nsc_off_t)rand() << 48) | ((nsc_off_t)rand() << 32) |
-#endif
- (rand() << 16) | rand()) % filesize;
- r = pwrite(fd, WRITEBUF, bufsize, (off_t)(wr_pos << SCTRSHFT));
- if (r <= 0) {
- FREEWRITE;
- perror("Test7: write");
- return (1);
- }
- FREEWRITE;
-
- /* verify write */
- r = pread(fd, buf1, bufsize, (off_t)(wr_pos << SCTRSHFT));
- if (r <= 0) {
- perror("Test7: writer: read");
- return (1);
- }
-
-
- if (memcmp(buf1, WRITEBUF, bufsize)) {
- (void) printf("\nTest7: Data corruption in writer,"
- " fd:%s, fpos:%" PRId64 ", len:%d\n",
- name[h], (int64_t)(wr_pos << SCTRSHFT), bufsize);
- err++;
- }
-
-
- return (err);
-}
-
-void
-init_shm()
-{
- int i;
-
- /* Clear out everything */
- bzero(shm, sizeof (struct shm_struct));
-
- (void) mutex_init(&ERRMUTEX, USYNC_PROCESS, NULL);
-
- /* Set up mask (constant) to test reader doneness */
- for (i = 0; i < readercount; i++)
- RD_DONE_MASK[i] = 1;
-
- /* Mark all readers done - so writer can start */
- for (i = 0; i < readercount; i++)
- RD_DONE[i] = 1;
-}
-
-int
-do_sdtest7(int fd, nsc_size_t loops, nsc_size_t filesize, int h, nsc_fd_t *sdfd)
-{
- int r, i, err;
- nsc_size_t j;
-
- if ((shmid = shmget(IPC_PRIVATE, sizeof (struct shm_struct),
- IPC_CREAT | 0666)) < 0) {
- perror("shmget error: ");
- (void) nsc_close(sdfd);
- exit(1);
- }
-
- shm = (struct shm_struct *)shmat(shmid, NULL, 0);
- if (shm == (struct shm_struct *)-1) {
- perror("shmat error: ");
- (void) nsc_close(sdfd);
- exit(1); /* cleanup exits */
- }
-
- init_shm();
-
- /* Start Readers */
- for (i = 0; i < readercount; i++) {
- r = fork();
- if (r == 0) { /* child */
- (void) do_sdtest7read(fd, h, i);
- (void) nsc_close(sdfd);
- exit(0);
- } else
- continue;
- }
-
- /* Start Writer */
- srand(getpid()); err = 0;
- for (j = 0; j < loops; j++) {
- err += do_sdtest7write(fd, filesize, h);
- }
- QUIT = 1;
-
- (void) printf("\n\nPartition %s, Test 7, writer: %d errors\n",
- name[h], err);
-
- for (i = 0; i < readercount; i++)
- (void) wait(0);
-
- /* No lock needed here - everybody's finished */
- err += ERR;
-
- (void) mutex_destroy(&ERRMUTEX);
- (void) shmctl(shmid, IPC_RMID, 0);
- return (err);
-}
-
-int
-do_sdtest8(int fd, nsc_size_t loops, nsc_size_t filesize)
-{
- nsc_off_t seekpos;
- int err = 0;
- ssize_t r;
- nsc_size_t i;
-
- for (i = 0; i < loops; i++) {
- seekpos = (
-#ifdef NSC_MULTI_TERABYTE
- ((nsc_off_t)rand() << 48) | ((nsc_off_t)rand() << 32) |
-#endif
- (rand() << 16) | rand()) % filesize;
- gen_data(buf1, bufsize);
- r = pwrite(fd, buf1, bufsize, (off_t)(seekpos << SCTRSHFT));
- if (r <= 0) {
- perror("Test8: write");
- err++;
- return (err);
- }
- }
- return (err);
-}
-
-void
-gen_data_known(int *buffer, int size, int data)
-{
- int i;
-
- size /= 4;
- for (i = 0; i < size; i++)
- buffer[i] = data;
-}
-
-int
-do_sdtest9(int fd, nsc_size_t loops, nsc_size_t filesize, int h)
-{
- int err = 0;
- ssize_t r;
- nsc_off_t fba_offset;
- nsc_size_t i, wrapval;
-
- /*
- * Test 9 will write a given pattern over and over Test 11 or
- * Test 12 will read same pattern.
- */
- /* Large loop value that would cause write overflow will wrap */
-
- gen_data_known(buf1, bufsize, pattern[h]);
-
- wrapval = filesize / fba_num_bufsize;
-
- if (loops == 0)
- loops = wrapval; /* entire disk */
-
- for (i = 0; i < loops; i++) {
- fba_offset = i % wrapval;
- r = pwrite(fd, buf1, bufsize,
- (off_t)(fba_offset * fba_num_bufsize) << SCTRSHFT);
- if (r <= 0) {
- perror("Test9: write");
- err++;
- return (err);
- }
- }
- return (err);
-}
-
-int
-do_sdtest10(int fd1, int fd2, nsc_size_t loops, nsc_size_t filesize1,
- nsc_size_t filesize2, int h)
-{
- nsc_size_t filesize;
- int err = 0;
- nsc_size_t i;
- ssize_t r;
-
- /*
- * Do sequential copy of disk1 to disk2 for loops number
- * of bufsize chunks, unless loops == 0, then copy size of
- * the smaller disk.
- * Go back and verify that the two disks are identical.
- */
-
- filesize = (filesize1 < filesize2) ? filesize1 : filesize2;
- if ((loops > (filesize / fba_num_bufsize)) || (!loops))
- loops = filesize / fba_num_bufsize;
-
- /* copy disk1 to to disk2 */
- for (i = 0; i < loops; i++) {
- r = pread(fd1, buf1, bufsize,
- (off_t)(i*fba_num_bufsize) << SCTRSHFT);
- if (r <= 0) {
- perror("Test10: read");
- return (1);
- }
- r = pwrite(fd2, buf1, bufsize,
- (off_t)(i*fba_num_bufsize) << SCTRSHFT);
- if (r <= 0) {
- perror("Test10: write");
- return (1);
- }
- }
-
- /* verify disks are identical */
- for (i = 0; i < loops; i++) {
- buf1[0] = '\0'; /* clear buf to make sure something is read */
- r = pread(fd1, buf1, bufsize,
- (off_t)(i * fba_num_bufsize) << SCTRSHFT);
- if (r <= 0) {
- perror("Test10: read");
- return (1);
- }
- buf2[0] = 'x'; /* make sure something is read */
- r = pread(fd2, buf2, bufsize,
- (off_t)(i * fba_num_bufsize) << SCTRSHFT);
- if (r <= 0) {
- perror("Test10: read");
- return (1);
- }
- if (memcmp(buf1, buf2, bufsize)) {
- (void) printf("Test10: Data corruption,"
- " fd1:%s, fd2:%s fpos:%" NSC_SZFMT ", len:%d\n",
- name[2*h], name[2*h+1], i, bufsize);
- err++;
- }
- }
- return (err);
-}
-
-int
-buffcmp(int *b1, int *b2, int size)
-{
- int i;
-
- for (i = 0; i < size/4; i++) {
- if (b1[i] != b2[i]) {
- (void) printf("Word %d does not match b1=0x%x, "
- "b2=0x%x\n", i, b1[i], b2[i]);
- return (1);
- }
- }
- return (0);
-
-}
-
-int
-do_sdtest11(int fd, nsc_size_t loops, nsc_size_t filesize, int h)
-{
- int err = 0;
- nsc_size_t i;
- ssize_t r;
- int buf3[MAXBUF];
- int buf4[MAXBUF];
- int timestamp;
- time_t clock;
- struct tm *tm;
-
-
- /*
- * Test 9 will write a given pattern over and over Test 11 will read
- * same pattern and clear with timestamp data (MM:SS).
- */
-
- clock = time(NULL);
- tm = localtime(&clock);
- (void) ascftime((char *)&timestamp, "%M""%S", tm);
-
- gen_data_known(buf1, bufsize, pattern[h]);
- gen_data_known(buf4, bufsize, timestamp);
- if ((loops > filesize / fba_num_bufsize) || (!loops))
- loops = filesize / fba_num_bufsize; /* entire disk */
-
- for (i = 0; i < loops; i++) {
- r = pread(fd, buf3, bufsize,
- (off_t)(i*fba_num_bufsize) << SCTRSHFT);
- if (r <= 0) {
- perror("Test11: read");
- err++;
- return (err);
- }
- if (buffcmp(buf1, buf3, bufsize)) {
- (void) printf("Data corr, fd:%s, fpos:%" NSC_SZFMT
- ", len:%d\n", name[h], i, bufsize);
- err++;
- return (err);
- }
- r = pwrite(fd, buf4, bufsize,
- (off_t)(i*fba_num_bufsize) << SCTRSHFT);
- if (r <= 0) {
- perror("Test11: write");
- err++;
- return (err);
- }
- }
- return (err);
-}
-
-int
-do_sdtest12(int fd, nsc_size_t loops, nsc_size_t filesize, int h)
-{
- int err = 0;
- nsc_size_t i;
- ssize_t r;
- int buf3[MAXBUF];
-
- /*
- * Test 9 will write a given pattern over and over Test 12 will read
- * same pattern
- */
-
- gen_data_known(buf1, bufsize, pattern[h]);
- if ((loops > filesize / fba_num_bufsize) || (!loops))
- loops = filesize / fba_num_bufsize; /* entire disk */
-
- for (i = 0; i < loops; i++) {
- r = pread(fd, buf3, bufsize,
- (off_t)(i*fba_num_bufsize) << SCTRSHFT);
- if (r <= 0) {
- perror("Test12: read");
- err++;
- return (err);
- }
- if (buffcmp(buf1, buf3, bufsize)) {
- (void) printf("Data corr, fd:%s, fpos:%" NSC_SZFMT
- ", len:%d\n", name[h], i, bufsize);
- err++;
- return (err);
- }
- }
- return (err);
-}
-
-#ifdef lint
-int
-sd_diag_lintmain(int argc, char *argv[])
-#else
-int
-main(int argc, char *argv[])
-#endif
-{
- int procs;
- nsc_size_t filesize, filesize2;
- int fd, fd2, r, id, h, i;
- nsc_fd_t *sdfd, *sdfd2;
-
- if (argc < 2) {
- print_usage();
- exit(0);
- }
- (void) strcpy(config_file, DISKLIST);
- parse_opts(argc, argv);
-
- _nsc_nocheck();
- if ((procs = read_parts()) == 0)
- exit(0);
-
- id = strtol(argv[optind], 0, 0);
- if (id == 10) {
- /*
- * each process gets 2 disks and copies disk1 to disk2,
- * then goes back and verifies that the two disks are
- * identical.
- */
- if (procs < 2) {
- (void) printf("%s requires having at least 2 disks for test "
- "#10.\n", config_file);
- exit(0);
- }
-
- for (h = 0; h < procs/2; h++) {
- r = fork();
- if (r == 0) {
- srand(getpid());
-
-
- if (!(sdfd = nsc_open(name[2*h], NSC_CACHE,
- O_RDWR | Rflag))) {
- (void) fprintf(stderr,
- "sd_diag: Error opening %s\n", name[2*h]);
- exit(1);
- }
- fd = nsc_fileno(sdfd);
- if (fd == -1) {
- (void) fprintf(stderr,
- "sd_diag: Error opening %s\n", name[2*h]);
- (void) nsc_close(sdfd);
- exit(1);
- }
- filesize = set_part_size(name[2*h], sdfd);
- if (!(sdfd2 = nsc_open(name[2*h+1], NSC_CACHE,
- O_RDWR | Rflag))) {
- (void) fprintf(stderr,
- "sd_diag: Error opening %s\n", name[2*h+1]);
- exit(1);
- }
- fd2 = nsc_fileno(sdfd2);
- if (fd2 == -1) {
- (void) fprintf(stderr,
- "sd_diag: Error opening %s\n", name[2*h+1]);
- (void) nsc_close(sdfd2);
- exit(1);
- }
- filesize2 = set_part_size(name[2*h+1], sdfd2);
- (void) sleep(2);
- r = do_sdtest10(fd, fd2, loops, filesize, filesize2, h);
-
- (void) printf("Partitions %s and %s, Test %d,"
- " Completed %d errors\n",
- name[2*h], name[2*h+1], id, r);
- (void) nsc_close(sdfd);
- (void) nsc_close(sdfd2);
- exit(0);
- } else if (r == -1) {
- perror("fork");
- break;
- } else
- continue;
- } /* for */
- for (i = 0; i < h; i++)
- (void) wait(0);
- } else {
-
- for (h = 0; h < procs; h++) {
- r = fork();
- if (r == 0) {
- srand(getpid());
-
- id = strtol(argv[optind], 0, 0);
- if (!(sdfd = nsc_open(name[h], NSC_CACHE,
- O_RDWR | Rflag))) {
- (void) fprintf(stderr,
- "sd_diag: Error opening %s\n", name[h]);
- exit(1);
- }
- fd = nsc_fileno(sdfd);
-
- if (fd == -1) {
- (void) fprintf(stderr,
- "sd_diag: Error opening %s\n", name[h]);
- (void) nsc_close(sdfd);
- exit(1);
- }
- filesize = set_part_size(name[h], sdfd);
-
- (void) sleep(2);
-
-
- switch (id) {
- case 1:
- r = do_sdtest1(fd, r_loops, filesize);
- break;
- case 2:
- r = do_sdtest2(fd, r_loops, filesize, h);
- break;
- case 3:
- r = do_sdtest3(fd, r_loops, filesize, h, sdfd);
- break;
- case 4:
- r = do_sdtest4(fd, loops, filesize);
- break;
- case 5:
- r = do_sdtest5(fd, loops, filesize, h);
- break;
- case 6:
- r = do_sdtest6(fd, loops, filesize, h);
- break;
- case 7:
- r = do_sdtest7(fd, r_loops, filesize, h, sdfd);
- break;
- case 8:
- r = do_sdtest8(fd, r_loops, filesize);
- break;
- case 9:
- r = do_sdtest9(fd, loops, filesize, h);
- break;
- case 11:
- r = do_sdtest11(fd, loops, filesize, h);
- break;
- case 12:
- r = do_sdtest12(fd, loops, filesize, h);
- break;
- default:
- break;
- }
-
- (void) printf("Partition %s, Test %d, Completed %d "
- "errors\n", name[h], id, r);
- (void) nsc_close(sdfd);
- exit(r ? 1 : 0);
- } else if (r == -1) {
- perror("fork");
- break;
- } else
- continue;
- }
- for (i = 0; i < h; i++)
- (void) wait(0);
- }
-
- return (0);
-}
diff --git a/usr/src/cmd/avs/sdbc/sd_stats.c b/usr/src/cmd/avs/sdbc/sd_stats.c
deleted file mode 100644
index 211ce6c1d6..0000000000
--- a/usr/src/cmd/avs/sdbc/sd_stats.c
+++ /dev/null
@@ -1,594 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <strings.h>
-#include <curses.h>
-#include <signal.h>
-#include <fcntl.h>
-#include <locale.h>
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/nsctl/sdbc_ioctl.h>
-#include <sys/unistat/spcs_s_u.h>
-#include <sys/nsctl/sd_bcache.h>
-#include <sys/nsctl/sd_conf.h>
-
-extern void total_display(void);
-extern void display_cache(void);
-extern void wrefresh_file(WINDOW *, int);
-extern int is_dirty(void);
-extern int dual_stats(void);
-void checkbuf(int);
-void setup_ranges(char *);
-void prheading(int);
-extern int zero_nic(void);
-
-#ifdef m88k
-#define USEC_INIT() usec_ptr = (unsigned int *)timer_init()
-#define USEC_READ() (*usec_ptr)
-#else /* !m88k */
-#define USEC_INIT() USEC_START()
-#include <sys/time.h>
-static struct timeval Usec_time;
-static int Usec_started = 0;
-
-extern int higher(int);
-extern int is_dirty();
-extern int dual_stats();
-extern void total_display();
-extern void display_cache();
-extern void wrefresh_file(WINDOW *, int);
-void setup_ranges(char *);
-
-void prheading(int);
-void checkbuf(int);
-void quit(int);
-void leave(int);
-#pragma does_not_return(quit, leave)
-
-int sdbc_max_devices = 0;
-
-static void
-USEC_START()
-{
- if (!Usec_started) {
- (void) gettimeofday(&Usec_time, NULL);
- Usec_started = 1;
- }
-}
-
-static unsigned int
-USEC_READ()
-{
- struct timeval tv;
- if (!Usec_started)
- USEC_START();
-
- (void) gettimeofday(&tv, NULL);
- return (unsigned)((tv.tv_sec - Usec_time.tv_sec) * 1000000
- + (tv.tv_usec - Usec_time.tv_usec));
-}
-#endif /* m88k */
-
-int rev_flag = 0; /* Reverse video flag */
-int bold_flg = 0; /* Bold flag */
-int under_flg = 0; /* Underline flag */
-int errflg = 0; /* Error flag */
-int node_sw = 0; /* Per node switch */
-int toggle_total_sw = 0;
-int mirror_sw = 0; /* Dual copy switch */
-
-int kmemfd;
-int delay = 1; /* Display delay (seconds) */
-
-time_t *usec_ptr;
-time_t currtime = 0;
-int lasttime = 0;
-int Elapsed_Time = 0;
-
-static char *range;
-static int had_r_option = 0;
-int logfd = -1; /* screen output logging */
-extern int range_num;
-extern int screen;
-extern int dual_screen;
-int *on_off;
-int *dual_on_off;
-int *updates_prev;
-double *rate_prev;
-int *samples;
-_sd_stats_t *cs_cur;
-_sd_stats_t *cs_prev;
-_sd_stats_t *cs_persec;
-
-typedef struct {
- int lb, ub;
-} range_t;
-
-extern range_t ranges[];
-
-#ifdef lint
-int
-sd_stats_lintmain(int argc, char *argv[])
-#else
-int
-main(int argc, char *argv[])
-#endif
-{
- spcs_s_info_t ustats;
- struct timeval tout;
- fd_set readfds;
- char *errmessage, *ch;
- int c, period, prev;
- int count = 0, dflag = 0;
- int fd = fileno(stdin);
-
- errmessage = NULL;
-
- if (strcmp(argv[0], "sd_stats") != 0)
- errmessage = getenv("SD_STATS_USAGE");
-
- if (errmessage == NULL)
- errmessage = gettext("Usage: sd_stats [-Mz] "
- "[-d delay_time] [-l logfile] [-r range]");
-
- if (SDBC_IOCTL(SDBC_MAXFILES, &sdbc_max_devices,
- 0, 0, 0, 0, &ustats) == SPCS_S_ERROR) {
- if (ustats) { /* if SPCS_S_ERROR */
- spcs_s_report(ustats, stderr);
- spcs_s_ufree(&ustats);
- }
- (void) fprintf(stderr, gettext("cannot get maxfiles\n"));
- exit(1);
- }
- on_off = calloc(sdbc_max_devices, sizeof (int));
- dual_on_off = calloc(sdbc_max_devices, sizeof (int));
- updates_prev = calloc(sdbc_max_devices, sizeof (int));
- samples = calloc(sdbc_max_devices, sizeof (int));
- rate_prev = calloc(sdbc_max_devices, sizeof (double));
- cs_cur = malloc(sizeof (_sd_stats_t) +
- (sdbc_max_devices - 1) * sizeof (_sd_shared_t));
- cs_prev = malloc(sizeof (_sd_stats_t) +
- (sdbc_max_devices - 1) * sizeof (_sd_shared_t));
- cs_persec = malloc(sizeof (_sd_stats_t) +
- (sdbc_max_devices - 1) * sizeof (_sd_shared_t));
- range = malloc(100);
-
- if (!on_off || !dual_on_off || !updates_prev || !samples ||
- !rate_prev || !cs_cur || !cs_prev || !cs_persec || !range) {
- (void) fprintf(stderr, gettext("no free memory\n"));
- exit(1);
- }
-
- *range = '\0';
-
- while ((c = getopt(argc, argv, "DMzd:l:r:h")) != EOF) {
-
- prev = c;
- switch (c) {
-
- case 'd':
- delay = atoi(optarg);
- ch = optarg;
- while (*ch != '\0') {
- if (!isdigit(*ch))
- errflg++;
- ch++;
- }
- break;
-
- case 'l':
- logfd = open(optarg, O_CREAT|O_WRONLY|O_TRUNC, 0644);
- break;
-
- case 'r':
- ch = optarg;
- while (*ch != '\0') {
- if ((!isdigit(*ch)) && (*ch != ',') &&
- (*ch != ':'))
- errflg++;
- ch++;
- }
- if (errflg)
- break;
-
- range = realloc((char *)range,
- (strlen(range) + strlen(optarg) + 1)
- * sizeof (char));
-
- if (had_r_option)
- (void) strcat(range, ",");
- (void) strcat(range, optarg);
- had_r_option = 1;
- break;
-
- case 'z':
- if (SDBC_IOCTL(SDBC_ZAP_STATS, 0, 0, 0, 0, 0,
- &ustats) == SPCS_S_ERROR) {
- if (ustats) {
- spcs_s_report(ustats, stderr);
- spcs_s_ufree(&ustats);
- }
- }
-
- break;
-
- case 'D':
- dflag = 1;
- break;
-
- case 'M':
- mirror_sw = 1;
- break;
-
- case 'h':
- case '?':
- default :
- errflg++;
- break;
- }
- }
-
- if (errflg) {
- (void) fprintf(stderr, "%s\n", errmessage);
- exit(1);
- } else if (!prev) {
- if (argc > 1) {
- (void) fprintf(stderr, "%s\n", errmessage);
- exit(1);
- }
- }
-
- if (dflag) {
- exit(is_dirty());
- }
-
-
- /*
- * A few curses routines to setup screen and tty interface
- */
- (void) initscr();
- (void) cbreak();
- (void) noecho();
- (void) nonl();
- (void) erase();
- (void) clear();
- (void) refresh();
-
- setup_ranges(range);
-
- /*
- * Set signal handle
- */
- (void) sigset(SIGPIPE, leave);
- (void) sigset(SIGINT, leave);
- (void) sigset(SIGQUIT, leave);
- (void) signal(SIGFPE, leave);
- (void) signal(SIGSEGV, leave);
-
- USEC_INIT();
- currtime = USEC_READ();
-
- /*
- * Wait one second before reading the new values
- */
- (void) sleep(1);
-
- /*CONSTCOND*/
- while (1) {
-
- lasttime = currtime;
- currtime = USEC_READ();
-
- /*
- * If less that 1 second, force it to one second
- */
- if ((period = (currtime - lasttime) / 1000000) <= 0)
- period = 1;
-
- /*
- * Calculate new per/period values for statistics
- */
- Elapsed_Time += period;
-
- /*
- * Display new statistics
- */
- prheading(++count);
-
- if (mirror_sw) {
- if (dual_stats() < 0)
- mirror_sw = 0;
- } else if (toggle_total_sw)
- total_display();
- else
- display_cache();
-
- (void) move(0, 0);
- (void) refresh();
- if (logfd > -1) wrefresh_file(stdscr, logfd);
-
- FD_ZERO(&readfds);
- FD_SET(fd, &readfds);
- tout.tv_sec = delay;
- for (;;) {
- tout.tv_usec = 0;
- if (select(fd + 1, &readfds, (fd_set *)0, (fd_set *)0,
- &tout) <= 0)
- break;
- if ((c = getch()) == EOF) {
- (void) sleep(delay);
- break;
- }
- checkbuf(c);
- tout.tv_sec = 0;
- }
- (void) erase();
- }
-#pragma error_messages(off, E_STATEMENT_NOT_REACHED)
- return (0);
-#pragma error_messages(default, E_STATEMENT_NOT_REACHED)
-}
-
-void
-checkbuf(int c)
-{
- spcs_s_info_t ustats;
-
- switch (c) {
- case 'b' : /* ctrl b or b -- scroll backward */
- case 2 :
- {
- if (mirror_sw == 1) {
- if (dual_screen > 0)
- dual_screen--;
- break;
- }
- if (screen > 0)
- screen--;
- break;
- }
-
- case 'f' : /* ctrl f or f -- scroll forward */
- case 6 :
- {
- if (mirror_sw == 1) {
- dual_screen++;
- break;
- }
- screen++;
- break;
- }
-
- case 't':
- case 'T':
- if (mirror_sw == 1)
- mirror_sw = 0;
-
- toggle_total_sw ^= 1;
- break;
-
- case '-':
- case KEY_DOWN:
- if (delay > 1) {
- --delay;
- } else {
- (void) beep();
- }
- break;
-
- case '+':
- case KEY_UP:
- delay++;
- break;
-
- case 'C':
- case 0xc:
- (void) clearok(stdscr, TRUE);
- break;
-
- case 'B':
- if (bold_flg) {
- bold_flg = 0;
- (void) attroff(A_BOLD);
- } else {
- bold_flg = 1;
- (void) attron(A_BOLD);
- }
- break;
-
- case 'R':
- if (rev_flag) {
- rev_flag = 0;
- (void) attroff(A_REVERSE);
- } else {
- rev_flag = 1;
- (void) attron(A_REVERSE);
- }
- break;
-
- case 'z':
- if (SDBC_IOCTL(SDBC_ZAP_STATS, 0, 0, 0, 0, 0,
- &ustats) == SPCS_S_ERROR) {
- if (ustats) {
- spcs_s_report(ustats, stderr);
- spcs_s_ufree(&ustats);
- }
- }
- break;
-
- case 'm':
- case 'M':
- mirror_sw = mirror_sw ? 0 : 1;
- (void) clear();
- break;
- }
-}
-
-void
-prheading(int count)
-{
- time_t tim;
-
- /*
- * Print sample count in upper left corner
- */
- (void) mvprintw(0, 0, "SAMPLE %-8d", count);
-
- /*
- * Get time and print it in upper right corner
- */
- tim = time((time_t *)0);
- (void) mvprintw(0, 79 - 10, "%-8.8s\n", &(ctime(&tim)[11]));
-}
-
-/*ARGSUSED*/
-void
-leave(int status)
-{
- (void) sigignore(SIGPIPE);
- (void) sigignore(SIGALRM);
- /* clear(); */
- (void) move(LINES, 0);
- (void) refresh();
- if (logfd > -1) wrefresh_file(stdscr, logfd);
- quit(0);
-}
-
-void
-quit(int status)
-{
- (void) resetterm();
- (void) endwin();
- exit(status);
-}
-
-void
-setup_ranges(char *range)
-{
- int ndx;
- char chr1;
- char prev_chr = '\0';
- int got_colon = 0;
- int after_got_colon = 0;
- int got_comma = 0;
- int after_got_comma = 0;
- int number = 0;
- int prev_num = 0;
-
- if (range == NULL || (strlen(range) == 0)) {
- ranges[range_num].lb = 0;
- ranges[range_num].ub = sdbc_max_devices - 1;
- return;
- } else {
- ndx = 0;
- got_comma = 0;
- got_colon = 0;
- while ((chr1 = (range[ndx++])) != '\0') {
- switch (chr1) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- number = number*10 + (chr1 - '0');
- break;
- case ':':
- got_colon = 1;
- break;
- case ',':
- got_comma = 1;
- break;
- default: /* ignore any unknown characters */
- break;
- } /* switch */
- if (got_comma && after_got_colon) {
- after_got_colon = 0;
- got_comma = 0;
- if (number >= sdbc_max_devices)
- number = sdbc_max_devices - 1;
- ranges[range_num].lb = prev_num;
- ranges[range_num].ub = number;
- if (range_num == 99) break;
- range_num++;
- number = 0;
- } else if (got_colon && after_got_comma) {
- got_colon = 0;
- after_got_colon = 1;
- after_got_comma = 0;
- if (number >= sdbc_max_devices)
- number = sdbc_max_devices - 1;
- prev_num = number;
- number = 0;
- } else if (got_colon) {
- got_colon = 0;
- after_got_colon = 1;
- if ((prev_chr != '\0') && (prev_chr != ':')) {
- if (number >= sdbc_max_devices)
- number = sdbc_max_devices - 1;
- prev_num = number;
- number = 0;
- }
- } else if (got_comma) {
- got_comma = 0;
- after_got_comma = 1;
- after_got_colon = 0;
- if (number >= sdbc_max_devices)
- number = sdbc_max_devices -1;
- if ((prev_chr != '\0') && (prev_chr != ',')) {
- ranges[range_num].lb = number;
- ranges[range_num].ub = number;
- if (range_num == 99) break;
- range_num++;
- }
- number = 0;
- } /* if */
- prev_chr = chr1;
- } /* while */
- if (number >= sdbc_max_devices)
- number = sdbc_max_devices - 1;
- if (after_got_colon) {
- ranges[range_num].lb = prev_num;
- ranges[range_num].ub = number;
- } else {
- if ((after_got_comma) && (prev_chr == ','))
- range_num--;
- else {
- ranges[range_num].lb = number;
- ranges[range_num].ub = number;
- }
- }
- }
-}
diff --git a/usr/src/cmd/avs/sdbc/sd_trace.c b/usr/src/cmd/avs/sdbc/sd_trace.c
deleted file mode 100644
index 9b237ea057..0000000000
--- a/usr/src/cmd/avs/sdbc/sd_trace.c
+++ /dev/null
@@ -1,961 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <errno.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <strings.h>
-#include <stdlib.h>
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/nsctl/sdbc_ioctl.h>
-#include <sys/nsctl/rdc_ioctl.h>
-#include <sys/nsctl/sd_bcache.h>
-#include <sys/nsctl/sd_conf.h>
-#include <sys/nsctl/rdc_io.h>
-#include <sys/nsctl/rdc_bitmap.h>
-#include <sys/unistat/spcs_s_u.h>
-#include <curses.h>
-
-static rdc_status_t *rdc_status;
-static rdc_u_info_t *rdc_info;
-static int rdc_maxsets;
-static int rdc_enabled_sets;
-
-static unsigned prev_time, delta_time;
-#ifdef m88k
-extern unsigned *usec_ptr;
-#endif
-static int bright = 0;
-
-extern int sdbc_max_devices;
-
-extern _sd_stats_t *cs_cur;
-extern _sd_stats_t *cs_prev;
-extern _sd_stats_t *cs_persec;
-
-extern int *on_off;
-extern int *dual_on_off;
-extern int *updates_prev;
-extern double *rate_prev;
-extern int *samples;
-
-int range_num = 0;
-int screen = 0;
-int dual_screen = 0;
-static int rnum = 0;
-
-typedef struct {
- int lb, ub;
-} range_t;
-range_t ranges[100];
-
-extern int range_first();
-extern int range_next(int);
-extern int range_last();
-
-static int dual_initted = 0;
-static char status[11][30];
-
-unsigned dc_delta_time, dc_prev_time;
-
-#ifdef m88k
-#define USEC_INIT() usec_ptr = (unsigned int *)timer_init()
-#define USEC_READ() (*usec_ptr)
-#else /* !m88k */
-#define USEC_INIT() USEC_START()
-#include <sys/time.h>
-static struct timeval Usec_time;
-static int Usec_started = 0;
-
-void total_display(void);
-void disp_stats(void);
-void do_calc(void);
-void init_dual(void);
-void calc_time(void);
-void calc_completion(int, int, int);
-void disp_total_stats(void);
-void display_cache(void);
-
-#define DISPLEN 16
-
-static void
-USEC_START(void)
-{
- if (!Usec_started) {
- (void) gettimeofday(&Usec_time, NULL);
- Usec_started = 1;
- }
-}
-
-static unsigned int
-USEC_READ()
-{
- struct timeval tv;
- if (!Usec_started)
- USEC_START();
-
- (void) gettimeofday(&tv, NULL);
- return (unsigned)((tv.tv_sec - Usec_time.tv_sec) * 1000000 +
- (tv.tv_usec - Usec_time.tv_usec));
-}
-#endif /* m88k */
-
-#define SAMPLE_RATE 5
-
-/*
- * refresh curses window to file
- */
-void
-wrefresh_file(WINDOW *win, int fd)
-{
- char buf[8192], c, *cp = buf, *line, *blank, *empty;
- int x, y;
-
- empty = NULL; /* cull trailing empty lines */
- for (y = 0; y < win->_maxy; y++) {
- line = cp;
- blank = NULL; /* cull trailing blanks */
- for (x = 0; x < win->_maxx; x++) {
- c = (win->_y[y][x]) & A_CHARTEXT;
- if (c != ' ')
- blank = NULL;
- else if (blank == NULL)
- blank = cp;
- *cp++ = c;
- }
- if (blank)
- cp = blank;
- if (line != cp)
- empty = NULL;
- else if (empty == NULL)
- empty = cp + 1;
- *cp++ = '\n';
- }
- if (empty)
- cp = empty;
- *cp++ = '\f'; *cp++ = '\n'; *cp = '\0';
- /* cp is eliminated by short _maxy and _maxx, it won't overflow */
- /* LINTED, cp - buf won't be > INT32_MAX */
- (void) write(fd, buf, cp - buf);
-}
-
-
-int
-higher(int high)
-{
- int i;
-
- for (i = high + 1; i <= sdbc_max_devices; i++) {
- if (cs_cur->st_shared[i].sh_alloc)
- return (i);
- }
- return (0);
-}
-
-int
-is_dirty()
-{
- int i, dirty = 0;
- spcs_s_info_t ustats;
-
- if (SDBC_IOCTL(SDBC_STATS, cs_cur, 0, 0, 0, 0,
- &ustats) == SPCS_S_ERROR) {
- perror("Could not get stats from kernel");
- if (ustats) {
- spcs_s_report(ustats, stderr);
- spcs_s_ufree(&ustats);
- }
- return (-errno);
- }
- if (cs_cur->st_cachesize == 0)
- return (0);
-
- for (i = 0; i < cs_cur->st_count; i++) {
- if (cs_cur->st_shared[i].sh_alloc)
- dirty += cs_cur->st_shared[i].sh_numdirty;
- }
-
- return (dirty != 0);
-}
-
-void
-display_cache(void)
-{
- static int first = 1;
- spcs_s_info_t ustats;
-
- if (SDBC_IOCTL(SDBC_STATS, cs_cur, 0, 0, 0, 0, &ustats) ==
- SPCS_S_ERROR) {
- perror("sd_stats");
- if (ustats) {
- spcs_s_report(ustats, stderr);
- spcs_s_ufree(&ustats);
- }
- }
-
- do_calc();
- if (first) {
- prev_time = USEC_READ();
- first = 0;
- } else
- disp_stats();
-}
-
-void
-total_display(void)
-{
- spcs_s_info_t ustats;
-
- if (SDBC_IOCTL(SDBC_STATS, cs_cur, 0, 0, 0, 0, &ustats) ==
- SPCS_S_ERROR) {
- if (ustats) {
- spcs_s_report(ustats, stderr);
- spcs_s_ufree(&ustats);
- }
- perror("sd_stats");
- }
- disp_total_stats();
-}
-
-
-int
-range_first()
-{
- rnum = 0;
- return (ranges[rnum].lb);
-}
-
-int
-range_next(int cd)
-{
- if (ranges[rnum].ub > cd)
- return (cd + 1);
- if (range_num > rnum)
- rnum++;
- else
- return (cd + 1);
- return (ranges[rnum].lb);
-}
-
-int
-range_last() {
- return (ranges[range_num].ub);
-}
-
-
-void
-set_dual_on_off()
-{
- int i, j, ct = 0, newct = 0;
-
- for (i = range_first(); i < rdc_enabled_sets && i <= range_last();
- i = range_next(i)) {
- if (rdc_info[i].flags & RDC_ENABLED) {
- ct++;
- if (ct > dual_screen * ((LINES - 9) / 2))
- break;
- }
- }
- if (((i >= rdc_enabled_sets) ||
- (i > range_last())) && (dual_screen > 0)) {
- dual_screen--;
- set_dual_on_off();
- } else {
- bzero(dual_on_off, sdbc_max_devices * sizeof (int));
- for (j = i; j < rdc_enabled_sets && j <= range_last();
- j = range_next(j)) {
- if (rdc_info[j].flags & RDC_ENABLED) {
- newct++;
- if (newct <= (LINES - 9) / 2) {
- dual_on_off[j] = 1;
- } else
- break;
- }
- }
- }
-}
-
-
-void
-set_on_off()
-{
- int i, j, ct = 0, newct = 0;
-
- for (i = range_first(); i <= range_last(); i = range_next(i)) {
- if (cs_cur->st_shared[i].sh_alloc) {
- ct++;
- if (ct > screen*((LINES - 9) / 2))
- break;
- }
- }
- if ((i > range_last()) && (screen > 0)) {
- screen--;
- set_on_off();
- } else {
- bzero(on_off, sdbc_max_devices * sizeof (int));
- for (j = i; j <= range_last(); j = range_next(j)) {
- if (cs_cur->st_shared[j].sh_alloc) {
- newct++;
- if (newct <= (LINES - 9) / 2)
- on_off[j] = 1;
- else
- break;
- }
- }
- }
-}
-
-void
-disp_stats(void)
-{
- double read_s, write_s, access_s, readp, writep;
- double rmiss_s, wmiss_s;
- double elapsed = delta_time / 1000000.0;
- double kbps = elapsed * 1024.0; /* for Kbytes per second */
- int rtotal, wtotal, i, j;
- double throughput = 0.0, rthroughput = 0.0;
- double creads = 0.0, cwrites = 0.0;
- char status_bit, down = 0;
- int len;
- char fn[19];
-
- if (delta_time != 0) {
- read_s = cs_persec->st_rdhits / elapsed;
- write_s = cs_persec->st_wrhits / elapsed;
- rmiss_s = cs_persec->st_rdmiss / elapsed;
- wmiss_s = cs_persec->st_wrmiss / elapsed;
- access_s = (cs_persec->st_wrhits + cs_persec->st_rdhits +
- cs_persec->st_rdmiss + cs_persec->st_wrmiss) / elapsed;
- } else
- read_s = write_s = access_s = 0.0;
-
- rtotal = cs_persec->st_rdhits + cs_persec->st_rdmiss;
- wtotal = cs_persec->st_wrhits + cs_persec->st_wrmiss;
- if (rtotal != 0)
- readp = cs_persec->st_rdhits / (double)rtotal;
- else
- readp = 0.0;
-
- if (wtotal != 0) {
- writep = cs_persec->st_wrhits / (double)wtotal;
- } else
- writep = 0.0;
-
- set_on_off();
- if (cs_cur->st_cachesize == 0)
- (void) mvprintw(0, 20, "****** Storage Cache Disabled ******");
- else
- (void) mvprintw(0, 20, "****** Storage Cache ******");
- (void) mvprintw(2, 26, "disk_io cache write_blocks");
- (void) attron(A_UNDERLINE);
- (void) mvprintw(3, 1, " cd cached_partition reads writes reads writes"
- " dirty todisk failed");
- (void) attroff(A_UNDERLINE);
- for (i = 0, j = 0; j < cs_cur->st_count; i++) {
- if (i >= sdbc_max_devices)
- break;
- if (cs_cur->st_shared[i].sh_alloc) {
- cs_persec->st_shared[i].sh_disk_write /= kbps;
- cs_persec->st_shared[i].sh_disk_read /= kbps;
- cs_persec->st_shared[i].sh_cache_write /= kbps;
- cs_persec->st_shared[i].sh_cache_read /= kbps;
- rthroughput += cs_persec->st_shared[i].sh_disk_read;
- throughput += cs_persec->st_shared[i].sh_disk_write;
- creads += cs_persec->st_shared[i].sh_cache_read;
- cwrites += cs_persec->st_shared[i].sh_cache_write;
- if (!down)
- down = cs_cur->st_shared[i].sh_failed;
- if (cs_cur->st_shared[i].sh_failed && bright) {
- status_bit = '*';
- } else
- status_bit = ' ';
- if ((len = strlen(cs_cur->st_shared[i].sh_filename))
- > 15) {
- (void) strcpy(fn, "...");
- (void) strcat(fn,
- cs_cur->st_shared[i].sh_filename +
- len - 12);
- } else
- (void) strcpy(fn,
- cs_cur->st_shared[i].sh_filename);
- if (on_off[i]) {
- (void) mvprintw(4 + j, 1,
- "%3d %-15s%c %6d %6d %6d %6d %6d %6d %6d",
- cs_cur->st_shared[i].sh_cd,
- fn,
- status_bit,
- cs_persec->st_shared[i].sh_disk_read,
- cs_persec->st_shared[i].sh_disk_write,
- cs_persec->st_shared[i].sh_cache_read,
- cs_persec->st_shared[i].sh_cache_write,
- cs_cur->st_shared[i].sh_numdirty,
- cs_cur->st_shared[i].sh_numio,
- cs_cur->st_shared[i].sh_numfail);
- j++;
- }
- }
- }
- bright = !bright;
-
- (void) mvprintw(4 + j, 22, "------ ------ ------ ------");
- (void) mvprintw(5 + j, 6, " Kbytes/s total:%6d %6d %6d %6d",
- (int)rthroughput, (int)throughput,
- (int)creads, (int)cwrites);
- (void) mvprintw(7 + j, 1, "accesses/s");
- (void) mvprintw(7 + j, 15, "read/s write/s %%readh %%writeh");
-
- (void) attron(A_UNDERLINE);
- (void) mvprintw(8 + j, 1, " ");
- (void) mvprintw(8 + j, 13,
- " ");
- (void) mvprintw(8 + j, 13, "(misses/s) (misses/s)");
- (void) attroff(A_UNDERLINE);
-
- (void) mvprintw(9 + j, 0, "%10.2lf %7.2f %7.2f %6.1f %6.1f",
- access_s, read_s, write_s, readp * 100.0, writep * 100.0);
- (void) mvprintw(10 + j, 0, " (%7.2f ) (%7.2f )\n\n",
- rmiss_s, wmiss_s);
-
- if (down)
- (void) mvprintw(20 + j, 1, "* -- disk off-line");
-}
-
-void
-do_calc(void)
-{
- int i, j;
-
- delta_time = USEC_READ() - prev_time;
-
- cs_persec->st_rdhits = cs_cur->st_rdhits - cs_prev->st_rdhits;
- cs_persec->st_rdmiss = cs_cur->st_rdmiss - cs_prev->st_rdmiss;
- cs_persec->st_wrhits = cs_cur->st_wrhits - cs_prev->st_wrhits;
- cs_persec->st_wrmiss = cs_cur->st_wrmiss - cs_prev->st_wrmiss;
-
- for (i = 0, j = 0; j < cs_cur->st_count; i++) {
- if (i >= sdbc_max_devices)
- break;
- if (cs_cur->st_shared[i].sh_alloc) {
- cs_persec->st_shared[i].sh_disk_write =
- FBA_SIZE(cs_cur->st_shared[i].sh_disk_write -
- cs_prev->st_shared[i].sh_disk_write);
- cs_persec->st_shared[i].sh_disk_read =
- FBA_SIZE(cs_cur->st_shared[i].sh_disk_read -
- cs_prev->st_shared[i].sh_disk_read);
- cs_persec->st_shared[i].sh_cache_read =
- FBA_SIZE(cs_cur->st_shared[i].sh_cache_read -
- cs_prev->st_shared[i].sh_cache_read);
- cs_persec->st_shared[i].sh_cache_write =
- FBA_SIZE(cs_cur->st_shared[i].sh_cache_write -
- cs_prev->st_shared[i].sh_cache_write);
- j++;
- }
- }
- (void) memcpy((char *) cs_prev, (char *) cs_cur, sizeof (_sd_stats_t) +
- (sdbc_max_devices - 1) * sizeof (_sd_shared_t));
- prev_time = USEC_READ();
-}
-
-
-void
-init_dual(void)
-{
-#define IND_ENABLED 0
-#define IND_RESYNC 1
-#define IND_RESYNC_REVERSE 2
-#define IND_VOLUME_DOWN 3
-#define IND_MIRROR_DOWN 4
-#define IND_LOGGING 5
-#define IND_RESYNC_NEEDED 6
-#define IND_REV_RESYNC_NEEDED 7
-#define IND_BITMAP_FAILED 8
-#define IND_FULL_SYNC_NEEDED 9
-#define IND_FCAL_FAILED 10
- (void) strcpy(status[IND_ENABLED], "replicating");
- (void) strcpy(status[IND_RESYNC], "sync");
- (void) strcpy(status[IND_RESYNC_REVERSE], "rev sync");
- (void) strcpy(status[IND_VOLUME_DOWN], "volume down");
- (void) strcpy(status[IND_MIRROR_DOWN], "mirror down");
- (void) strcpy(status[IND_LOGGING], "logging");
- (void) strcpy(status[IND_RESYNC_NEEDED], "need sync");
- (void) strcpy(status[IND_REV_RESYNC_NEEDED], "need rev sync");
- (void) strcpy(status[IND_BITMAP_FAILED], "bitmap failed");
- (void) strcpy(status[IND_FULL_SYNC_NEEDED], "full sync needed");
- (void) strcpy(status[IND_FCAL_FAILED], "fcal failed");
- dual_initted = 1;
-}
-
-
-int
-rdc_get_maxsets(void)
-{
- rdc_status_t rdc_status;
- spcs_s_info_t ustatus;
- int rc;
-
- rdc_status.nset = 0;
- ustatus = spcs_s_ucreate();
-
- rc = RDC_IOCTL(RDC_STATUS, &rdc_status, 0, 0, 0, 0, ustatus);
- spcs_s_ufree(&ustatus);
-
- if (rc == SPCS_S_ERROR)
- return (-1);
-
- return (rdc_status.maxsets);
-}
-
-int
-dual_stats()
-{
- int ind, i, k, len;
- int stars, size, segs;
- int rdcindex;
- float pct;
- char fn[19];
- char *phost;
- char *shost;
- char *pfile;
- char *sfile;
- char lhost[16];
- spcs_s_info_t ustats = NULL;
-
- (void) gethostname(lhost, 16);
-
- if (rdc_maxsets <= 0)
- rdc_maxsets = rdc_get_maxsets();
-
- if (rdc_maxsets < 0)
- goto no_stats;
-
- if (!rdc_status) {
- rdc_status = malloc(sizeof (rdc_status_t) +
- (sizeof (rdc_set_t) * (rdc_maxsets - 1)));
- if (!rdc_status) {
-no_stats:
- (void) mvprintw(0, 20,
- "****** Dual Copy Not Available ******");
- return (-1);
- }
-
- rdc_info = rdc_status->rdc_set;
- }
-
- rdc_status->nset = rdc_maxsets;
- ustats = spcs_s_ucreate();
-
- size = RDC_IOCTL(RDC_STATUS, rdc_status, 0, 0, 0, 0, ustats);
- if (size == SPCS_S_ERROR) {
- if (ustats) {
- spcs_s_report(ustats, stderr);
- spcs_s_ufree(&ustats);
- }
- (void) mvprintw(0, 20, "****** Dual Copy Not Available ******");
- return (-1);
- }
- spcs_s_ufree(&ustats);
- rdc_enabled_sets = rdc_status->nset;
-
- if (!dual_initted)
- init_dual();
-
- set_dual_on_off();
-
- calc_time();
-
- (void) mvprintw(0, 20, "****** Dual Copy Statistics ******");
- (void) attron(A_UNDERLINE);
- (void) mvprintw(2, 0, "primary");
- (void) mvprintw(2, 22, "link status");
- (void) mvprintw(2, 36, "secondary");
- (void) mvprintw(2, 54, "dual copy status");
- (void) attroff(A_UNDERLINE);
-
- for (rdcindex = 0, k = 0; rdcindex < rdc_enabled_sets; rdcindex++) {
- if (!(rdc_info[rdcindex].flags & RDC_ENABLED) ||
- !dual_on_off[rdcindex])
- continue;
-
- if (rdc_info[rdcindex].sync_flags & RDC_VOL_FAILED)
- ind = IND_VOLUME_DOWN;
- else if (rdc_info[rdcindex].flags & RDC_FCAL_FAILED)
- ind = IND_FCAL_FAILED;
- else if (rdc_info[rdcindex].bmap_flags & RDC_BMP_FAILED)
- ind = IND_BITMAP_FAILED;
- else if (rdc_info[rdcindex].flags & RDC_LOGGING) {
- if (rdc_info[rdcindex].sync_flags &
- RDC_SYNC_NEEDED)
- ind = IND_RESYNC_NEEDED;
- else if (rdc_info[rdcindex].sync_flags &
- RDC_RSYNC_NEEDED)
- ind = IND_REV_RESYNC_NEEDED;
- else
- ind = IND_LOGGING;
- } else if ((rdc_info[rdcindex].flags & RDC_SLAVE) &&
- (rdc_info[rdcindex].flags & RDC_SYNCING)) {
- if (rdc_info[rdcindex].flags & RDC_PRIMARY)
- ind = IND_RESYNC_REVERSE;
- else
- ind = IND_RESYNC;
- } else if (rdc_info[rdcindex].flags & RDC_SYNCING) {
- if (rdc_info[rdcindex].flags & RDC_PRIMARY)
- ind = IND_RESYNC;
- else
- ind = IND_RESYNC_REVERSE;
- } else
- ind = IND_ENABLED;
-
- phost = rdc_info[rdcindex].primary.intf;
- pfile = rdc_info[rdcindex].primary.file;
- shost = rdc_info[rdcindex].secondary.intf;
- sfile = rdc_info[rdcindex].secondary.file;
-
- if ((len = strlen(phost)) > 8) {
- (void) mvprintw(4 + k, 0, ".%+7s:",
- phost + len - 7);
- } else
- (void) mvprintw(4 + k, 0, "%+8s:", phost);
-
- if ((len = strlen(pfile)) > DISPLEN) {
- (void) mvprintw(4 + k, 9, "...%-13s",
- pfile + len - DISPLEN + 3);
- } else
- (void) mvprintw(4 + k, 9, "%-16s", pfile);
-
- (void) attron(A_BOLD);
- (void) mvprintw(4 + k, 26, "*");
- (void) mvprintw(4 + k, 28, "*");
-
- (void) mvprintw(4 + k, 56, "%-8s", status[ind]);
- (void) attroff(A_BOLD);
-
- if (ind == IND_RESYNC_REVERSE) {
- if (bright && !(rdc_info[rdcindex].flags & RDC_LOGGING))
- (void) mvprintw(4 + k, 27, "<");
- if (rdc_info[rdcindex].flags & RDC_PRIMARY &&
- !(rdc_info[rdcindex].flags & RDC_LOGGING))
- calc_completion(rdcindex,
- rdc_info[rdcindex].bits_set, 4 + k);
- } else if (ind == IND_RESYNC) {
- if (bright && !(rdc_info[rdcindex].flags & RDC_LOGGING))
- (void) mvprintw(4 + k, 27, ">");
- if (rdc_info[rdcindex].flags & RDC_PRIMARY &&
- !(rdc_info[rdcindex].flags & RDC_LOGGING))
- calc_completion(rdcindex,
- rdc_info[rdcindex].bits_set, 4 + k);
- } else if (ind == IND_LOGGING)
- (void) mvprintw(4 + k, 27, ".");
- else if (ind == IND_ENABLED)
- (void) mvprintw(4 + k, 27, "=");
-
- if ((len = strlen(shost)) > 8) {
- (void) mvprintw(4 + k, 30, ".%+7s:",
- shost + len - 7);
- } else
- (void) mvprintw(4 + k, 30, "%+8s:", shost);
-
- if ((len = strlen(sfile)) > DISPLEN) {
- (void) mvprintw(4 + k, 39, "...%-13s",
- sfile + len - DISPLEN + 3);
- } else
- (void) mvprintw(4 + k, 39, "%-16s", sfile);
-
- k++;
- }
-
- k += 5;
- (void) attron(A_UNDERLINE);
- for (i = 0; i < 80; i++)
- (void) mvprintw(k, i, " ");
- k += 2;
- (void) mvprintw(k, 0, "partition");
- (void) mvprintw(k, 16, "recovery needed");
- (void) mvprintw(k, 48, "recovery completed");
- (void) attroff(A_UNDERLINE);
- k += 2;
-
- for (rdcindex = 0; rdcindex < rdc_enabled_sets; rdcindex++) {
- if (!(rdc_info[rdcindex].flags & RDC_ENABLED) ||
- !dual_on_off[rdcindex])
- continue;
-
- if (!(rdc_info[rdcindex].flags & RDC_PRIMARY)) {
- continue;
- }
- if (!(rdc_info[rdcindex].flags & RDC_SLAVE) &&
- !(rdc_info[rdcindex].flags & RDC_SYNCING) &&
- !(rdc_info[rdcindex].flags & RDC_LOGGING)) {
- continue;
- }
-
- len = strlen(rdc_info[rdcindex].secondary.file);
- if (len > 15) {
- (void) strcpy(fn, "...");
- (void) strcat(fn,
- rdc_info[rdcindex].secondary.file + len - 12);
- } else
- (void) strcpy(fn, rdc_info[rdcindex].secondary.file);
- (void) mvprintw(k, 0, "%-15s", fn);
-
- segs = FBA_TO_LOG_LEN(rdc_info[rdcindex].volume_size);
- pct = segs ?
- ((float)rdc_info[rdcindex].bits_set / (float)segs) : 0.0;
- stars = (int)(pct * 20.0);
- while (stars > 0) {
- (void) mvprintw(k, 16 + stars, "*");
- stars--;
- }
- (void) attron(A_BOLD);
- (void) mvprintw(k, 16, "[");
- (void) mvprintw(k, 37, "]");
- (void) attroff(A_BOLD);
- (void) mvprintw(k, 39, "%6.2f%%", pct * 100.0);
-
- if (rdc_info[rdcindex].flags & RDC_SYNCING)
- pct = ((float)rdc_info[rdcindex].sync_pos /
- (float)rdc_info[rdcindex].volume_size);
- else
- pct = 0.0;
- stars = (int)(pct * 20.0);
- while (stars > 0) {
- (void) mvprintw(k, 48 + stars, "*");
- stars--;
- }
- (void) attron(A_BOLD);
- (void) mvprintw(k, 48, "[");
- (void) mvprintw(k, 69, "]");
- (void) attroff(A_BOLD);
- (void) mvprintw(k, 70, "%6.2f%%", pct * 100.0);
- k++;
- }
- bright = !bright;
- return (0);
-}
-
-/*
- * Calculate a time interval in milliseconds using the
- * micosecond counter
- */
-void
-calc_time(void)
-{
- unsigned int cur;
-
- cur = USEC_READ();
- dc_delta_time = cur > dc_prev_time ? cur - dc_prev_time :
- cur + 0xFFFFFFFF - dc_prev_time;
- dc_delta_time /= 1000;
- dc_prev_time = cur;
-}
-
-/*
- * Calculate estimated time of completion of resync
- */
-void
-calc_completion(int cd, int updates_left, int l)
-{
- int delta_done;
- double rate;
- long time_left;
- long hours;
- long minutes;
- static int initted = 0;
-
- if (!initted) {
- updates_prev[cd] = updates_left;
- initted = 1;
- return;
- }
-
- /*
- * Caclulate updates since last check
- */
- delta_done = updates_prev[cd] - updates_left;
- updates_prev[cd] = updates_left;
-
- /*
- * If no updates, don't bother estimating completion time
- */
- if (delta_done <= 0) {
- samples[cd] = 0;
- return;
- }
-
- rate = delta_done * 1000.0 / dc_delta_time;
-
- /*
- * Calculate rate of updates as a weighted average
- * of previous and current rate
- */
- if (rate_prev[cd] && samples[cd] > SAMPLE_RATE)
- rate = (rate_prev[cd] * 4.0 + rate) / 5.0;
- rate_prev[cd] = rate;
- samples[cd]++;
-
- /*
- * Get enough samples before making estimate
- */
- if (samples[cd]++ < SAMPLE_RATE)
- return;
-
- time_left = (long)(updates_left/rate); /* time left in seconds */
-
- if (time_left < 0)
- return;
-
- hours = time_left / (60 * 60);
- time_left -= hours * (60 * 60);
- minutes = time_left / 60;
- time_left -= minutes * 60;
- (void) mvprintw(l, 67,
- "time %02d:%02d:%02d \n", hours, minutes, time_left);
-}
-
-void
-disp_total_stats(void)
-{
- unsigned int read_s, write_s, access_s;
- double readp, writep;
- unsigned int rmiss_s, wmiss_s;
- double kbps = 2.0;
- int rtotal, wtotal, i, j;
- unsigned int throughput = 0, rthroughput = 0, creads = 0, cwrites = 0;
- char status_bit, down = 0;
- int len;
- char fn[19];
-
- read_s = cs_cur->st_rdhits;
- write_s = cs_cur->st_wrhits;
- rmiss_s = cs_cur->st_rdmiss;
- wmiss_s = cs_cur->st_wrmiss;
- access_s = (read_s + write_s + rmiss_s + wmiss_s);
-
- rtotal = cs_cur->st_rdhits + cs_cur->st_rdmiss;
- wtotal = cs_cur->st_wrhits + cs_cur->st_wrmiss;
- if (rtotal != 0)
- readp = cs_cur->st_rdhits / (double)rtotal;
- else
- readp = 0.0;
-
- if (wtotal != 0)
- writep = cs_cur->st_wrhits / (double)wtotal;
- else
- writep = 0.0;
-
- set_on_off();
- (void) mvprintw(0, 14,
- "****** Storage Cache (Cumulative) ******");
- (void) mvprintw(2, 30, "disk_io cache");
- (void) attron(A_UNDERLINE);
- (void) mvprintw(3, 1,
- " cd cached_partition reads writes reads writes");
- (void) attroff(A_UNDERLINE);
- for (i = 0, j = 0; j < cs_cur->st_count; i++) {
- if (i >= sdbc_max_devices)
- break;
- if (cs_cur->st_shared[i].sh_alloc) {
- cs_cur->st_shared[i].sh_disk_write /= kbps;
- cs_cur->st_shared[i].sh_disk_read /= kbps;
- cs_cur->st_shared[i].sh_cache_write /= kbps;
- cs_cur->st_shared[i].sh_cache_read /= kbps;
- rthroughput += cs_cur->st_shared[i].sh_disk_read;
- throughput += cs_cur->st_shared[i].sh_disk_write;
- creads += cs_cur->st_shared[i].sh_cache_read;
- cwrites += cs_cur->st_shared[i].sh_cache_write;
- if (!down)
- down = cs_cur->st_shared[i].sh_failed;
- if (cs_cur->st_shared[i].sh_failed && bright)
- status_bit = '*';
- else
- status_bit = ' ';
- if ((len =
- strlen(cs_cur->st_shared[i].sh_filename)) > 15) {
- (void) strcpy(fn, "...");
- (void) strcat(fn,
- cs_cur->st_shared[i].sh_filename +
- len - 12);
- } else
- (void) strcpy(fn,
- cs_cur->st_shared[i].sh_filename);
-
- if (on_off[i]) {
- (void) mvprintw(4 + j, 1,
- "%3d %-15s%c %10u %10u %10u %10u",
- cs_cur->st_shared[i].sh_cd,
- fn,
- status_bit,
- cs_cur->st_shared[i].sh_disk_read,
- cs_cur->st_shared[i].sh_disk_write,
- cs_cur->st_shared[i].sh_cache_read,
- cs_cur->st_shared[i].sh_cache_write);
- j++;
- }
- }
- }
- bright = !bright;
-
- (void) mvprintw(4 + j, 22,
- "---------- ---------- ---------- ----------");
- (void) mvprintw(5 + j, 8, " Kbytes total:%10u %10u %10u %10u",
- (int)rthroughput, (int)throughput,
- (int)creads, (int)cwrites);
- (void) mvprintw(7 + j, 1, " accesses");
- (void) mvprintw(7 + j, 18, "read write %%readh %%writeh");
-
- (void) attron(A_UNDERLINE);
- (void) mvprintw(8 + j, 1, " ");
- (void) mvprintw(8 + j, 13,
- " ");
- (void) mvprintw(8 + j, 11, "( misses) ( misses)");
- (void) attroff(A_UNDERLINE);
-
- (void) mvprintw(9 + j, 0, "%10u %10u %10u %6.1f %6.1f",
- access_s, read_s, write_s, readp*100.0, writep*100.0);
- (void) mvprintw(10 + j, 0,
- " (%10u) (%10u)\n\n", rmiss_s, wmiss_s);
-
- (void) attron(A_UNDERLINE);
- (void) mvprintw(13 + j, 1, "cachesize blocksize");
- (void) attroff(A_UNDERLINE);
- (void) mvprintw(14 + j, 1, "%8dK %10d", cs_cur->st_cachesize / 1024,
- cs_cur->st_blksize);
-
- (void) attron(A_UNDERLINE);
- (void) mvprintw(16 + j, 1, "Write blocks available:");
- (void) attroff(A_UNDERLINE);
- (void) mvprintw(17 + j, 1, "Net 0: %6d", cs_cur->st_wlru_inq);
-
- (void) attron(A_UNDERLINE);
- (void) mvprintw(19 + j, 1, "LRU stats: Blocks Requeued Optimized");
- (void) attroff(A_UNDERLINE);
- (void) mvprintw(20 + j, 7, "%12d %12u %12u", cs_cur->st_lru_blocks,
- cs_cur->st_lru_req, cs_cur->st_lru_noreq);
-
- if (down)
- (void) mvprintw(25 + j, 1, "* -- disk off-line");
-}
diff --git a/usr/src/cmd/avs/sdbc/sdbc_dynmem.c b/usr/src/cmd/avs/sdbc/sdbc_dynmem.c
deleted file mode 100644
index f6d25a11f4..0000000000
--- a/usr/src/cmd/avs/sdbc/sdbc_dynmem.c
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- */
-
-/*
- * This program is strictly for demonstration purposes and not for
- * production use. It demonstrates how to access the dynamic memory
- * caching statistics and turning variables via the kstat library.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <stropts.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <memory.h>
-#include <string.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <signal.h>
-#include <locale.h>
-#include <kstat.h>
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/sysinfo.h>
-#include <sys/buf.h>
-#include <sys/vfs.h>
-#include <sys/dnlc.h>
-
-#define TRUE 1
-#define FALSE 0
-#define SDBC_KSTAT_MODULE "sdbc"
-#define SDBC_KSTAT_DYNMEM "dynmem"
-
-typedef struct {
- int instance;
- kstat_t *ksp;
- } KSTAT_INFO_DEF;
-
-typedef struct {
- kstat_named_t *knp;
- char *named;
- int newval;
- } DYNMEM_KNP_DEFN;
-
-typedef enum {
-MONITOR = 0,
-MAXLIST,
-AGECT1,
-AGECT2,
-AGECT3,
-SEC1,
-SEC2,
-SEC3,
-PCNT1,
-PCNT2,
-HDPCNT,
-ALLOC,
-DEALLOC,
-HISTORY,
-NODATA,
-CAND,
-DEALLOCS,
-HOSTS,
-PESTS,
-METAS,
-HOLDS,
-OTHERS,
-NOTAVAIL,
-DIRECTIVE,
-SIMPLECT
-} arglist_id;
-
-#define NO_VALUE -1
-
-DYNMEM_KNP_DEFN dynmem_knp[] = {
- NULL, "sdbc_monitor_dynmem", NO_VALUE,
- NULL, "sdbc_max_dyn_list", NO_VALUE,
- NULL, "sdbc_cache_aging_ct1", NO_VALUE,
- NULL, "sdbc_cache_aging_ct2", NO_VALUE,
- NULL, "sdbc_cache_aging_ct3", NO_VALUE,
- NULL, "sdbc_cache_aging_sec1", NO_VALUE,
- NULL, "sdbc_cache_aging_sec2", NO_VALUE,
- NULL, "sdbc_cache_aging_sec3", NO_VALUE,
- NULL, "sdbc_cache_aging_pcnt1", NO_VALUE,
- NULL, "sdbc_cache_aging_pcnt2", NO_VALUE,
- NULL, "sdbc_max_holds_pcnt", NO_VALUE,
- NULL, "sdbc_alloc_cnt", NO_VALUE,
- NULL, "sdbc_dealloc_cnt", NO_VALUE,
- NULL, "sdbc_history", NO_VALUE,
- NULL, "sdbc_nodatas", NO_VALUE,
- NULL, "sdbc_candidates", NO_VALUE,
- NULL, "sdbc_deallocs", NO_VALUE,
- NULL, "sdbc_hosts", NO_VALUE,
- NULL, "sdbc_pests", NO_VALUE,
- NULL, "sdbc_metas", NO_VALUE,
- NULL, "sdbc_holds", NO_VALUE,
- NULL, "sdbc_others", NO_VALUE,
- NULL, "sdbc_notavail", NO_VALUE,
- NULL, "sdbc_process_directive", NO_VALUE,
- NULL, "sdbc_simplect", NO_VALUE,
- NULL, NULL, NO_VALUE
- };
-
-/*
- * Print Usage
- */
-static void
-print_usage()
-{
- (void) printf("USAGE: wake - wakeup thread, hys - max hysteresis\n");
- (void) printf(" mon 1 - monitor shutdown\n");
- (void) printf(" 2 - monitor thread stats1\n");
- (void) printf(" 4 - monitor thread stats2\n");
- (void) printf(" age1 n - num cyc to full host aging and "
- "dealloc\n");
- (void) printf(" age2 n - num cyc to full meta aging and "
- "dealloc\n");
- (void) printf(" age3 n - num cyc to full one pg aging and "
- "dealloc\n");
- (void) printf(" sec1 n - sec1 aging time\n");
- (void) printf(" sec2 n - sec2 aging time\n");
- (void) printf(" sec3 n - sec3 aging time\n");
- (void) printf(" pcnt1 n - percent to sec1/sec2 trans\n");
- (void) printf(" pcnt2 n - percent to sec2/sec3 trans\n");
- (void) printf(" hdpcnt n - max percent of cents for holds\n");
- (void) printf(" list n - host+pest max len\n");
- (void) printf("No Args - print current settings only\n");
-}
-
-/*
- * Main
- */
-/* ARGSUSED */
-#ifdef lint
-int
-sd_dynmem_lintmain(int argc, char *argv[])
-#else
-int
-main(int argc, char *argv[])
-#endif
-{
- DYNMEM_KNP_DEFN *p_dynmem_knp;
- kstat_ctl_t *kctl;
- KSTAT_INFO_DEF info_ksp;
- int val;
- char **pargs, **cur_pargs;
-
- /*
- * grab and parse argument list
- */
- p_dynmem_knp = dynmem_knp;
- pargs = argv;
- while (*pargs) {
- (void) printf("pargs=%x - %s\n", (uint_t)pargs, *pargs);
-
- cur_pargs = pargs;
- pargs++;
-
- if (strcmp(*cur_pargs, "h") == 0) {
- print_usage();
- return (0);
- }
-
- if (strcmp(*cur_pargs, "wake") == 0) {
- if ((p_dynmem_knp+DIRECTIVE)->newval == NO_VALUE)
- (p_dynmem_knp+DIRECTIVE)->newval = 0;
- (p_dynmem_knp+DIRECTIVE)->newval |= 0x01;
- continue;
- }
-
- if (strcmp(*cur_pargs, "hys") == 0) {
- if ((p_dynmem_knp+DIRECTIVE)->newval == NO_VALUE)
- (p_dynmem_knp+DIRECTIVE)->newval = 0;
- (p_dynmem_knp+DIRECTIVE)->newval |= 0x02;
- continue;
- }
-
- if (strcmp (*cur_pargs, "mon") == 0) {
- val = atoi(*pargs);
- (void) printf("errno=%x, %s=%x\n", errno, *cur_pargs,
- val);
- pargs++;
- (p_dynmem_knp+MONITOR)->newval = val;
- }
-
- if (strcmp (*cur_pargs, "age1") == 0) {
- val = atoi(*pargs);
- (void) printf("errno=%x, %s=%x\n", errno, *cur_pargs,
- val);
- pargs++;
- (p_dynmem_knp+AGECT1)->newval = val;
- }
-
- if (strcmp(*cur_pargs, "age2") == 0) {
- val = atoi(*pargs);
- (void) printf("errno=%x, %s=%x\n", errno, *cur_pargs,
- val);
- pargs++;
- (p_dynmem_knp+AGECT2)->newval = val;
- }
-
- if (strcmp(*cur_pargs, "age3") == 0) {
- val = atoi(*pargs);
- (void) printf("errno=%x, %s=%x\n", errno, *cur_pargs,
- val);
- pargs++;
- (p_dynmem_knp+AGECT3)->newval = val;
- }
-
- if (strcmp (*cur_pargs, "sec1") == 0) {
- val = atoi(*pargs);
- (void) printf("errno=%x, %s=%x\n", errno, *cur_pargs,
- val);
- pargs++;
- if (val == 0)
- break;
- else {
- (p_dynmem_knp+SEC1)->newval = val;
- continue;
- }
- }
-
- if (strcmp(*cur_pargs, "sec2") == 0) {
- val = atoi(*pargs);
- pargs++;
- (void) printf("errno=%x, %s=%x\n", errno, *cur_pargs,
- val);
- if (val == 0)
- break;
- else {
- (p_dynmem_knp+SEC2)->newval = val;
- continue;
- }
- }
-
- if (strcmp(*cur_pargs, "sec3") == 0) {
- val = atoi(*pargs);
- pargs++;
- (void) printf("errno=%x, %s=%x\n", errno, *cur_pargs,
- val);
- if (val == 0)
- break;
- else {
- (p_dynmem_knp+SEC3)->newval = val;
- continue;
- }
- }
-
- if (strcmp(*cur_pargs, "pcnt1") == 0) {
- val = atoi(*pargs);
- pargs++;
- (void) printf("errno=%x, %s=%x\n", errno, *cur_pargs,
- val);
- if (val == 0)
- break;
- else {
- (p_dynmem_knp+PCNT1)->newval = val;
- continue;
- }
- }
-
- if (strcmp(*cur_pargs, "pcnt2") == 0) {
- val = atoi(*pargs);
- pargs++;
- (void) printf("errno=%x, %s=%x\n", errno, *cur_pargs,
- val);
- if (val == 0)
- break;
- else {
- (p_dynmem_knp+PCNT2)->newval = val;
- continue;
- }
- }
-
- if (strcmp(*cur_pargs, "hdpcnt") == 0) {
- val = atoi(*pargs);
- pargs++;
- (void) printf("errno=%x, %s=%x\n", errno, *cur_pargs,
- val);
- if (val < 0)
- break;
- else {
- (p_dynmem_knp+HDPCNT)->newval = val;
- continue;
- }
- }
-
- if (strcmp(*cur_pargs, "list") == 0) {
- val = atoi(*pargs);
- pargs++;
- (void) printf("errno=%x, %s=%x\n", errno, *cur_pargs,
- val);
- if (val == 0)
- break;
- else {
- (p_dynmem_knp+MAXLIST)->newval = val;
- continue;
- }
- }
- } /* while(*pargs && cl) */
-
- /*
- * open the kstat library
- */
- kctl = kstat_open();
- if (kctl == NULL) {
- (void) printf("kstat_open() failed\n");
- return (1);
- }
-
- /*
- * is the name module about
- */
- info_ksp.instance = 0;
- info_ksp.ksp = kstat_lookup(kctl, SDBC_KSTAT_MODULE, 0,
- SDBC_KSTAT_DYNMEM);
- if (info_ksp.ksp == NULL) {
- (void) printf("No module to report\n");
- return (1);
- }
-
- /*
- * using the info get a copy of the data
- */
- if (kstat_read(kctl, info_ksp.ksp, NULL) == -1) {
- (void) printf("Can't read kstat\n");
- return (1);
- }
-
- /*
- * print the current data
- */
- p_dynmem_knp = dynmem_knp;
- while (p_dynmem_knp->named) {
- p_dynmem_knp->knp =
- kstat_data_lookup(info_ksp.ksp, p_dynmem_knp->named);
- if (p_dynmem_knp->knp == NULL) {
- (void) printf("kstat_data_lookup(%s) failed\n",
- p_dynmem_knp->named);
- return (1);
- } else {
- (void) printf("%s: %x\n", p_dynmem_knp->named,
- (uint_t)p_dynmem_knp->knp->value.ul);
- p_dynmem_knp++;
- }
- }
-
- /*
- * modify the data and write it back
- */
- p_dynmem_knp = dynmem_knp;
- while (p_dynmem_knp->named) {
- if (p_dynmem_knp->newval != NO_VALUE)
- p_dynmem_knp->knp->value.ul = p_dynmem_knp->newval;
- p_dynmem_knp++;
- }
-
- if (kstat_write(kctl, info_ksp.ksp, NULL) == -1) {
- (void) printf("kstat_write() failed\n");
- return (1);
- }
-
- (void) printf("Finished (h for help)\n");
- return (0);
-}
diff --git a/usr/src/cmd/avs/sdbc/sdbc_ioctl.c b/usr/src/cmd/avs/sdbc/sdbc_ioctl.c
deleted file mode 100644
index baa0858236..0000000000
--- a/usr/src/cmd/avs/sdbc/sdbc_ioctl.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * SDBC user level ioctl interface
- */
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <strings.h>
-
-#include <sys/nsctl/sd_cache.h>
-#include <sys/nsctl/sd_conf.h>
-#include <sys/nsctl/sdbc_ioctl.h>
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_u.h>
-
-#include <sys/nsctl/sv.h>
-#include <sys/nsctl/sv_impl.h>
-
-
-const char *__sdbc_dev = "/dev/sdbc";
-static int __sdbc_fd;
-
-
-static int
-__sdbc_open(void)
-{
- int fd;
-
- fd = open("/dev/nsctl", O_RDONLY);
- if (fd >= 0)
- (void) close(fd);
-
- fd = open(__sdbc_dev, O_RDONLY);
- if (fd < 0)
- return (-1);
-
- return (__sdbc_fd = fd);
-}
-
-
-static void
-sv_list()
-{
- sv_name_t svn[1];
- sv_name_t *svn_system;
- sv_list_t svl;
- static int fd = -1;
-
- if (fd < 0)
- fd = open(SV_DEVICE, O_RDONLY);
- if (fd < 0)
- return;
-
- bzero(&svl, sizeof (svl));
- bzero(&svn[0], sizeof (svn));
-
- svl.svl_names = &svn[0];
- svl.svl_error = spcs_s_ucreate();
-
- if (ioctl(fd, SVIOC_LIST, &svl) < 0)
- return;
-
- svn_system = calloc(svl.svl_maxdevs, sizeof (*svn));
- if (svn_system == NULL)
- return;
-
- /* Grab the system list from the driver */
- svl.svl_count = svl.svl_maxdevs;
- svl.svl_names = svn_system;
-
- (void) ioctl(fd, SVIOC_LIST, &svl);
-
- free(svn_system);
- spcs_s_ufree(&svl.svl_error);
-}
-
-
-int
-sdbc_ioctl(long cmd, long a0, long a1, long a2, long a3, long a4,
- spcs_s_info_t *ustatus)
-{
- _sdbc_ioctl_t args;
- int rc;
-
- *ustatus = NULL;
-
- if (!__sdbc_fd && __sdbc_open() < 0)
- return (-1);
-
- switch (cmd) {
- /*
- * These ioctls work on open cache descriptors. The sv_list() function
- * has the side-effect of re-opening all configured descriptors.
- * Without this call, devices seem to "disappear" from the system when
- * certain reconfiguration operations, for example II or SNDR disable,
- * are done.
- * It does rely on SV being configured, so in an STE-only environment
- * the disappearing will still seem to happen.
- */
- case SDBC_SET_CD_HINT:
- case SDBC_GET_CD_HINT:
- case SDBC_STATS:
- case SDBC_GET_CD_BLK:
- case SDBC_INJ_IOERR:
- case SDBC_CLR_IOERR:
- sv_list();
- break;
-
- default:
- break;
- }
-
- args.arg0 = a0;
- args.arg1 = a1;
- args.arg2 = a2;
- args.arg3 = a3;
- args.arg4 = a4;
- args.magic = _SD_MAGIC; /* for versioning */
- args.sdbc_ustatus = spcs_s_ucreate();
-
- if ((rc = ioctl(__sdbc_fd, cmd, &args)) < 0) {
- *ustatus = args.sdbc_ustatus;
- } else {
- spcs_s_ufree(&args.sdbc_ustatus);
- *ustatus = NULL;
- }
-
- return (rc);
-}
diff --git a/usr/src/cmd/avs/sv/Makefile b/usr/src/cmd/avs/sv/Makefile
deleted file mode 100644
index 150d63e925..0000000000
--- a/usr/src/cmd/avs/sv/Makefile
+++ /dev/null
@@ -1,94 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-DYNPROG= svadm svboot
-
-include ../../Makefile.cmd
-include ../Makefile.com
-
-PROG = $(DYNPROG)
-LPROG = $(PROG:%=%.li)
-
-SUBDIRS= etc
-
-svadm := POBJS = svadm.o
-svboot := POBJS = svboot.o
-
-OBJS= svadm.o svboot.o
-SRCS= $(OBJS:%.o=%.c)
-POFILE = sv_all.po
-POFILES = $(OBJS:%.o=%.po)
-
-svadm := LDLIBS += -lunistat -ldscfg
-svboot := LDLIBS += -lunistat -ldscfg
-
-CFLAGS += -v
-LINTFLAGS += -erroff=E_NAME_USED_NOT_DEF2
-LINTFLAGS += -erroff=E_SEC_SCANF_UNBOUNDED_COPY
-LINTFLAGS += -erroff=E_SEC_PRINTF_VAR_FMT
-ROOTLINK1 = $(ROOTUSRSBIN)/svadm
-ROOTLINK2 = $(ROOTUSRSBIN)/svboot
-
-all := TARGET= all
-install := TARGET= install
-clean := TARGET= clean
-clobber := TARGET= clobber
-lint := TARGET= lint
-
-.KEEP_STATE:
-
-.PARALLEL: $(OBJS)
-
-all: $(SUBDIRS) $(PROG) $(POFILES)
-
-install: $(SUBDIRS) all $(ROOTPROG) $(ROOTLINK1) $(ROOTLINK2)
-
-lint: $(SUBDIRS) $(LPROG)
-
-clean: $(SUBDIRS)
- $(RM) *.o $(POFILE)
-
-$(PROG): $$(POBJS)
- $(LINK.c) $(POBJS) -o $@ $(LDLIBS)
- $(POST_PROCESS)
-
-$(POFILE): $(POFILES)
- $(RM) $@
- $(CAT) $(POFILES) > $@
-
-$(SUBDIRS): FRC
- @cd $@; pwd; $(MAKE) $(TARGET)
-
-$(LPROG):
- $(LINT.c) $(@:%.li=%.c) $(LDLIBS)
-
-$(ROOTLINK1): $(ROOTUSRSBIN) $(ROOTPROG)
- -$(RM) $@; $(LN) $(ROOTBIN)/svadm $@
-
-$(ROOTLINK2): $(ROOTUSRSBIN) $(ROOTPROG)
- -$(RM) $@; $(LN) $(ROOTBIN)/svboot $@
-
-FRC:
-
-include ../../Makefile.targ
diff --git a/usr/src/cmd/avs/sv/etc/Makefile b/usr/src/cmd/avs/sv/etc/Makefile
deleted file mode 100644
index d027aedca9..0000000000
--- a/usr/src/cmd/avs/sv/etc/Makefile
+++ /dev/null
@@ -1,69 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-include ../../../Makefile.cmd
-include ../../Makefile.com
-
-SHFILES = sv sv.cluster
-ROOTINIT_D = $(ROOTETC)/init.d
-
-FILEMODE = 0744
-
-ROOTINIT_DPROG1 = $(ROOTINIT_D)/sv
-ROOTINIT_DPROG2 = $(ROOTINIT_D)/sv.cluster
-
-.KEEP_STATE:
-
-all: $(SHFILES)
-
-install: all $(ROOTINIT_DPROG1) $(ROOTINIT_DPROG2) $(CLUSTERSBINDIR) \
- $(CLUSTERLIBSTOPDIR) $(CLUSTERLIBSTARTDIR) $(ROOTLIBSVCMETHOD)
- -$(RM) $(CLUSTERLIBDSCFGSTOPDIR)/10sv
- -$(RM) $(CLUSTERLIBDSCFGSTARTDIR)/15sv
- -$(RM) $(CLUSTERSBINDIR)/sv
- -$(RM) $(ROOTLIBSVCMETHOD)/svc-sv
- -$(SYMLINK) ../../../sbin/sv $(CLUSTERLIBDSCFGSTOPDIR)/10sv
- -$(SYMLINK) ../../../sbin/sv $(CLUSTERLIBDSCFGSTARTDIR)/15sv
- $(LN) $(ROOTINIT_D)/sv $(ROOTLIBSVCMETHOD)/svc-sv
- $(CP) $(ROOTINIT_D)/sv.cluster $(CLUSTERSBINDIR)/sv
-
-$(ROOTINIT_DPROG1): sv
- $(INS.file) sv
-
-$(ROOTINIT_DPROG2): sv.cluster
- $(INS.file) sv.cluster
-
-$(CLUSTERLIBSTOPDIR):
- $(INS.dir)
-
-$(CLUSTERLIBSTARTDIR):
- $(INS.dir)
-
-lint:
-
-clean:
- $(RM) $(SHFILES)
-
-clobber: clean
- $(RM) $(ROOTINIT_DPROG1) $(ROOTINIT_DPROG2)
diff --git a/usr/src/cmd/avs/sv/etc/sv.cluster.sh b/usr/src/cmd/avs/sv/etc/sv.cluster.sh
deleted file mode 100644
index 272ae7f7ba..0000000000
--- a/usr/src/cmd/avs/sv/etc/sv.cluster.sh
+++ /dev/null
@@ -1,77 +0,0 @@
-#!/usr/bin/ksh
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-if [ ! -d /usr/sbin -o ! -d /usr/bin ]
-then
- exit 1
-fi
-
-# Constants
-
-SVBOOT=/usr/sbin/svboot
-SVCS=/usr/bin/svcs
-SVCS_NAME=system/nws_sv
-
-# Functions
-
-# main program
-
-# Determine if SMF service is online
-#
-ONLINE=`$SVCS -D $SVCS_NAME 2>>/dev/null | grep "^online"`
-if [ -z $ONLINE ]
-then
- echo "$SVCS_NAME not online"
- exit 1
-fi
-
-if [[ ! -x $SVBOOT ]]
-then
- echo "$0: cannot find $SVBOOT"
- exit 1
-fi
-
-if [[ -z "$2" ]]
-then
- opt=usage
-else
- opt=$1
-fi
-
-case "$opt" in
-'start')
- $SVBOOT -C "$2" -r
- ;;
-
-'stop')
-
- $SVBOOT -C "$2" -s
- ;;
-
-*)
- echo "Usage: $0 { start | stop } cluster_resource"
- exit 1
- ;;
-esac
diff --git a/usr/src/cmd/avs/sv/etc/sv.sh b/usr/src/cmd/avs/sv/etc/sv.sh
deleted file mode 100644
index d9c952577c..0000000000
--- a/usr/src/cmd/avs/sv/etc/sv.sh
+++ /dev/null
@@ -1,122 +0,0 @@
-#!/sbin/sh
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-[ ! -d /usr/sbin -o ! -d /usr/bin ] && exit
-
-# Constants
-
-SVBOOT=/usr/sbin/svboot
-SVCS=/usr/bin/svcs
-DSCFG_DEPEND_NOCHK="/tmp/.dscfgadm_pid"
-OS_MINOR=`/usr/bin/uname -r | /usr/bin/cut -d '.' -f2`
-
-. /lib/svc/share/smf_include.sh
-
-# Make sure prior SMF dependents are not 'online'
-# $1 = name of SMF service to validate dependents
-#
-do_smf_depends ()
-{
- times=0
- count=1
-
- if [ $OS_MINOR -ge 11 ]
- then
- return 0
- elif [ -f $DSCFG_DEPEND_NOCHK ]
- then
- for pid in `pgrep dscfgadm`
- do
- if [ `grep -c $pid $DSCFG_DEPEND_NOCHK` -gt 0 ]
- then
- return 0
- fi
- done
- elif [ `ps -ef | grep preremove | grep -c SUNWspsvu` -gt 0 ]
- then
- return 0
-
- fi
-
-
- while [ $count -ne 0 ]
- do
- count=`$SVCS -o STATE -D $1 2>>/dev/null | grep "^online" | wc -l`
- if [ $count -ne 0 ]
- then
- # Output banner after waiting first 5 seconds
- #
- if [ $times -eq 1 ]
- then
- echo "Waiting for $1 dependents to be 'offline'"
- $SVCS -D $1 2>>/dev/null | grep "^online"
- fi
-
- # Has it been longer then 5 minutes? (60 * 5 secs.)
- #
- if [ $times -eq 60 ]
- then
- echo "Error: Failed waiting for $1 dependents to be 'offline'"
- $SVCS -D $1 2>>/dev/null | grep "^online"
- exit $SMF_EXIT_ERR_FATAL
- fi
-
- # Now sleep, giving other services time to stop
- #
- sleep 5
- times=`expr $times + 1`
- fi
- done
- return 0
-}
-
-# main program
-
-if [ ! -x $SVBOOT ]
-then
- echo "$0: cannot find $SVBOOT"
- exit $SMF_EXIT_MON_OFFLINE
-fi
-
-case "$1" in
-'start')
-
- $SVBOOT -r
- ;;
-
-'stop')
-
- do_smf_depends "system/nws_sv"
-
- $SVBOOT -s
- ;;
-
-*)
- echo "Usage: $0 { start | stop }"
- exit $SMF_EXIT_MON_OFFLINE
- ;;
-esac
-
-exit $SMF_EXIT_OK
diff --git a/usr/src/cmd/avs/sv/svadm.c b/usr/src/cmd/avs/sv/svadm.c
deleted file mode 100644
index 4fee03b277..0000000000
--- a/usr/src/cmd/avs/sv/svadm.c
+++ /dev/null
@@ -1,1515 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mkdev.h>
-#include <sys/param.h>
-#include <sys/wait.h>
-#include <fcntl.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <strings.h>
-#include <errno.h>
-#include <stdio.h>
-#include <locale.h>
-#include <unistd.h>
-#include <search.h>
-#include <libgen.h>
-#include <nsctl.h>
-
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_u.h>
-#include <sys/unistat/spcs_errors.h>
-
-#include <sys/nsctl/sv.h>
-#include <sys/nsctl/sv_impl.h>
-
-#include <sys/nsctl/cfg.h>
-#include <sys/nsctl/nsc_hash.h>
-
-#include "../sv/svadm.h"
-
-
-static int sv_max_devices;
-
-
-/*
- * support for the special cluster tag "local" to be used with -C in a
- * cluster for local volumes.
- */
-
-#define SV_LOCAL_TAG "local"
-
-static int sv_islocal;
-
-/*
- * libcfg access.
- */
-
-static CFGFILE *cfg; /* libcfg file pointer */
-static int cfg_changed; /* set to 1 if we need to commit changes */
-
-static char *cfg_cluster_tag; /* local cluster tag */
-
-static char *implicit_tag; /* implicit cluster tag */
-
-
-/*
- * Print width for print_sv() output.
- */
-
-#define STATWIDTH (SV_MAXPATH / 2)
-
-/*
- * Pathnames.
- */
-
-static const caddr_t sv_rpath = SV_DEVICE;
-
-/*
- * Functions.
- */
-
-static int read_config_file(const caddr_t, sv_name_t []);
-static int enable_dev(sv_name_t *);
-static int disable_dev(const caddr_t);
-static void error(spcs_s_info_t *, caddr_t, ...);
-static void create_cfg_hash();
-static int find_in_hash(char *path);
-static void destroy_hashtable();
-static void remove_from_cfgfile(char *path, int setnumber);
-
-static caddr_t program;
-
-static void
-sv_cfg_open(CFGLOCK mode)
-{
- if (cfg != NULL)
- return;
-
- cfg = cfg_open(NULL);
- if (cfg == NULL) {
- error(NULL, gettext("unable to access the configuration"));
- /* NOTREACHED */
- }
-
- if (cfg_cluster_tag && *cfg_cluster_tag) {
- cfg_resource(cfg, cfg_cluster_tag);
- } else {
- cfg_resource(cfg, NULL);
- }
- if (!cfg_lock(cfg, mode)) {
- error(NULL, gettext("unable to lock the configuration"));
- /* NOTREACHED */
- }
-}
-
-
-static void
-sv_cfg_close(void)
-{
- if (cfg == NULL)
- return;
-
- if (cfg_changed) {
- (void) cfg_commit(cfg);
- cfg_changed = 0;
- }
-
- cfg_close(cfg);
- cfg = NULL;
-}
-
-
-
-static void
-usage(void)
-{
- (void) fprintf(stderr, gettext("usage:\n"));
-
- (void) fprintf(stderr, gettext(
- "\t%s -h help\n"), program);
-
- (void) fprintf(stderr, gettext(
- "\t%s [-C tag] display status\n"),
- program);
-
- (void) fprintf(stderr, gettext(
- "\t%s [-C tag] -i display "
- "extended status\n"), program);
-
- (void) fprintf(stderr, gettext(
- "\t%s [-C tag] -v display "
- "version number\n"), program);
-
- (void) fprintf(stderr, gettext(
- "\t%s [-C tag] -e { -f file | volume } enable\n"), program);
-
- (void) fprintf(stderr, gettext(
- "\t%s [-C tag] -d { -f file | volume } disable\n"), program);
-
- (void) fprintf(stderr, gettext(
- "\t%s [-C tag] -r { -f file | volume } reconfigure\n"), program);
-
- sv_cfg_close();
-}
-
-static void
-message(caddr_t prefix, spcs_s_info_t *status, caddr_t string, va_list ap)
-{
- (void) fprintf(stderr, "%s: %s: ", program, prefix);
- (void) vfprintf(stderr, string, ap);
- (void) fprintf(stderr, "\n");
-
- if (status) {
- spcs_s_report(*status, stderr);
- spcs_s_ufree(status);
- }
-}
-
-
-static void
-error(spcs_s_info_t *status, caddr_t string, ...)
-{
- va_list ap;
- va_start(ap, string);
-
- message(gettext("error"), status, string, ap);
-
- va_end(ap);
-
- sv_cfg_close();
- exit(1);
-}
-
-
-static void
-warn(spcs_s_info_t *status, caddr_t string, ...)
-{
- va_list ap;
- va_start(ap, string);
-
- message(gettext("warning"), status, string, ap);
-
- va_end(ap);
-}
-
-
-static void
-sv_get_maxdevs(void)
-{
- sv_name_t svn[1];
- sv_list_t svl;
- int fd;
-
- if (sv_max_devices > 0)
- return;
-
- fd = open(sv_rpath, O_RDONLY);
- if (fd < 0)
- error(NULL, gettext("unable to open %s: %s"),
- sv_rpath, strerror(errno));
-
- bzero(&svl, sizeof (svl));
- bzero(&svn[0], sizeof (svn));
-
- svl.svl_names = &svn[0];
- svl.svl_error = spcs_s_ucreate();
-
- if (ioctl(fd, SVIOC_LIST, &svl) < 0) {
- (void) close(fd);
- error(&svl.svl_error, gettext("unable to get max devs"));
- }
-
- spcs_s_ufree(&svl.svl_error);
- sv_max_devices = svl.svl_maxdevs;
-
- (void) close(fd);
-}
-
-
-static sv_name_t *
-sv_alloc_svnames(void)
-{
- sv_name_t *svn = NULL;
-
- sv_get_maxdevs();
-
- svn = calloc(sv_max_devices, sizeof (*svn));
- if (svn == NULL) {
- error(NULL, "unable to allocate %ld bytes of memory",
- sv_max_devices * sizeof (*svn));
- }
-
- return (svn);
-}
-
-
-static void
-sv_check_dgislocal(char *dgname)
-{
- char *othernode;
- int rc;
-
- /*
- * check where this disk service is mastered
- */
-
- rc = cfg_dgname_islocal(dgname, &othernode);
- if (rc < 0) {
- error(NULL, gettext("unable to find "
- "disk service, %s: %s"), dgname, strerror(errno));
- }
-
- if (rc == 0) {
- error(NULL, gettext("disk service, %s, is "
- "active on node \"%s\"\nPlease re-issue "
- "the command on that node"), dgname, othernode);
- }
-}
-
-
-/*
- * Carry out cluster based checks for a specified volume, or just
- * global options.
- */
-static void
-sv_check_cluster(char *path)
-{
- char dgname[CFG_MAX_BUF];
- static int sv_iscluster = -1; /* set to 1 if running in a cluster */
-
- /*
- * Find out if we are running in a cluster
- */
- if (sv_iscluster == -1) {
- if ((sv_iscluster = cfg_iscluster()) < 0) {
- error(NULL, gettext("unable to ascertain environment"));
- }
- }
-
- if (!sv_iscluster && cfg_cluster_tag != NULL) {
- error(NULL, gettext("-C is not valid when not in a cluster"));
- }
-
- if (!sv_iscluster || sv_islocal || path == NULL) {
- return;
- }
-
-
- /*
- * Cluster-only checks on pathname
- */
- if (cfg_dgname(path, dgname, sizeof (dgname)) == NULL) {
- error(NULL, gettext("unable to determine "
- "disk group name for %s"), path);
- return;
- }
-
- if (cfg_cluster_tag != NULL) {
- /*
- * Do dgislocal check now in case path did not contain
- * a dgname.
- *
- * E.g. adding a /dev/did/ device to a disk service.
- */
-
- sv_check_dgislocal(cfg_cluster_tag);
- }
-
- if (strcmp(dgname, "") == 0)
- return; /* NULL dgname is valid */
-
- if (cfg_cluster_tag == NULL) {
- /*
- * Implicitly set the cluster tag to dgname
- */
-
- sv_check_dgislocal(dgname);
-
- if (implicit_tag) {
- free(implicit_tag);
- implicit_tag = NULL;
- }
-
- implicit_tag = strdup(dgname);
- if (implicit_tag == NULL) {
- error(NULL,
- gettext("unable to allocate memory "
- "for cluster tag"));
- }
- } else {
- /*
- * Check dgname and cluster tag from -C are the same.
- */
-
- if (strcmp(dgname, cfg_cluster_tag) != 0) {
- error(NULL,
- gettext("-C (%s) does not match disk group "
- "name (%s) for %s"), cfg_cluster_tag,
- dgname, path);
- }
-
- /*
- * sv_check_dgislocal(cfg_cluster_tag) was called above.
- */
- }
-}
-
-
-static void
-print_version(void)
-{
- sv_version_t svv;
- int fd;
-
- bzero(&svv, sizeof (svv));
- svv.svv_error = spcs_s_ucreate();
-
- fd = open(sv_rpath, O_RDONLY);
- if (fd < 0) {
- warn(NULL, gettext("unable to open %s: %s"),
- sv_rpath, strerror(errno));
- return;
- }
-
- if (ioctl(fd, SVIOC_VERSION, &svv) != 0) {
- error(&svv.svv_error,
- gettext("unable to read the version number"));
- /* NOTREACHED */
- }
-
- spcs_s_ufree(&svv.svv_error);
-#ifdef DEBUG
- (void) printf(gettext("Storage Volume version %d.%d.%d.%d\n"),
- svv.svv_major_rev, svv.svv_minor_rev,
- svv.svv_micro_rev, svv.svv_baseline_rev);
-#else
- if (svv.svv_micro_rev) {
- (void) printf(gettext("Storage Volume version %d.%d.%d\n"),
- svv.svv_major_rev, svv.svv_minor_rev, svv.svv_micro_rev);
- } else {
- (void) printf(gettext("Storage Volume version %d.%d\n"),
- svv.svv_major_rev, svv.svv_minor_rev);
- }
-#endif
-
- (void) close(fd);
-}
-
-int
-main(int argc, char *argv[])
-{
- extern int optind;
- extern char *optarg;
- char *conf_file = NULL;
- int enable, disable, compare, print, version;
- int opt, Cflag, fflag, iflag;
- int rc;
-
- (void) setlocale(LC_ALL, "");
- (void) textdomain("svadm");
-
- program = strdup(basename(argv[0]));
-
- Cflag = fflag = iflag = 0;
- compare = enable = disable = version = 0;
-
- print = 1;
-
- while ((opt = getopt(argc, argv, "C:def:hirv")) != EOF) {
- switch (opt) {
-
- case 'C':
- if (Cflag) {
- warn(NULL,
- gettext("-C specified multiple times"));
- usage();
- exit(2);
- /* NOTREACHED */
- }
-
- Cflag++;
- cfg_cluster_tag = optarg;
- break;
-
- case 'e':
- print = 0;
- enable++;
- break;
-
- case 'd':
- print = 0;
- disable++;
- break;
-
- case 'f':
- fflag++;
- conf_file = optarg;
- break;
-
- case 'i':
- iflag++;
- break;
-
- case 'r':
- /* Compare running system with sv.cf */
- print = 0;
- compare++;
- break;
-
- case 'v':
- print = 0;
- version++;
- break;
-
- case 'h':
- usage();
- exit(0);
-
- default:
- usage();
- exit(2);
- /* NOTREACHED */
- }
- }
-
-
- /*
- * Usage checks
- */
-
- if ((enable + disable + compare) > 1) {
- warn(NULL, gettext("-d, -e and -r are mutually exclusive"));
- usage();
- exit(2);
- }
-
- if (fflag && (print || version)) {
- warn(NULL, gettext("-f is only valid with -d, -e or -r"));
- usage();
- exit(2);
- }
-
- if (fflag && optind != argc) {
- usage();
- exit(2);
- }
-
- if (print || version) {
- /* check for no more args */
-
- if (optind != argc) {
- usage();
- exit(2);
- }
- } else {
- /* check for inline args */
-
- if (!fflag && (argc - optind) != 1) {
- usage();
- exit(2);
- }
- }
-
- if (!print && iflag) {
- usage();
- exit(2);
- }
-
-
- /*
- * Check for the special cluster tag and convert into the
- * internal representation.
- */
-
- if (cfg_cluster_tag != NULL &&
- strcmp(cfg_cluster_tag, SV_LOCAL_TAG) == 0) {
- cfg_cluster_tag = "-";
- sv_islocal = 1;
- }
-
-
- /*
- * Process commands
- */
-
- if (optind != argc) {
- /* deal with inline volume argument */
-
- rc = 0;
- if (enable)
- rc = enable_one_sv(argv[optind]);
- else if (disable)
- rc = disable_one_sv(argv[optind]);
- else /* if (compare) */
- compare_one_sv(argv[optind]);
-
- if (rc != 0)
- return (1);
-
- return (0);
- }
-
- rc = 0;
- if (enable)
- rc = enable_sv(conf_file);
- else if (disable)
- rc = disable_sv(conf_file);
- else if (compare)
- compare_sv(conf_file);
- else if (print)
- print_sv(iflag);
- else /* if (version) */
- print_version();
-
- if (rc != 0)
- return (1);
-
- return (0);
-}
-
-
-
-/* LINT - not static as fwcadm uses it */
-static int
-enable_sv(char *conf_file)
-{
- int index;
- sv_name_t *svn;
- int cnt;
- int rc, ret;
-
- svn = sv_alloc_svnames();
-
- index = read_config_file(conf_file, svn);
-
- rc = ret = 0;
-
- for (cnt = 0; cnt < index; cnt++) {
-
- /*
- * Check for more data.
- */
- if (svn[cnt].svn_path[0] == '\0') {
- /*
- * This was set when reading sv.conf. After the last
- * line svn_path was set to \0, so we are finished.
- * We shouldn't get here, but put this in just in
- * case.
- */
- break;
- }
- rc = enable_dev(&svn[cnt]);
- if (rc && !ret)
- ret = rc;
- }
-
- sv_cfg_close();
-
- return (ret);
-}
-
-
-/* LINT - not static as fwcadm uses it */
-static int
-enable_one_sv(caddr_t path)
-{
- sv_name_t svn;
- int rc;
-
- sv_get_maxdevs();
-
- bzero(&svn, sizeof (svn));
- (void) strncpy(svn.svn_path, path, sizeof (svn.svn_path));
- svn.svn_mode = (NSC_DEVICE | NSC_CACHE);
-
- /* force NULL termination */
- svn.svn_path[sizeof (svn.svn_path) - 1] = '\0';
-
- rc = enable_dev(&svn);
- sv_cfg_close();
-
- return (rc);
-}
-
-
-static int
-enable_dev(sv_name_t *svn)
-{
- char buf[CFG_MAX_BUF];
- struct stat stb;
- sv_conf_t svc;
- int fd;
- int sev;
- int rc;
- char *lcltag;
- char *altname;
-
- sv_check_cluster(svn->svn_path);
- sv_cfg_open(CFG_WRLOCK);
-
- bzero(&svc, sizeof (svc));
-
- if (stat(svn->svn_path, &stb) != 0) {
- warn(NULL, gettext("unable to access %s: %s"),
- svn->svn_path, strerror(errno));
- return (1);
- }
-
- if (!S_ISCHR(stb.st_mode)) {
- warn(NULL, gettext("%s is not a character device - ignored"),
- svn->svn_path);
- return (1);
- }
-
- svc.svc_major = major(stb.st_rdev);
- svc.svc_minor = minor(stb.st_rdev);
- (void) strncpy(svc.svc_path, svn->svn_path, sizeof (svc.svc_path));
-
- fd = open(sv_rpath, O_RDONLY);
- if (fd < 0) {
- warn(NULL, gettext("unable to open %s: %s"),
- svn->svn_path, strerror(errno));
- return (1);
- }
-
- svc.svc_flag = svn->svn_mode;
- svc.svc_error = spcs_s_ucreate();
-
- /* first, check for duplicates */
- rc = cfg_get_canonical_name(cfg, svn->svn_path, &altname);
- if (rc < 0) {
- spcs_log("sv", NULL, gettext("Unable to parse config file"));
- warn(NULL, gettext("Unable to parse config file"));
- (void) close(fd);
- return (1);
- }
- if (rc) {
- error(NULL, gettext("'%s' has already been configured as "
- "'%s'. Re-enter command with the latter name."),
- svn->svn_path, altname);
- }
-
- /* secondly, try to insert it into the dsvol config */
- if (implicit_tag && *implicit_tag) {
- lcltag = implicit_tag;
- } else if (cfg_cluster_tag && *cfg_cluster_tag) {
- lcltag = cfg_cluster_tag;
- } else {
- lcltag = "-";
- }
- rc = cfg_add_user(cfg, svn->svn_path, lcltag, "sv");
- if (CFG_USER_ERR == rc) {
- spcs_log("sv", NULL,
- gettext("%s: unable to put %s into dsvol cfg"),
- program, svn->svn_path);
- warn(NULL, gettext("unable to put %s into dsvol cfg"),
- svn->svn_path);
- (void) close(fd);
- return (1);
- }
- cfg_changed = 1;
-
- if (CFG_USER_OK == rc) {
- /* success */
- (void) close(fd);
- return (0);
- }
-
- if (ioctl(fd, SVIOC_ENABLE, &svc) < 0) {
- if ((CFG_USER_REPEAT == rc) && (SV_EENABLED == errno)) {
- /* it's ok -- we were just double-checking */
- (void) close(fd);
- return (0);
- }
-
- spcs_log("sv", &svc.svc_error,
- gettext("%s: unable to enable %s"),
- program, svn->svn_path);
-
- warn(&svc.svc_error, gettext("unable to enable %s"),
- svn->svn_path);
-
- /* remove it from dsvol, if we're the ones who put it in */
- if (CFG_USER_FIRST == rc) {
- (void) cfg_rem_user(cfg, svn->svn_path, lcltag, "sv");
- }
- (void) close(fd);
- return (1);
- }
-
- spcs_log("sv", NULL, gettext("%s: enabled %s"),
- program, svn->svn_path);
-
- if (implicit_tag != NULL) {
-#ifdef DEBUG
- if (cfg_cluster_tag != NULL) {
- error(NULL,
- gettext("enable_dev: -C %s AND implicit_tag %s!"),
- cfg_cluster_tag, implicit_tag);
- }
-#endif
-
- (void) snprintf(buf, sizeof (buf), "%s - %s",
- svc.svc_path, implicit_tag);
- } else {
- (void) strcpy(buf, svc.svc_path);
- }
-
- rc = 0;
- if (cfg_put_cstring(cfg, "sv", buf, sizeof (buf)) < 0) {
- warn(NULL,
- gettext("unable to add %s to configuration storage: %s"),
- svc.svc_path, cfg_error(&sev));
- rc = 1;
- }
-
- cfg_changed = 1;
- spcs_s_ufree(&svc.svc_error);
- (void) close(fd);
-
- return (rc);
-}
-
-
-/*
- * This routine parses the config file passed in via conf_file and
- * stores the data in the svn array. The return value is the number
- * of entries read from conf_file. If an error occurs the error()
- * routine is called (which exits the program).
- */
-static int
-read_config_file(const caddr_t conf_file, sv_name_t svn[])
-{
- char line[1024], rdev[1024], junk[1024];
- struct stat stb;
- int lineno;
- int cnt, i;
- int index = 0; /* Current location in svn array */
- sv_name_t *cur_svn; /* Pointer to svn[index] */
- FILE *fp;
-
- if (access(conf_file, R_OK) != 0 ||
- stat(conf_file, &stb) != 0 ||
- !S_ISREG(stb.st_mode)) {
- error(NULL, gettext("cannot read config file %s"), conf_file);
- }
-
- if ((fp = fopen(conf_file, "r")) == NULL) {
- error(NULL, gettext("unable to open config file %s: %s"),
- conf_file, strerror(errno));
- }
-
- lineno = 0;
-
- while (fgets(line, sizeof (line), fp) != NULL) {
- lineno++;
-
- i = strlen(line);
-
- if (i < 1)
- continue;
-
- if (line[i-1] == '\n')
- line[i-1] = '\0';
- else if (i == (sizeof (line) - 1)) {
- warn(NULL, gettext(
- "line %d: line too long -- should be less than %d characters"),
- lineno, (sizeof (line) - 1));
- warn(NULL, gettext("line %d: ignored"), lineno);
- }
-
- /*
- * check for comment line.
- */
- if (line[0] == '#')
- continue;
-
- cnt = sscanf(line, "%s %s", rdev, junk);
-
- if (cnt != 1 && cnt != 2) {
- if (cnt > 0) {
- warn(NULL, gettext("line %d: invalid format"),
- lineno);
- warn(NULL, gettext("line %d: ignored"), lineno);
- }
- continue;
- }
-
- rdev[sizeof (rdev) - 1] = '\0';
-
- cur_svn = &svn[index]; /* For easier reading below */
-
- if (strlen(rdev) >= sizeof (cur_svn->svn_path)) {
- warn(NULL, gettext(
- "line %d: raw device name (%s) longer than %d characters"),
- lineno, rdev,
- (sizeof (cur_svn->svn_path) - 1));
- warn(NULL, gettext("line %d: ignored"), lineno);
- continue;
- }
-
- (void) strcpy(cur_svn->svn_path, rdev);
- cur_svn->svn_mode = (NSC_DEVICE | NSC_CACHE);
-
- index++;
- }
-
- /* Set the last path to NULL */
- svn[index].svn_path[0] = '\0';
-
- (void) fclose(fp);
-
- return (index);
-}
-
-
-/*
- * Disable the device from the kernel configuration.
- *
- * RETURN:
- * 0 on success
- * non-zero on failure.
- *
- * Failures are reported to the user.
- */
-static int
-disable_dev(const caddr_t path)
-{
- struct stat stb;
- sv_conf_t svc;
- int fd;
-
- sv_check_cluster(path);
-
- if (stat(path, &stb) < 0) {
- svc.svc_major = (major_t)-1;
- svc.svc_minor = (minor_t)-1;
- } else {
- svc.svc_major = major(stb.st_rdev);
- svc.svc_minor = minor(stb.st_rdev);
- }
-
- if ((fd = open(sv_rpath, O_RDONLY)) < 0) {
- warn(NULL, gettext("unable to open %s: %s"),
- sv_rpath, strerror(errno));
- return (-1);
- }
-
- (void) strcpy(svc.svc_path, path);
- svc.svc_error = spcs_s_ucreate();
-
- /*
- * Issue the ioctl to attempt to disable this device. Note that all
- * the libdscfg details are handled elsewhere.
- */
- if (ioctl(fd, SVIOC_DISABLE, &svc) < 0) {
- if (errno != SV_EDISABLED) {
- spcs_log("sv", &svc.svc_error,
- gettext("%s: unable to disable %s"),
- program, path);
-
- warn(&svc.svc_error,
- gettext("unable to disable %s"), path);
- (void) close(fd);
- return (-1);
- }
- }
-
- spcs_log("sv", NULL, gettext("%s: disabled %s"), program, path);
-
- spcs_s_ufree(&svc.svc_error);
- (void) close(fd);
-
- return (0);
-}
-
-
-static void
-print_cluster_tag(const int setnumber)
-{
- char buf[CFG_MAX_BUF];
- char key[CFG_MAX_KEY];
-
- bzero(buf, sizeof (buf));
- (void) snprintf(key, sizeof (key), "sv.set%d.cnode", setnumber);
-
- (void) cfg_get_cstring(cfg, key, buf, sizeof (buf));
-
- if (*buf != '\0') {
- if (strcmp(buf, "-") == 0) {
- (void) printf(" [%s]", gettext("local to node"));
- } else {
- (void) printf(" [%s: %s]", gettext("cluster"), buf);
- }
- }
-}
-
-
-/* LINT - not static as fwcadm uses it */
-static void
-print_sv(int verbose)
-{
- sv_name_t *svn, *svn_system; /* Devices in system */
- sv_list_t svl_system;
- int fd, i;
- int setnumber;
-
- sv_check_cluster(NULL);
- sv_cfg_open(CFG_RDLOCK);
-
- svn_system = sv_alloc_svnames();
-
- if ((fd = open(sv_rpath, O_RDONLY)) < 0) {
- (void) printf(gettext("unable to open %s: %s"),
- sv_rpath, strerror(errno));
- return;
- }
-
- /* Grab the system list from the driver */
- svl_system.svl_count = sv_max_devices;
- svl_system.svl_names = &svn_system[0];
- svl_system.svl_error = spcs_s_ucreate();
-
- if (ioctl(fd, SVIOC_LIST, &svl_system) < 0) {
- error(&svl_system.svl_error, gettext("unable to get list"));
- }
-
- spcs_s_ufree(&svl_system.svl_error);
- (void) close(fd);
-
- /*
- * We build a hashmap out of the entries from the config file to make
- * searching faster. We end up taking a performance hit when the # of
- * volumes is small, but for larger configurations it's a
- * HUGE improvement.
- */
-
- /* build the hashtable */
- cfg_rewind(cfg, CFG_SEC_CONF);
- create_cfg_hash();
-
- /*
- * For each volume found from the kernel, print out
- * info about it from the kernel.
- */
- for (i = 0; i < svl_system.svl_count; i++) {
- if (*svn_system[i].svn_path == '\0') {
- break;
- }
-
- svn = &svn_system[i];
- if (svn->svn_mode == 0) {
-#ifdef DEBUG
- (void) printf(gettext("%s [kernel guard]\n"),
- svn->svn_path);
-#endif
- continue;
- }
- /* get sv entry from the hashtable */
- if ((setnumber = find_in_hash(svn->svn_path)) != -1) {
- (void) printf("%-*s", STATWIDTH, svn->svn_path);
-
- if (verbose) {
- print_cluster_tag(setnumber);
- }
-
- (void) printf("\n");
-
- } else {
- /*
- * We didn't find the entry in the hashtable. Let
- * the user know that the persistent storage is
- * inconsistent with the kernel configuration.
- */
- if (cfg_cluster_tag == NULL)
- warn(NULL, gettext(
- "%s is configured, but not in the "
- "config storage"), svn->svn_path);
- }
- }
-
- /* free up the hashtable */
- destroy_hashtable();
-
- sv_cfg_close();
-}
-
-
-/* LINT - not static as fwcadm uses it */
-static int
-disable_sv(char *conf_file)
-{
- sv_name_t *svn, *svn_system; /* Devices in system */
- sv_list_t svl_system;
- int fd, i, setnumber;
- int rc, ret;
-
- svn_system = sv_alloc_svnames();
-
- rc = ret = 0;
-
- if (conf_file == NULL) {
- if ((fd = open(sv_rpath, O_RDONLY)) < 0) {
- (void) printf(gettext("unable to open %s: %s"),
- sv_rpath, strerror(errno));
- return (1);
- }
-
- /* Grab the system list from the driver */
- svl_system.svl_count = sv_max_devices;
- svl_system.svl_names = &svn_system[0];
- svl_system.svl_error = spcs_s_ucreate();
-
- if (ioctl(fd, SVIOC_LIST, &svl_system) < 0) {
- error(&(svl_system.svl_error),
- gettext("unable to get list"));
- }
-
- spcs_s_ufree(&(svl_system.svl_error));
- (void) close(fd);
- } else {
- svl_system.svl_count = read_config_file(conf_file, svn_system);
- }
-
-
- for (i = 0; i < svl_system.svl_count; i++) {
- if (*svn_system[i].svn_path == '\0')
- break;
-
- svn = &svn_system[i];
-
- sv_check_cluster(svn->svn_path);
- sv_cfg_open(CFG_WRLOCK);
- create_cfg_hash();
- rc = 0;
- if ((setnumber = find_in_hash(svn->svn_path)) != -1) {
- if ((rc = disable_dev(svn->svn_path)) != -1) {
- remove_from_cfgfile(svn->svn_path, setnumber);
- } else if (errno == SV_ENODEV) {
- remove_from_cfgfile(svn->svn_path, setnumber);
- }
- } else {
- /* warn the user that we didn't find it in cfg file */
- warn(NULL, gettext(
- "%s was not found in the config storage"),
- svn->svn_path);
- /* try to disable anyway */
- (void) disable_dev(svn->svn_path);
- rc = 1;
- }
-
- sv_cfg_close();
- destroy_hashtable();
-
- if (rc && !ret)
- ret = rc;
- }
-
- return (ret);
-}
-
-
-/* LINT - not static as fwcadm uses it */
-static int
-disable_one_sv(char *path)
-{
- int setnumber;
- int rc;
-
- sv_get_maxdevs();
- sv_check_cluster(path);
- sv_cfg_open(CFG_WRLOCK);
-
- create_cfg_hash();
- if ((setnumber = find_in_hash(path)) != -1) {
- /* remove from kernel */
- if ((rc = disable_dev(path)) == 0) {
- /* remove the cfgline */
- remove_from_cfgfile(path, setnumber);
- } else if (errno == SV_ENODEV) {
- remove_from_cfgfile(path, setnumber);
- }
- } else {
- /* warn the user that we didn't find it in cfg file */
- warn(NULL,
- gettext("%s was not found in the config storage"), path);
- /* still attempt to remove */
- (void) disable_dev(path);
- rc = 1;
- }
- destroy_hashtable();
-
- sv_cfg_close();
- return (rc);
-}
-
-
-static void
-compare_tag(char *path)
-{
- char buf[CFG_MAX_BUF], vol[CFG_MAX_BUF], cnode[CFG_MAX_BUF];
- char key[CFG_MAX_KEY];
- int found, setnumber, i;
- char *tag;
-
- sv_check_cluster(path);
- cfg_resource(cfg, (char *)NULL); /* reset */
- cfg_rewind(cfg, CFG_SEC_CONF);
-
-#ifdef DEBUG
- if (cfg_cluster_tag != NULL && implicit_tag != NULL) {
- error(NULL, gettext("compare_tag: -C %s AND implicit_tag %s!"),
- cfg_cluster_tag, implicit_tag);
- }
-#endif
-
- if (cfg_cluster_tag != NULL)
- tag = cfg_cluster_tag;
- else if (implicit_tag != NULL)
- tag = implicit_tag;
- else
- tag = "-";
-
- found = 0;
- for (i = 0; i < sv_max_devices; i++) {
- setnumber = i + 1;
- (void) snprintf(key, sizeof (key), "sv.set%d", setnumber);
- if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0) {
- break;
- }
-
- if (sscanf(buf, "%s - %s", vol, cnode) != 2) {
- continue;
- }
-
- if (strcmp(path, vol) == 0) {
- found = 1;
- break;
- }
- }
-
- if (!found) {
- warn(NULL, gettext("unable to find %s in the configuration"),
- path);
- return;
- }
-
- /* have name match, compare cnode to new tag */
-
- if (strcmp(tag, cnode) == 0) {
- /* cluster tags match */
- return;
- }
-
- /* need to change the cluster tag */
-
- (void) snprintf(key, sizeof (key), "sv.set%d.cnode", setnumber);
- if (cfg_put_cstring(cfg, key, tag, strlen(tag)) < 0) {
- warn(NULL,
- gettext("unable to change cluster tag for %s"), path);
- return;
- }
-
- cfg_changed = 1;
-
- /* change "-" tags to "" for display purposes */
-
- if (strcmp(tag, "-") == 0)
- tag = "";
-
- if (strcmp(cnode, "-") == 0)
- (void) strcpy(cnode, "");
-
- (void) printf(
- gettext("%s: changed cluster tag for %s from \"%s\" to \"%s\"\n"),
- program, path, cnode, tag);
-
- spcs_log("sv", NULL,
- gettext("%s: changed cluster tag for %s from \"%s\" to \"%s\""),
- program, path, cnode, tag);
-}
-
-
-/* LINT - not static as fwcadm uses it */
-static void
-compare_sv(char *conf_file)
-{
- sv_name_t *svn_config; /* Devices in config file */
- sv_name_t *svn_system; /* Devices in system */
- sv_name_t *enable; /* Devices that need enabled */
- sv_list_t svl_system;
- int config_cnt;
- int sys_cnt = 0;
- int setnumber, i, j;
- int index = 0; /* Index in enable[] */
- int found;
- int fd0;
-
- svn_config = sv_alloc_svnames();
- svn_system = sv_alloc_svnames();
- enable = sv_alloc_svnames();
-
- bzero(svn_system, sizeof (svn_system));
- bzero(&svl_system, sizeof (svl_system));
- bzero(enable, sizeof (enable));
-
- /*
- * Read the configuration file
- * The return value is the number of entries
- */
- config_cnt = read_config_file(conf_file, svn_config);
-
- if ((fd0 = open(sv_rpath, O_RDONLY)) < 0)
- error(NULL, gettext("unable to open %s: %s"),
- sv_rpath, strerror(errno));
-
- /* Grab the system list from the driver */
- svl_system.svl_count = sv_max_devices;
- svl_system.svl_names = &svn_system[0];
- svl_system.svl_error = spcs_s_ucreate();
-
- if (ioctl(fd0, SVIOC_LIST, &svl_system) < 0) {
- error(&svl_system.svl_error, gettext("unable to get list"));
- }
-
- spcs_s_ufree(&svl_system.svl_error);
- (void) close(fd0);
-
- /*
- * Count the number of devices in the system.
- * The last entry in the array has '\0' for a path name.
- */
- for (j = 0; j < sv_max_devices; j++) {
- if (svn_system[j].svn_path[0] != '\0') {
- sys_cnt++;
- } else {
- break;
- }
- }
- /*
- * Compare the configuration array with the system array.
- * Mark any differences and disable conflicting devices.
- */
- for (i = 0; i < config_cnt; i++) {
- found = 0;
- for (j = 0; j < sys_cnt; j++) {
- if (svn_system[j].svn_path[0] == '\0' ||
- svn_system[j].svn_mode == 0)
- continue;
-
- /* Check to see if path matches */
- if (strcmp(svn_system[j].svn_path,
- svn_config[i].svn_path) == 0) {
- /* Found a match */
- svn_system[j].svn_path[0] = '\0';
- found++;
- break;
- }
- }
-
- if (!found) {
- /* Minor number not in system = > enable device */
- enable[index].svn_mode = svn_config[i].svn_mode;
- (void) strcpy(enable[index].svn_path,
- svn_config[i].svn_path);
- index++;
- }
- }
-
- /* Disable any devices that weren't in the config file */
- for (j = 0; j < sys_cnt; j++) {
- sv_check_cluster(NULL);
- sv_cfg_open(CFG_WRLOCK);
- create_cfg_hash();
- if (svn_system[j].svn_path[0] != '\0' &&
- svn_system[j].svn_mode != 0) {
- (void) printf(gettext("%s: disabling sv: %s\n"),
- program, svn_system[j].svn_path);
- if (disable_dev(svn_system[j].svn_path) == 0) {
- setnumber =
- find_in_hash(svn_system[j].svn_path);
- if (setnumber != -1) {
- /* the volume was found in cfg store */
- remove_from_cfgfile(
- svn_system[j].svn_path, setnumber);
- }
- }
- }
- sv_cfg_close();
- destroy_hashtable();
- }
-
- while (index) {
- /*
- * Config file doesn't match system => enable the devices
- * in enable[]
- */
- index--;
- (void) printf(gettext("%s: enabling new sv: %s\n"),
- program, enable[index].svn_path);
- (void) enable_dev(&enable[index]);
- }
-
- /*
- * Search for entries where the cluster tag has changed.
- */
- sv_check_cluster(NULL);
- sv_cfg_open(CFG_WRLOCK);
-
- for (i = 0; i < sv_max_devices; i++) {
- if (svn_config[i].svn_path[0] == '\0')
- break;
-
- compare_tag(svn_config[i].svn_path);
- }
-
- sv_cfg_close();
-}
-
-
-/*
- * We assume that the volume is already enabled and we can only
- * be changing the cluster tag. Anything else is an error.
- */
-/* LINT - not static as fwcadm uses it */
-static void
-compare_one_sv(char *path)
-{
- sv_get_maxdevs();
- sv_check_cluster(NULL);
- sv_cfg_open(CFG_WRLOCK);
-
- compare_tag(path);
-
- sv_cfg_close();
-}
-
-/*
- * Read all sets from the libdscfg configuration file, and store everything in
- * the hashfile.
- *
- * We assume that the config file has been opened & rewound for us. We store
- * the volume name as the key, and the setnumber where we found it as the data.
- *
- * The caller can pass in a pointer to the maximum number of volumes, or
- * a pointer to NULL, specifying we want 'all' the volumes. The table is
- * searched using find_in_hash.
- */
-static void
-create_cfg_hash()
-{
- char key[CFG_MAX_KEY], buf[CFG_MAX_BUF];
- char vol[CFG_MAX_BUF], cnode[CFG_MAX_BUF];
- int setnumber;
- ENTRY item;
-
- if (hcreate((size_t)sv_max_devices) == 0)
- error(NULL, gettext("unable to create hash table"));
-
- for (setnumber = 1; /* CSTYLED */; setnumber++) {
- (void) snprintf(key, sizeof (key), "sv.set%d", setnumber);
- if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0)
- break;
-
- if (sscanf(buf, "%s - %s", vol, cnode) != 2) {
- continue;
- }
-
- item.key = strdup(vol);
- item.data = (void *)setnumber;
- if (hsearch(item, ENTER) == NULL) {
- error(NULL,
- gettext("unable to add entry to hash table"));
- }
- }
-}
-
-/*
- * Function to search the hash for a specific volume. If it is found,
- * we return the set number. If it isn't found, we return -1
- */
-static int
-find_in_hash(char *path)
-{
- ENTRY *found_entry, item;
- int retval = -1;
-
- item.key = path;
-
- if ((found_entry = hsearch(item, FIND)) != NULL) {
- retval = (int)found_entry->data;
- }
-
- return (retval);
-}
-
-/*
- * Just a wrapper to destory the hashtable. At some point in the future we
- * might want to do something more.... For instance, verify that the cfg
- * database and the kernel configuration match (?) Just an idea.
- */
-static void
-destroy_hashtable()
-{
- hdestroy();
-}
-
-/*
- * This function will remove a particular set from the config file.
- *
- * We make a whole host of assumptions:
- * o the hashfile is up to date;
- * o The config file has been opened with a WRLOCK for us.
- */
-static void
-remove_from_cfgfile(char *path, int setnumber)
-{
- char key[CFG_MAX_KEY];
- int sev;
- char *lcltag;
-
- /* attempt to remove the volume from config storage */
- (void) snprintf(key, sizeof (key), "sv.set%d", setnumber);
- if (cfg_put_cstring(cfg, key, NULL, 0) < 0) {
- warn(NULL, gettext("unable to remove %s from "
- "config storage: %s"), path, cfg_error(&sev));
- } else {
- if (implicit_tag && *implicit_tag) {
- lcltag = implicit_tag;
- } else if (cfg_cluster_tag && *cfg_cluster_tag) {
- lcltag = cfg_cluster_tag;
- } else {
- lcltag = "-";
- }
- if (cfg_rem_user(cfg, path, lcltag, "sv") != CFG_USER_LAST) {
- warn(NULL, gettext("unable to remove %s from dsvol"),
- path);
- }
- cfg_changed = 1;
- }
-}
diff --git a/usr/src/cmd/avs/sv/svadm.h b/usr/src/cmd/avs/sv/svadm.h
deleted file mode 100644
index f1dfa35c1e..0000000000
--- a/usr/src/cmd/avs/sv/svadm.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SVADM_H
-#define _SVADM_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*
- * Functions exported from svadm.o for the use of fwcadm.o
- */
-
-static void compare_one_sv(char *);
-static void compare_sv(char *);
-static int disable_one_sv(char *);
-static int disable_sv(char *);
-static int enable_one_sv(char *);
-static int enable_sv(char *);
-static void print_sv(int);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SVADM_H */
diff --git a/usr/src/cmd/avs/sv/svboot.c b/usr/src/cmd/avs/sv/svboot.c
deleted file mode 100644
index ccee741c1f..0000000000
--- a/usr/src/cmd/avs/sv/svboot.c
+++ /dev/null
@@ -1,533 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mkdev.h>
-#include <sys/param.h>
-#include <fcntl.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <strings.h>
-#include <errno.h>
-#include <stdio.h>
-#include <locale.h>
-#include <unistd.h>
-#include <libgen.h>
-#include <nsctl.h>
-
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_u.h>
-#include <sys/unistat/spcs_errors.h>
-
-#include <sys/nsctl/sv.h>
-#include <sys/nsctl/sv_impl.h>
-
-#include <sys/nsctl/cfg.h>
-
-
-static int sv_max_devices;
-
-
-/*
- * Pathnames.
- */
-
-static const caddr_t sv_rpath = SV_DEVICE;
-
-/*
- * Functions.
- */
-
-static void resume_dev(int, sv_name_t *);
-static void suspend_dev(int, const caddr_t);
-static int read_libcfg(sv_name_t svn[]);
-static void resume_sv();
-static void suspend_sv();
-static void prepare_unload_sv();
-
-
-/*
- * support for the special cluster tag "local" to be used with -C in a
- * cluster for local volumes.
- */
-
-#define SV_LOCAL_TAG "local"
-
-static caddr_t program;
-static caddr_t cfg_cluster_tag;
-
-
-static void
-usage(void)
-{
- (void) fprintf(stderr, gettext("usage:\n"));
-
- (void) fprintf(stderr, gettext(
- "\t%s -h help\n"), program);
-
- (void) fprintf(stderr, gettext(
- "\t%s [-C tag] -r resume all sv devices\n"), program);
-
- (void) fprintf(stderr, gettext(
- "\t%s [-C tag] -s suspend all sv devices\n"), program);
-
- (void) fprintf(stderr, gettext(
- "\t%s -u prepare for sv unload\n"), program);
-}
-
-
-static void
-message(caddr_t prefix, spcs_s_info_t *status, caddr_t string, va_list ap)
-{
- (void) fprintf(stderr, "%s: %s: ", program, prefix);
- (void) vfprintf(stderr, string, ap);
- (void) fprintf(stderr, "\n");
-
- if (status) {
- spcs_s_report(*status, stderr);
- spcs_s_ufree(status);
- }
-}
-
-
-static void
-error(spcs_s_info_t *status, caddr_t string, ...)
-{
- va_list ap;
- va_start(ap, string);
-
- message(gettext("error"), status, string, ap);
-
- va_end(ap);
- exit(1);
-}
-
-
-static void
-warn(spcs_s_info_t *status, caddr_t string, ...)
-{
- va_list ap;
- va_start(ap, string);
-
- message(gettext("warning"), status, string, ap);
-
- va_end(ap);
-}
-
-
-static void
-sv_get_maxdevs(void)
-{
- sv_name_t svn[1];
- sv_list_t svl;
- int fd;
-
- if (sv_max_devices > 0)
- return;
-
- fd = open(sv_rpath, O_RDONLY);
- if (fd < 0)
- error(NULL, gettext("unable to open %s: %s"),
- sv_rpath, strerror(errno));
-
- bzero(&svl, sizeof (svl));
- bzero(&svn[0], sizeof (svn));
-
- svl.svl_names = &svn[0];
- svl.svl_error = spcs_s_ucreate();
-
- if (ioctl(fd, SVIOC_LIST, &svl) < 0)
- error(&svl.svl_error, gettext("unable to get max devs"));
-
- spcs_s_ufree(&svl.svl_error);
- sv_max_devices = svl.svl_maxdevs;
-
- (void) close(fd);
-}
-
-
-static sv_name_t *
-sv_alloc_svnames(void)
-{
- sv_name_t *svn = NULL;
-
- sv_get_maxdevs();
-
- svn = calloc(sv_max_devices, sizeof (*svn));
- if (svn == NULL) {
- error(NULL, "unable to allocate %ld bytes of memory",
- sv_max_devices * sizeof (*svn));
- }
-
- return (svn);
-}
-
-int
-main(int argc, char *argv[])
-{
- extern int optind;
- extern char *optarg;
- int Cflag, resume, suspend, unload;
- int opt;
-
- (void) setlocale(LC_ALL, "");
- (void) textdomain("svboot");
-
- program = strdup(basename(argv[0]));
-
- Cflag = unload = resume = suspend = 0;
-
- while ((opt = getopt(argc, argv, "C:hrsu")) != EOF) {
- switch (opt) {
-
- case 'C':
- if (Cflag) {
- warn(NULL,
- gettext("-C specified multiple times"));
- usage();
- exit(2);
- /* NOTREACHED */
- }
-
- Cflag++;
- cfg_cluster_tag = optarg;
- break;
-
- case 'r':
- resume++;
- break;
-
- case 's':
- suspend++;
- break;
-
- case 'u':
- unload++;
- break;
-
- case 'h':
- usage();
- exit(0);
-
- case '?': /* FALLTHRU */
-
- default:
- usage();
- exit(2);
- /* NOTREACHED */
- }
- }
-
-
- /*
- * Usage checks
- */
-
- if ((resume + suspend + unload) > 1) {
- warn(NULL, gettext("-r , -s and -u are mutually exclusive"));
- usage();
- exit(2);
- }
-
- if (!resume && !suspend && !unload) {
- warn(NULL, gettext("option required"));
- usage();
- exit(2);
- }
-
- if (optind != argc) {
- usage();
- exit(2);
- }
-
-
- /*
- * Check for the special (local) cluster tag
- */
-
- if (cfg_cluster_tag != NULL &&
- strcmp(cfg_cluster_tag, SV_LOCAL_TAG) == 0)
- cfg_cluster_tag = "-";
-
- /*
- * Process commands
- */
-
- if (resume)
- resume_sv();
- else if (suspend)
- suspend_sv();
- else if (unload)
- prepare_unload_sv();
-
- return (0);
-}
-
-
-static void
-resume_sv()
-{
- int index;
- sv_name_t *svn;
- int cnt;
- int fd;
-
- svn = sv_alloc_svnames();
-
- index = read_libcfg(svn);
-
- fd = open(sv_rpath, O_RDONLY);
- if (fd < 0) {
- warn(NULL, gettext("unable to open %s: %s"),
- svn->svn_path, strerror(errno));
- return;
- }
-
- for (cnt = 0; cnt < index; cnt++) {
-
- /*
- * Check for more data.
- */
- if (svn[cnt].svn_path[0] == '\0') {
- /*
- * This was set when reading sv.conf. After the last
- * line svn_path was set to \0, so we are finished.
- * We shouldn't get here, but put this in just in
- * case.
- */
- break;
- }
- resume_dev(fd, &svn[cnt]);
- }
- (void) close(fd);
-}
-
-
-static void
-resume_dev(int fd, sv_name_t *svn)
-{
- struct stat stb;
- sv_conf_t svc;
-
- bzero(&svc, sizeof (svc));
-
- if (stat(svn->svn_path, &stb) != 0) {
- warn(NULL, gettext("unable to access %s: %s"),
- svn->svn_path, strerror(errno));
- return;
- }
-
- svc.svc_major = major(stb.st_rdev);
- svc.svc_minor = minor(stb.st_rdev);
- (void) strncpy(svc.svc_path, svn->svn_path, sizeof (svc.svc_path));
-
- svc.svc_flag = svn->svn_mode;
- svc.svc_error = spcs_s_ucreate();
-
- if (ioctl(fd, SVIOC_ENABLE, &svc) < 0) {
- spcs_log("sv", &svc.svc_error,
- gettext("%s: unable to resume %s"),
- program, svn->svn_path);
-
- warn(&svc.svc_error, gettext("unable to resume %s"),
- svn->svn_path);
- return;
- }
-
- spcs_log("sv", NULL, gettext("%s: resume %s"),
- program, svn->svn_path);
-
- spcs_s_ufree(&svc.svc_error);
-}
-
-
-/*
- * This routine parses the config file and
- * stores the data in the svn array. The return value is the number
- * of entries read from conf_file. If an error occurs the error()
- * routine is called (which exits the program).
- */
-static int
-read_libcfg(sv_name_t svn[])
-{
- char rdev[CFG_MAX_BUF];
- char key[CFG_MAX_KEY];
- struct stat stb;
- int i;
- int setnumber;
- int index = 0; /* Current location in svn array */
- sv_name_t *cur_svn; /* Pointer to svn[index] */
- CFGFILE *cfg;
-
- if ((cfg = cfg_open("")) == NULL) {
- error(NULL, gettext("Error opening config: %s"),
- strerror(errno));
- }
-
- cfg_resource(cfg, cfg_cluster_tag);
- if (!cfg_lock(cfg, CFG_RDLOCK)) {
- error(NULL, gettext("Error locking config: %s"),
- strerror(errno));
- }
-
- for (i = 0; /*CSTYLED*/; i++) {
- setnumber = i + 1;
-
- bzero(rdev, CFG_MAX_BUF);
- (void) snprintf(key, sizeof (key), "sv.set%d.vol", setnumber);
- if (cfg_get_cstring(cfg, key, rdev, sizeof (rdev)) < 0)
- break;
-
- /* Check to see if the raw device is present */
- if (stat(rdev, &stb) != 0) {
- warn(NULL, gettext("unable to access %s: %s"),
- rdev, strerror(errno));
- continue;
- }
-
- if (!S_ISCHR(stb.st_mode)) {
- warn(NULL, gettext("%s is not a character device"),
- rdev);
- continue;
- }
-
- cur_svn = &svn[index]; /* For easier reading below */
-
- if (strlen(rdev) >= sizeof (cur_svn->svn_path)) {
- warn(NULL, gettext(
- "raw device name (%s) longer than %d characters"),
- rdev,
- (sizeof (cur_svn->svn_path) - 1));
- continue;
- }
-
- (void) strcpy(cur_svn->svn_path, rdev);
- cur_svn->svn_mode = (NSC_DEVICE | NSC_CACHE);
-
- index++;
- }
-
- cfg_close(cfg);
-
- /* Set the last path to NULL */
- svn[index].svn_path[0] = '\0';
-
- return (index);
-}
-
-
-static void
-suspend_dev(int fd, const caddr_t path)
-{
- struct stat stb;
- sv_conf_t svc;
-
- if (stat(path, &stb) < 0) {
- svc.svc_major = (major_t)-1;
- svc.svc_minor = (minor_t)-1;
- } else {
- svc.svc_major = major(stb.st_rdev);
- svc.svc_minor = minor(stb.st_rdev);
- }
-
- (void) strcpy(svc.svc_path, path);
- svc.svc_error = spcs_s_ucreate();
-
- if (ioctl(fd, SVIOC_DISABLE, &svc) < 0) {
- if (errno != SV_EDISABLED) {
- spcs_log("sv", &svc.svc_error,
- gettext("%s: unable to suspend %s"),
- program, path);
-
- warn(&svc.svc_error,
- gettext("unable to suspend %s"), path);
- return;
- }
- }
-
- spcs_log("sv", NULL, gettext("%s: suspend %s"), program, path);
-
- spcs_s_ufree(&svc.svc_error);
-}
-
-
-static void
-suspend_sv(void)
-{
- sv_name_t *svn, *svn_system; /* Devices in system */
- sv_list_t svl_system;
- int i;
- int fd;
-
- svn_system = sv_alloc_svnames();
-
- svl_system.svl_count = read_libcfg(svn_system);
-
- if ((fd = open(sv_rpath, O_RDONLY)) < 0) {
- warn(NULL, gettext("unable to open %s: %s"),
- sv_rpath, strerror(errno));
- return;
- }
-
- for (i = 0; i < svl_system.svl_count; i++) {
- if (*svn_system[i].svn_path == '\0')
- break;
-
- svn = &svn_system[i];
- suspend_dev(fd, svn->svn_path);
- }
-
- (void) close(fd);
-}
-
-
-/*
- * Check kernel's sv_ndevices and thread sets,
- * if empty then change kernel state to allow unload,
- * and sleep SV_WAIT_UNLAOD (10 seconds).
- *
- * Only called in pkgrm time.
- */
-static void
-prepare_unload_sv(void)
-{
- int fd;
- int rc = 0;
-
- if ((fd = open(sv_rpath, O_RDONLY)) < 0) {
- warn(NULL, gettext("unable to open %s: %s"),
- sv_rpath, strerror(errno));
- return;
- }
-
- if (ioctl(fd, SVIOC_UNLOAD, &rc) < 0)
- error(NULL, gettext("unable to unload"));
-
- if (rc != 0)
- error(NULL, gettext("still has active devices or threads"));
-
- (void) close(fd);
-}
diff --git a/usr/src/cmd/avs/svc/Makefile b/usr/src/cmd/avs/svc/Makefile
deleted file mode 100644
index 751aa9e5cc..0000000000
--- a/usr/src/cmd/avs/svc/Makefile
+++ /dev/null
@@ -1,54 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-include ../../Makefile.cmd
-
-XML = nws_scm.xml nws_sv.xml nws_ii.xml nws_rdc.xml nws_rdcsyncd.xml
-SHFILES = $(XML)
-
-ROOTSVCSYSFILES = $(XML:%=$(ROOTSVCSYSTEM)/%)
-
-.KEEP_STATE:
-
-.PARALLEL: $(OBJS)
-
-all: $(SHFILES)
-
-lint:
-
-install: all $(ROOTSVCSYSFILES)
-
-clean:
- $(RM) *.xml
-
-$(SHFILES): $(XML:%=manifest/%)
- $(RM) $(@F)
- $(CP) $(@F:%=manifest/%) .
-
-FILEMODE = 0444
-
-$(ROOTSVCSYSFILES): $(SHFILES)
-
-
-include ../../Makefile.targ
diff --git a/usr/src/cmd/avs/svc/manifest/nws_ii.xml b/usr/src/cmd/avs/svc/manifest/nws_ii.xml
deleted file mode 100644
index 6a1c330db5..0000000000
--- a/usr/src/cmd/avs/svc/manifest/nws_ii.xml
+++ /dev/null
@@ -1,100 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
-<!--
-CDDL HEADER START
-
-The contents of this file are subject to the terms of the
-Common Development and Distribution License (the "License").
-You may not use this file except in compliance with the License.
-
-You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-or http://www.opensolaris.org/os/licensing.
-See the License for the specific language governing permissions
-and limitations under the License.
-
-When distributing Covered Code, include this CDDL HEADER in each
-file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-If applicable, add the following below this CDDL HEADER, with the
-fields enclosed by brackets "[]" replaced with your own identifying
-information: Portions Copyright [yyyy] [name of copyright owner]
-
-CDDL HEADER END
-
- Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- Use is subject to license terms.
-
- Service manifest for Availability Suite init.
--->
-
-<service_bundle type='manifest' name='SUNWscmr:nws_ii'>
-
-<service
- name='system/nws_ii'
- type='service'
- version='1'>
-
- <create_default_instance enabled='false' />
-
- <single_instance />
-
- <dependency
- name='nws_ii_sv'
- type='service'
- grouping='require_all'
- restart_on='none'>
- <service_fmri value='svc:/system/nws_sv' />
- </dependency>
-
- <!--
- We need to make sure that no user filesystems can mount until
- AVS has configured, since user filesystems may be mounted on
- volumes under AVS control
- -->
- <dependent
- name='nws_ii-local-fs'
- grouping='optional_all'
- restart_on='none'>
- <service_fmri value='svc:/system/filesystem/local' />
- </dependent>
-
- <exec_method
- type='method'
- name='start'
- exec='/lib/svc/method/svc-ii %m'
- timeout_seconds='300' />
-
- <exec_method
- type='method'
- name='stop'
- exec='/lib/svc/method/svc-ii %m'
- timeout_seconds='600' />
-
- <property_group
- name='startd'
- type='framework'>
- <propval
- name='duration'
- type='astring'
- value='transient' />
- </property_group>
-
-
- <stability value='Unstable' />
-
- <template>
- <common_name>
- <loctext xml:lang='C'>
- Network Storage Instant Image Init service.
- </loctext>
- </common_name>
-
- <documentation>
- <manpage
- title='iiadm'
- section='1M'
- manpath='/usr/share/man' />
- </documentation>
- </template>
-</service>
-
-</service_bundle>
diff --git a/usr/src/cmd/avs/svc/manifest/nws_rdc.xml b/usr/src/cmd/avs/svc/manifest/nws_rdc.xml
deleted file mode 100644
index c2a231bf64..0000000000
--- a/usr/src/cmd/avs/svc/manifest/nws_rdc.xml
+++ /dev/null
@@ -1,108 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
-<!--
-CDDL HEADER START
-
-The contents of this file are subject to the terms of the
-Common Development and Distribution License (the "License").
-You may not use this file except in compliance with the License.
-
-You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-or http://www.opensolaris.org/os/licensing.
-See the License for the specific language governing permissions
-and limitations under the License.
-
-When distributing Covered Code, include this CDDL HEADER in each
-file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-If applicable, add the following below this CDDL HEADER, with the
-fields enclosed by brackets "[]" replaced with your own identifying
-information: Portions Copyright [yyyy] [name of copyright owner]
-
-CDDL HEADER END
-
- Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- Use is subject to license terms.
-
- Service manifest for Availability Suite init.
--->
-
-<service_bundle type='manifest' name='SUNWscmr:nws_rdc'>
-
-<service
- name='system/nws_rdc'
- type='service'
- version='1'>
-
- <create_default_instance enabled='false' />
-
- <single_instance />
-
- <dependency
- name='nws_rdc_sv'
- type='service'
- grouping='require_all'
- restart_on='none'>
- <service_fmri value='svc:/system/nws_sv' />
- </dependency>
-
- <dependency
- name='nws_rdc_ii'
- type='service'
- grouping='optional_all'
- restart_on='none'>
- <service_fmri value='svc:/system/nws_ii' />
- </dependency>
-
- <!--
- We need to make sure that no user filesystems can mount until
- AVS has configured, since user filesystems may be mounted on
- volumes under AVS control
- -->
- <dependent
- name='nws_rdc-local-fs'
- grouping='optional_all'
- restart_on='none'>
- <service_fmri value='svc:/system/filesystem/local' />
- </dependent>
-
- <exec_method
- type='method'
- name='start'
- exec='/lib/svc/method/svc-rdc %m'
- timeout_seconds='300' />
-
- <exec_method
- type='method'
- name='stop'
- exec='/lib/svc/method/svc-rdc %m'
- timeout_seconds='600' />
-
- <property_group
- name='startd'
- type='framework'>
- <propval
- name='duration'
- type='astring'
- value='transient' />
- </property_group>
-
-
- <stability value='Unstable' />
-
- <template>
- <common_name>
- <loctext xml:lang='C'>
- Network Storage Remote Data Replication Init service.
- </loctext>
- </common_name>
-
- <documentation>
- <manpage
- title='sndrd'
- section='1rdc'
- manpath='/usr/share/man' />
- </documentation>
- </template>
-</service>
-
-</service_bundle>
diff --git a/usr/src/cmd/avs/svc/manifest/nws_rdcsyncd.xml b/usr/src/cmd/avs/svc/manifest/nws_rdcsyncd.xml
deleted file mode 100644
index b6b416beb4..0000000000
--- a/usr/src/cmd/avs/svc/manifest/nws_rdcsyncd.xml
+++ /dev/null
@@ -1,101 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
-<!--
-CDDL HEADER START
-
-The contents of this file are subject to the terms of the
-Common Development and Distribution License (the "License").
-You may not use this file except in compliance with the License.
-
-You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-or http://www.opensolaris.org/os/licensing.
-See the License for the specific language governing permissions
-and limitations under the License.
-
-When distributing Covered Code, include this CDDL HEADER in each
-file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-If applicable, add the following below this CDDL HEADER, with the
-fields enclosed by brackets "[]" replaced with your own identifying
-information: Portions Copyright [yyyy] [name of copyright owner]
-
-CDDL HEADER END
-
- Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- Use is subject to license terms.
-
- Service manifest for Availability Suite init.
--->
-
-<service_bundle type='manifest' name='SUNWscmr:nws_rdcsyncd'>
-
-<service
- name='system/nws_rdcsyncd'
- type='service'
- version='1'>
-
- <create_default_instance enabled='false' />
-
- <single_instance />
-
- <dependency
- name='nws_rdcsyncd_rdc'
- type='service'
- grouping='require_all'
- restart_on='none'>
- <service_fmri value='svc:/system/nws_rdc' />
- </dependency>
-
- <!--
- This dependency is necessary to make sure that
- network/rpc/bind:default has started. Since rpc/bind is Unstable,
- the dependency on it cannot be explicitly specified.
- -->
- <dependency
- name='nws_rdc_multi-user'
- type='service'
- grouping='require_all'
- restart_on='none'>
- <service_fmri value='svc:/milestone/multi-user' />
- </dependency>
-
- <exec_method
- type='method'
- name='start'
- exec='/lib/svc/method/svc-rdcsyncd %m'
- timeout_seconds='60' />
-
- <exec_method
- type='method'
- name='stop'
- exec='/lib/svc/method/svc-rdcsyncd %m'
- timeout_seconds='20' />
-
- <property_group
- name='startd'
- type='framework'>
- <propval
- name='duration'
- type='astring'
- value='transient' />
- </property_group>
-
-
- <stability value='Unstable' />
-
- <template>
- <common_name>
- <loctext xml:lang='C'>
- Network Storage Remote Data Replication Syncd service.
- </loctext>
- </common_name>
-
- <documentation>
- <manpage
- title='sndrsyncd'
- section='1rdc'
- manpath='/usr/share/man' />
- </documentation>
- </template>
-</service>
-
-</service_bundle>
diff --git a/usr/src/cmd/avs/svc/manifest/nws_scm.xml b/usr/src/cmd/avs/svc/manifest/nws_scm.xml
deleted file mode 100644
index 7714afbeb9..0000000000
--- a/usr/src/cmd/avs/svc/manifest/nws_scm.xml
+++ /dev/null
@@ -1,123 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
-<!--
-CDDL HEADER START
-
-The contents of this file are subject to the terms of the
-Common Development and Distribution License (the "License").
-You may not use this file except in compliance with the License.
-
-You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-or http://www.opensolaris.org/os/licensing.
-See the License for the specific language governing permissions
-and limitations under the License.
-
-When distributing Covered Code, include this CDDL HEADER in each
-file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-If applicable, add the following below this CDDL HEADER, with the
-fields enclosed by brackets "[]" replaced with your own identifying
-information: Portions Copyright [yyyy] [name of copyright owner]
-
-CDDL HEADER END
-
- Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- Use is subject to license terms.
-
- Service manifest for Availability Suite init.
--->
-
-<service_bundle type='manifest' name='SUNWscmr:nws_scm'>
-
-<service
- name='system/nws_scm'
- type='service'
- version='1'>
-
- <create_default_instance enabled='false' />
-
- <single_instance />
-
- <!--
- We want our services to start up after single-user mode.
- This also satisfies our dependency on system/filesystem/minimal.
- We need to make sure we have /usr and /var mounted. /usr, because
- that's where our software is installed. /var, since that's where
- ds.log is stored. Single-user also satisfies the nws_rdc dependency
- on system/identity:node.
- -->
- <dependency
- name='nws_scm-single-user'
- type='service'
- grouping='require_all'
- restart_on='none'>
- <service_fmri value='svc:/milestone/single-user' />
- </dependency>
-
- <!--
- We need to make sure that all device links have been created in
- the /dev tree, and that all local and fabric devices are
- available. We also need to make sure that vxvm and svm devices
- have been configured at this point. Right now, the
- 'milestone/devices' takes care of all of these.
- -->
- <dependency
- name='nws_scm-dev-milestone'
- type='service'
- grouping='require_all'
- restart_on='none'>
- <service_fmri value='svc:/milestone/devices' />
- </dependency>
-
- <!--
- We need to make sure that no user filesystems can mount until
- AVS has configured, since user filesystems may be mounted on
- volumes under AVS control
- -->
- <dependent
- name='nws_scm-local-fs'
- grouping='optional_all'
- restart_on='none'>
- <service_fmri value='svc:/system/filesystem/local' />
- </dependent>
-
- <exec_method
- type='method'
- name='start'
- exec='/lib/svc/method/svc-scm %m'
- timeout_seconds='180' />
-
- <exec_method
- type='method'
- name='stop'
- exec='/lib/svc/method/svc-scm %m'
- timeout_seconds='180' />
-
- <property_group
- name='startd'
- type='framework'>
- <propval
- name='duration'
- type='astring'
- value='transient' />
- </property_group>
-
-
- <stability value='Unstable' />
-
- <template>
- <common_name>
- <loctext xml:lang='C'>
- Network Storage Core Init service.
- </loctext>
- </common_name>
-
- <documentation>
- <manpage
- title='scmadm'
- section='1scm'
- manpath='/usr/share/man' />
- </documentation>
- </template>
-</service>
-
-</service_bundle>
diff --git a/usr/src/cmd/avs/svc/manifest/nws_sv.xml b/usr/src/cmd/avs/svc/manifest/nws_sv.xml
deleted file mode 100644
index cb62572431..0000000000
--- a/usr/src/cmd/avs/svc/manifest/nws_sv.xml
+++ /dev/null
@@ -1,100 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
-<!--
-CDDL HEADER START
-
-The contents of this file are subject to the terms of the
-Common Development and Distribution License (the "License").
-You may not use this file except in compliance with the License.
-
-You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-or http://www.opensolaris.org/os/licensing.
-See the License for the specific language governing permissions
-and limitations under the License.
-
-When distributing Covered Code, include this CDDL HEADER in each
-file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-If applicable, add the following below this CDDL HEADER, with the
-fields enclosed by brackets "[]" replaced with your own identifying
-information: Portions Copyright [yyyy] [name of copyright owner]
-
-CDDL HEADER END
-
- Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- Use is subject to license terms.
-
- Service manifest for Availability Suite init.
--->
-
-<service_bundle type='manifest' name='SUNWscmr:nws_sv'>
-
-<service
- name='system/nws_sv'
- type='service'
- version='1'>
-
- <create_default_instance enabled='false' />
-
- <single_instance />
-
- <dependency
- name='nws_sv_scm'
- type='service'
- grouping='require_all'
- restart_on='none'>
- <service_fmri value='svc:/system/nws_scm' />
- </dependency>
-
- <!--
- We need to make sure that no user filesystems can mount until
- AVS has configured, since user filesystems may be mounted on
- volumes under AVS control
- -->
- <dependent
- name='nws_sv-local-fs'
- grouping='optional_all'
- restart_on='none'>
- <service_fmri value='svc:/system/filesystem/local' />
- </dependent>
-
- <exec_method
- type='method'
- name='start'
- exec='/lib/svc/method/svc-sv %m'
- timeout_seconds='300' />
-
- <exec_method
- type='method'
- name='stop'
- exec='/lib/svc/method/svc-sv %m'
- timeout_seconds='600' />
-
- <property_group
- name='startd'
- type='framework'>
- <propval
- name='duration'
- type='astring'
- value='transient' />
- </property_group>
-
-
- <stability value='Unstable' />
-
- <template>
- <common_name>
- <loctext xml:lang='C'>
- Network Storage Storage Volume Init service.
- </loctext>
- </common_name>
-
- <documentation>
- <manpage
- title='svadm'
- section='1sv'
- manpath='/usr/share/man' />
- </documentation>
- </template>
-</service>
-
-</service_bundle>
diff --git a/usr/src/cmd/mdb/Makefile.common b/usr/src/cmd/mdb/Makefile.common
index dcff6b3898..41de4dfdc2 100644
--- a/usr/src/cmd/mdb/Makefile.common
+++ b/usr/src/cmd/mdb/Makefile.common
@@ -70,7 +70,6 @@ COMMON_MODULES_KVM = \
hook \
neti \
idm \
- ii \
ip \
ipc \
ipp \
@@ -82,18 +81,15 @@ COMMON_MODULES_KVM = \
mpt_sas \
mr_sas \
nca \
- nsctl \
nsmb \
pmcs \
ptm \
qlc \
random \
- rdc \
s1394 \
scsi_vhci \
sctp \
sd \
- sdbc \
smbfs \
smbsrv \
sockfs \
@@ -102,7 +98,6 @@ COMMON_MODULES_KVM = \
srpt \
stmf \
stmf_sbd \
- sv \
ufs \
usba \
zfs
diff --git a/usr/src/cmd/mdb/common/modules/ii/Makefile.com b/usr/src/cmd/mdb/common/modules/ii/Makefile.com
deleted file mode 100644
index 40975cea69..0000000000
--- a/usr/src/cmd/mdb/common/modules/ii/Makefile.com
+++ /dev/null
@@ -1,24 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-CPPFLAGS += -DNSC_MULTI_TERABYTE
diff --git a/usr/src/cmd/mdb/common/modules/ii/ii.c b/usr/src/cmd/mdb/common/modules/ii/ii.c
deleted file mode 100644
index 48bc03502b..0000000000
--- a/usr/src/cmd/mdb/common/modules/ii/ii.c
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <stddef.h>
-
-#include <sys/types.h>
-#include <sys/mdb_modapi.h>
-
-#include <sys/nsctl/nsctl.h>
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_k.h>
-
-
-#include <sys/nsctl/dsw.h>
-#include <sys/nsctl/dsw_dev.h>
-
-#include <sys/nsctl/nsvers.h>
-
-
-const mdb_bitmask_t bi_flags_bits[] = {
- { "DSW_GOLDEN", DSW_GOLDEN, DSW_GOLDEN },
- { "DSW_COPYINGP", DSW_COPYINGP, DSW_COPYINGP },
- { "DSW_COPYINGM", DSW_COPYINGM, DSW_COPYINGM },
- { "DSW_COPYINGS", DSW_COPYINGS, DSW_COPYINGS },
- { "DSW_COPYINGX", DSW_COPYINGX, DSW_COPYINGX },
- { "DSW_BMPOFFLINE", DSW_BMPOFFLINE, DSW_BMPOFFLINE },
- { "DSW_SHDOFFLINE", DSW_SHDOFFLINE, DSW_SHDOFFLINE },
- { "DSW_MSTOFFLINE", DSW_MSTOFFLINE, DSW_MSTOFFLINE },
- { "DSW_OVROFFLINE", DSW_OVROFFLINE, DSW_OVROFFLINE },
- { "DSW_TREEMAP", DSW_TREEMAP, DSW_TREEMAP },
- { "DSW_OVERFLOW", DSW_OVERFLOW, DSW_OVERFLOW },
- { "DSW_SHDEXPORT", DSW_SHDEXPORT, DSW_SHDEXPORT },
- { "DSW_SHDIMPORT", DSW_SHDIMPORT, DSW_SHDIMPORT },
- { "DSW_VOVERFLOW", DSW_VOVERFLOW, DSW_VOVERFLOW },
- { "DSW_HANGING", DSW_HANGING, DSW_HANGING },
- { "DSW_CFGOFFLINE", DSW_CFGOFFLINE, DSW_CFGOFFLINE },
- { "DSW_OVRHDRDRTY", DSW_OVRHDRDRTY, DSW_OVRHDRDRTY },
- { "DSW_RESIZED", DSW_RESIZED, DSW_RESIZED },
- { "DSW_FRECLAIM", DSW_FRECLAIM, DSW_FRECLAIM },
- { NULL, 0, 0 }
-};
-
-const mdb_bitmask_t bi_state_bits[] = {
- { "DSW_IOCTL", DSW_IOCTL, DSW_IOCTL },
- { "DSW_CLOSING", DSW_CLOSING, DSW_CLOSING },
- { "DSW_MSTTARGET", DSW_MSTTARGET, DSW_MSTTARGET },
- { "DSW_MULTIMST", DSW_MULTIMST, DSW_MULTIMST },
- { NULL, 0, 0 }
-};
-static uintptr_t nextaddr;
-/*
- * Display a ii_fd_t
- * Requires an address.
- */
-/*ARGSUSED*/
-static int
-ii_fd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- ii_fd_t fd;
-
- if (!(flags & DCMD_ADDRSPEC))
- return (DCMD_USAGE);
-
- if (mdb_vread(&fd, sizeof (fd), addr) != sizeof (fd)) {
- mdb_warn("failed to read ii_fd_t at 0x%p", addr);
- return (DCMD_ERR);
- }
-
- mdb_inc_indent(4);
- mdb_printf("ii_info: 0x%p ii_bmp: %d ii_shd: %d ii_ovr: %d ii_optr: "
- "0x%p\nii_oflags: 0x%x\n", fd.ii_info, fd.ii_bmp, fd.ii_shd,
- fd.ii_ovr, fd.ii_optr, fd.ii_oflags);
- mdb_dec_indent(4);
-
- return (DCMD_OK);
-}
-
-/*
- * displays a ii_info_dev structure.
- */
-/*ARGSUSED*/
-static int
-ii_info_dev(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- _ii_info_dev_t ipdev;
-
- if (!(flags & DCMD_ADDRSPEC))
- return (DCMD_USAGE);
-
- if (mdb_vread(&ipdev, sizeof (ipdev), addr) != sizeof (ipdev)) {
- mdb_warn("failed to read ii_info_dev_t at 0x%p", addr);
- return (DCMD_ERR);
- }
-
- mdb_inc_indent(4);
- mdb_printf("bi_fd: 0x%p bi_iodev: 0x%p bi_tok: 0x%p\n",
- ipdev.bi_fd, ipdev.bi_iodev, ipdev.bi_tok);
- mdb_printf("bi_ref: %d bi_rsrv: %d bi_orsrv: %d\n",
- ipdev.bi_ref, ipdev.bi_rsrv, ipdev.bi_orsrv);
-
- /*
- * use nsc_fd to dump the fd details.... if present.
- */
- if (ipdev.bi_fd) {
- mdb_printf("nsc_fd structure:\n");
- mdb_inc_indent(4);
- mdb_call_dcmd("nsc_fd", (uintptr_t)(ipdev.bi_fd),
- flags, 0, NULL);
- mdb_dec_indent(4);
- }
- mdb_dec_indent(4);
- return (DCMD_OK);
-}
-
-/*
- * Displays an _ii_overflow structure
- */
-/*ARGSUSED*/
-static int
-ii_overflow(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- _ii_overflow_t ii_overflow;
-
- nextaddr = 0;
- if (!(flags & DCMD_ADDRSPEC))
- return (DCMD_USAGE);
-
- if (mdb_vread(&ii_overflow, sizeof (ii_overflow), addr)
- != sizeof (ii_overflow)) {
- mdb_warn("failed to read ii_overflow_t at 0x%p", addr);
- return (DCMD_ERR);
- }
-
- mdb_inc_indent(4);
- mdb_printf("_ii_overflow at 0x%p\n", addr);
- mdb_printf("_ii_doverflow_t\n");
- mdb_inc_indent(4);
- mdb_printf("ii_dvolname: %s\n", ii_overflow.ii_volname);
- mdb_printf("ii_dhmagic: %x\n", ii_overflow.ii_hmagic);
- mdb_printf("ii_dhversion: %x\n", ii_overflow.ii_hversion);
- mdb_printf("ii_ddrefcnt: %x\n", ii_overflow.ii_drefcnt);
- mdb_printf("ii_dflags: %x\n", ii_overflow.ii_flags);
- mdb_printf("ii_dfreehead: %x\n", ii_overflow.ii_freehead);
- mdb_printf("ii_dnchunks: %x\n", ii_overflow.ii_nchunks);
- mdb_printf("ii_dunused: %x\n", ii_overflow.ii_unused);
- mdb_printf("ii_dused: %x\n", ii_overflow.ii_used);
- mdb_printf("ii_urefcnt: %x\n", ii_overflow.ii_urefcnt);
- mdb_dec_indent(4);
-
- mdb_printf("ii_mutex: %x\n", ii_overflow.ii_mutex);
- mdb_printf("ii_kstat_mutex: %x\n", ii_overflow.ii_kstat_mutex);
- mdb_printf("ii_crefcnt: %d\n", ii_overflow.ii_crefcnt);
- mdb_printf("ii_detachcnt: %d\n", ii_overflow.ii_detachcnt);
- mdb_printf("ii_next: %x\n", ii_overflow.ii_next);
-
- mdb_printf("Overflow volume:\n");
- if (ii_overflow.ii_dev)
- ii_info_dev((uintptr_t)ii_overflow.ii_dev, flags, 0, NULL);
-
- mdb_printf(" ii_ioname: %s\n", &ii_overflow.ii_ioname);
- mdb_dec_indent(4);
-
- nextaddr = (uintptr_t)ii_overflow.ii_next;
- return (DCMD_OK);
-}
-/*ARGSUSED*/
-static int
-ii_info(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- _ii_info_t ii_info = {0};
- char string[DSW_NAMELEN];
-
- nextaddr = 0;
- if (!(flags & DCMD_ADDRSPEC))
- return (DCMD_USAGE);
-
- if (mdb_vread(&ii_info, sizeof (ii_info), addr) != sizeof (ii_info)) {
- mdb_warn("failed to read ii_info_t at 0x%p", addr);
- return (DCMD_ERR);
- }
-
- mdb_printf(
- "bi_next: 0x%p\n"
- "bi_head: 0x%p\t"
- "bi_sibling: 0x%p\n"
- "bi_master: 0x%p\t"
- "bi_nextmst: 0x%p\n",
- ii_info.bi_next, ii_info.bi_head, ii_info.bi_sibling,
- ii_info.bi_master, ii_info.bi_nextmst);
-
- mdb_printf("bi_mutex: 0x%p\n", ii_info.bi_mutex);
-
- /*
- * Print out all the fds by using ii_info_dev
- */
- mdb_printf("Cache master:\n");
- if (ii_info.bi_mstdev)
- ii_info_dev((uintptr_t)ii_info.bi_mstdev, flags, 0, NULL);
-
- mdb_printf("Raw master:\n");
- if (ii_info.bi_mstrdev)
- ii_info_dev((uintptr_t)ii_info.bi_mstrdev, flags, 0, NULL);
-
- mdb_printf("Cache shadow:\n");
- ii_info_dev((uintptr_t)(addr + offsetof(_ii_info_t, bi_shddev)),
- flags, 0, NULL);
-
- mdb_printf("Raw shadow:\n");
- ii_info_dev((uintptr_t)(addr + offsetof(_ii_info_t, bi_shdrdev)),
- flags, 0, NULL);
-
- mdb_printf("Bitmap:\n");
- ii_info_dev((uintptr_t)(addr + offsetof(_ii_info_t, bi_bmpdev)),
- flags, 0, NULL);
-
- mdb_printf("bi_keyname: %-*s\n", DSW_NAMELEN, ii_info.bi_keyname);
- mdb_printf("bi_bitmap: 0x%p\n", ii_info.bi_bitmap);
-
- if ((ii_info.bi_cluster == NULL) ||
- (mdb_vread(&string, sizeof (string), (uintptr_t)ii_info.bi_cluster)
- != sizeof (string)))
- string[0] = 0;
- mdb_printf("bi_cluster: %s\n", string);
-
- if ((ii_info.bi_group == NULL) ||
- (mdb_vread(&string, sizeof (string), (uintptr_t)ii_info.bi_group)
- != sizeof (string)))
- string[0] = 0;
- mdb_printf("bi_group: %s\n", string);
-
- mdb_printf("bi_busy: 0x%p\n", ii_info.bi_busy);
-
- mdb_printf("bi_shdfba: %0x\t", ii_info.bi_shdfba);
- mdb_printf("bi_shdbits: %0x\n", ii_info.bi_shdbits);
- mdb_printf("bi_copyfba: %0x\t", ii_info.bi_copyfba);
- mdb_printf("bi_copybits: %0x\n", ii_info.bi_copybits);
-
- mdb_printf("bi_size: %0x\n", ii_info.bi_size);
-
- mdb_printf("bi_flags: 0x%x <%b>\n",
- ii_info.bi_flags, ii_info.bi_flags, bi_flags_bits);
-
- mdb_printf("bi_state: 0x%x <%b>\n",
- ii_info.bi_state, ii_info.bi_state, bi_state_bits);
-
- mdb_printf("bi_disabled: %d\n", ii_info.bi_disabled);
- mdb_printf("bi_ioctl: %d\n", ii_info.bi_ioctl);
- mdb_printf("bi_release: %d\t", ii_info.bi_release);
- mdb_printf("bi_rsrvcnt: %d\n", ii_info.bi_rsrvcnt);
-
- mdb_printf("bi_copydonecv: %x\t", ii_info.bi_copydonecv);
- mdb_printf("bi_reservecv: %x\n", ii_info.bi_reservecv);
- mdb_printf("bi_releasecv: %x\t", ii_info.bi_releasecv);
- mdb_printf("bi_closingcv: %x\n", ii_info.bi_closingcv);
- mdb_printf("bi_ioctlcv: %x\t", ii_info.bi_ioctlcv);
- mdb_printf("bi_busycv: %x\n", ii_info.bi_busycv);
- mdb_call_dcmd("rwlock", (uintptr_t)(addr +
- offsetof(_ii_info_t, bi_busyrw)), flags, 0, NULL);
- mdb_printf("bi_bitmap_ops: 0x%p\n", ii_info.bi_bitmap_ops);
-
- mdb_printf("bi_rsrvmutex: %x\t", ii_info.bi_rsrvmutex);
- mdb_printf("bi_rlsemutex: %x\n", ii_info.bi_rlsemutex);
- mdb_printf("bi_bmpmutex: %x\n", ii_info.bi_bmpmutex);
-
- mdb_printf("bi_mstchks: %d\t", ii_info.bi_mstchks);
- mdb_printf("bi_shdchks: %d\n", ii_info.bi_shdchks);
- mdb_printf("bi_shdchkused: %d\t", ii_info.bi_shdchkused);
- mdb_printf("bi_shdfchk: %d\n", ii_info.bi_shdfchk);
-
- mdb_printf("bi_overflow\n");
- if (ii_info.bi_overflow)
- ii_overflow((uintptr_t)ii_info.bi_overflow, flags, 0, NULL);
-
- mdb_printf("bi_iifd:\n");
- if (ii_info.bi_iifd)
- (void) ii_fd((uintptr_t)ii_info.bi_iifd, flags, 0, NULL);
-
- mdb_printf("bi_throttle_unit: %d\t", ii_info.bi_throttle_unit);
- mdb_printf("bi_throttle_delay: %d\n", ii_info.bi_throttle_delay);
-
- mdb_printf("bi_linkrw:\n");
- mdb_call_dcmd("rwlock", (uintptr_t)(addr +
- offsetof(_ii_info_t, bi_linkrw)), flags, 0, NULL);
-
- mdb_printf("bi_chksmutex: %x\n", ii_info.bi_chksmutex);
- mdb_printf("bi_locked_pid: %x\n", ii_info.bi_locked_pid);
- mdb_printf("bi_kstat: 0x%p\n", ii_info.bi_kstat);
- /* ii_kstat_info_t bi_kstat_io; */
-
- nextaddr = (uintptr_t)ii_info.bi_next;
- return (DCMD_OK);
-}
-
-/*
- * This should be a walker surely.
- */
-/*ARGSUSED*/
-static int
-ii_info_all(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- uintptr_t myaddr;
- /*
- * we use the global address.
- */
- if (flags & DCMD_ADDRSPEC)
- return (DCMD_USAGE);
-
- if (mdb_readsym(&myaddr, sizeof (myaddr), "_ii_info_top") !=
- sizeof (myaddr)) {
- return (DCMD_ERR);
- }
-
- mdb_printf("_ii_info_top contains 0x%lx\n", myaddr);
-
- while (myaddr) {
- ii_info(myaddr, DCMD_ADDRSPEC, 0, NULL);
- myaddr = nextaddr;
- }
- return (DCMD_OK);
-}
-
-/*
- * Display general ii module information.
- */
-
-#define ii_get_print(kvar, str, fmt, val) \
- if (mdb_readvar(&(val), #kvar) == -1) { \
- mdb_dec_indent(4); \
- mdb_warn("unable to read '" #kvar "'"); \
- return (DCMD_ERR); \
- } \
- mdb_printf("%-20s" fmt "\n", str ":", val)
-
-/* ARGSUSED */
-static int
-ii(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- int maj, min, mic, baseline, i;
-
- if (argc != 0)
- return (DCMD_USAGE);
-
- if (mdb_readvar(&maj, "dsw_major_rev") == -1) {
- mdb_warn("unable to read 'dsw_major_rev'");
- return (DCMD_ERR);
- }
-
- if (mdb_readvar(&min, "dsw_minor_rev") == -1) {
- mdb_warn("unable to read 'dsw_minor_rev'");
- return (DCMD_ERR);
- }
-
- if (mdb_readvar(&mic, "dsw_micro_rev") == -1) {
- mdb_warn("unable to read 'dsw_micro_rev'");
- return (DCMD_ERR);
- }
-
- if (mdb_readvar(&baseline, "dsw_baseline_rev") == -1) {
- mdb_warn("unable to read 'dsw_baseline_rev'");
- return (DCMD_ERR);
- }
-
- mdb_printf("Point-in-Time Copy module version: kernel %d.%d.%d.%d; "
- "mdb %d.%d.%d.%d\n", maj, min, mic, baseline,
- ISS_VERSION_MAJ, ISS_VERSION_MIN, ISS_VERSION_MIC, ISS_VERSION_NUM);
-
- mdb_inc_indent(4);
- ii_get_print(ii_debug, "debug", "%d", i);
- ii_get_print(ii_bitmap, "bitmaps", "%d", i);
- mdb_dec_indent(4);
-
- return (DCMD_OK);
-}
-
-
-/*
- * MDB module linkage information:
- */
-
-static const mdb_dcmd_t dcmds[] = {
-{ "ii", NULL, "display ii module info", ii },
-{ "ii_fd", NULL, "display ii_fd structure", ii_fd },
-{ "ii_info", NULL, "display ii_info structure", ii_info },
-{ "ii_info_all", NULL, "display all ii_info structures", ii_info_all },
-{ "ii_info_dev", NULL, "display ii_info_dev structure", ii_info_dev},
-{ "ii_overflow", NULL, "display ii_overflow structure", ii_overflow},
-{ NULL }
-};
-
-
-static const mdb_walker_t walkers[] = {
- { NULL }
-};
-
-
-static const mdb_modinfo_t modinfo = {
- MDB_API_VERSION, dcmds, walkers
-};
-
-
-const mdb_modinfo_t *
-_mdb_init(void)
-{
- return (&modinfo);
-}
diff --git a/usr/src/cmd/mdb/common/modules/nsctl/Makefile.com b/usr/src/cmd/mdb/common/modules/nsctl/Makefile.com
deleted file mode 100644
index 40975cea69..0000000000
--- a/usr/src/cmd/mdb/common/modules/nsctl/Makefile.com
+++ /dev/null
@@ -1,24 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-CPPFLAGS += -DNSC_MULTI_TERABYTE
diff --git a/usr/src/cmd/mdb/common/modules/nsctl/nsctl.c b/usr/src/cmd/mdb/common/modules/nsctl/nsctl.c
deleted file mode 100644
index e9a360deb6..0000000000
--- a/usr/src/cmd/mdb/common/modules/nsctl/nsctl.c
+++ /dev/null
@@ -1,2159 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/ksynch.h>
-#include <sys/kmem.h>
-#include <sys/errno.h>
-#include <sys/ddi.h>
-
-#include <sys/mdb_modapi.h>
-
-#define __NSC_GEN__
-#include <sys/nsc_thread.h>
-#include <sys/nsctl/nsc_dev.h>
-#include <sys/nsctl/nsc_gen.h>
-#include <sys/nsctl/nsc_mem.h>
-#include <sys/nsctl/nsctl.h>
-#include <sys/nsctl/nsc_disk.h>
-
-
-/*
- * Data struct for the complex walks.
- */
-
-struct complex_args {
- int argc;
- mdb_arg_t *argv;
-};
-
-
-/*
- * Bit definitions
- */
-
-#define NSC_RW_BITS \
- { "NSC_READ", NSC_READ, NSC_READ }, \
- { "NSC_WRITE", NSC_WRITE, NSC_WRITE }
-
-
-static const mdb_bitmask_t nsc_bhflag_bits[] = {
- NSC_RW_BITS,
- { "NSC_PINNABLE", NSC_PINNABLE, NSC_PINNABLE },
- { "NSC_NOBLOCK", NSC_NOBLOCK, NSC_NOBLOCK },
- { "NSC_HALLOCATED", NSC_HALLOCATED, NSC_HALLOCATED },
- { "NSC_HACTIVE", NSC_HACTIVE, NSC_HACTIVE },
- { "NSC_BCOPY", NSC_BCOPY, NSC_BCOPY },
- { "NSC_PAGEIO", NSC_PAGEIO, NSC_PAGEIO },
- { "NSC_ABUF", NSC_ABUF, NSC_ABUF },
- { "NSC_MIXED", NSC_MIXED, NSC_MIXED },
- { "NSC_WRTHRU", NSC_WRTHRU, NSC_WRTHRU },
- { "NSC_FORCED_WRTHRU", NSC_FORCED_WRTHRU, NSC_FORCED_WRTHRU },
- { "NSC_NOCACHE", NSC_NOCACHE, NSC_NOCACHE },
- { "NSC_QUEUE", NSC_QUEUE, NSC_QUEUE },
- { "NSC_RDAHEAD", NSC_RDAHEAD, NSC_RDAHEAD },
- { "NSC_NO_FORCED_WRTHRU", NSC_NO_FORCED_WRTHRU, NSC_NO_FORCED_WRTHRU },
- { "NSC_METADATA", NSC_METADATA, NSC_METADATA },
- { "NSC_SEQ_IO", NSC_SEQ_IO, NSC_SEQ_IO },
- { NULL, 0, 0 }
-};
-
-
-static const mdb_bitmask_t nsc_fdflag_bits[] = {
- NSC_RW_BITS,
- { NULL, 0, 0 }
-};
-
-
-static const mdb_bitmask_t nsc_fdmode_bits[] = {
- { "NSC_MULTI", NSC_MULTI, NSC_MULTI },
- { NULL, 0, 0 }
-};
-
-
-static const mdb_bitmask_t nsc_type_bits[] = {
- /* types */
- { "NSC_NULL", NSC_NULL, NSC_NULL },
- { "NSC_DEVICE", NSC_DEVICE, NSC_DEVICE },
- { "NSC_FILE", NSC_FILE, NSC_FILE },
- { "NSC_CACHE", NSC_CACHE, NSC_CACHE },
- { "NSC_VCHR", NSC_VCHR, NSC_VCHR },
- { "NSC_NCALL", NSC_NCALL, NSC_NCALL },
-
- /* type flags */
- { "NSC_ANON", NSC_ANON, NSC_ANON },
-
- /* ids */
- { "NSC_RAW_ID", NSC_RAW_ID, NSC_RAW_ID },
- { "NSC_FILE_ID", NSC_FILE_ID, NSC_FILE_ID },
- { "NSC_FREEZE_ID", NSC_FREEZE_ID, NSC_FREEZE_ID },
- { "NSC_VCHR_ID", NSC_VCHR_ID, NSC_VCHR_ID },
- { "NSC_NCALL_ID", NSC_NCALL_ID, NSC_NCALL_ID },
- { "NSC_SDBC_ID", NSC_SDBC_ID, NSC_SDBC_ID },
- { "NSC_RDCLR_ID", NSC_RDCLR_ID, NSC_RDCLR_ID },
- { "NSC_RDCL_ID", NSC_RDCL_ID, NSC_RDCL_ID },
- { "NSC_IIR_ID", NSC_IIR_ID, NSC_IIR_ID },
- { "NSC_II_ID", NSC_II_ID, NSC_II_ID },
- { "NSC_RDCHR_ID", NSC_RDCHR_ID, NSC_RDCHR_ID },
- { "NSC_RDCH_ID", NSC_RDCH_ID, NSC_RDCH_ID },
- { NULL, 0, 0 }
-};
-
-
-static const mdb_bitmask_t nsc_availpend_bits[] = {
- NSC_RW_BITS,
- { "_NSC_OPEN", _NSC_OPEN, _NSC_OPEN },
- { "_NSC_CLOSE", _NSC_CLOSE, _NSC_CLOSE },
- { "_NSC_PINNED", _NSC_PINNED, _NSC_PINNED },
- { "_NSC_ATTACH", _NSC_ATTACH, _NSC_ATTACH },
- { "_NSC_DETACH", _NSC_DETACH, _NSC_DETACH },
- { "_NSC_OWNER", _NSC_OWNER, _NSC_OWNER },
- { NULL, 0, 0 }
-};
-
-
-static const mdb_bitmask_t nsc_ioflag_bits[] = {
- { "NSC_REFCNT", NSC_REFCNT, NSC_REFCNT },
- { "NSC_FILTER", NSC_FILTER, NSC_FILTER },
- { NULL, 0, 0 }
-};
-
-
-static const mdb_bitmask_t nstset_flag_bits[] = {
- { "NST_SF_KILL", NST_SF_KILL, NST_SF_KILL },
- { NULL, 0, 0 }
-};
-
-
-static const mdb_bitmask_t nst_flag_bits[] = {
- { "NST_TF_INUSE", NST_TF_INUSE, NST_TF_INUSE },
- { "NST_TF_ACTIVE", NST_TF_ACTIVE, NST_TF_ACTIVE },
- { "NST_TF_PENDING", NST_TF_PENDING, NST_TF_PENDING },
- { "NST_TF_DESTROY", NST_TF_DESTROY, NST_TF_DESTROY },
- { "NST_TF_KILL", NST_TF_KILL, NST_TF_KILL },
- { NULL, 0, 0 }
-};
-
-
-/*
- * Global data.
- */
-
-static nsc_mem_t type_mem[20];
-static int complex_walk;
-static int complex_hdr;
-
-
-/* ---------------------------------------------------------------------- */
-
-/*
- * Walker for an nsc_io chain.
- * A global walk is assumed to start at _nsc_io_top.
- */
-
-static int
-nsc_io_winit(mdb_walk_state_t *wsp)
-{
- if (wsp->walk_addr == NULL &&
- mdb_readvar(&wsp->walk_addr, "_nsc_io_top") == -1) {
- mdb_warn("unable to read '_nsc_io_top'");
- return (WALK_ERR);
- }
-
- return (WALK_NEXT);
-}
-
-
-static int
-nsc_io_wstep(mdb_walk_state_t *wsp)
-{
- uintptr_t next;
- int status;
-
- if (wsp->walk_addr == NULL)
- return (WALK_DONE);
-
- status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
- wsp->walk_cbdata);
-
- next = wsp->walk_addr + OFFSETOF(nsc_io_t, next);
-
- if (mdb_vread(&wsp->walk_addr, sizeof (uintptr_t), next) == -1) {
- mdb_warn("failed to read nsc_io_t.next at %p", next);
- return (WALK_DONE);
- }
-
- return (status);
-}
-
-
-/* ---------------------------------------------------------------------- */
-
-/*
- * Walker for an nsc_dev chain.
- * A global walk is assumed to start at _nsc_dev_top.
- */
-
-static int
-nsc_dev_winit(mdb_walk_state_t *wsp)
-{
- if (wsp->walk_addr == NULL &&
- mdb_readvar(&wsp->walk_addr, "_nsc_dev_top") == -1) {
- mdb_warn("unable to read '_nsc_dev_top'");
- return (WALK_ERR);
- }
-
- return (WALK_NEXT);
-}
-
-
-static int
-nsc_dev_wstep(mdb_walk_state_t *wsp)
-{
- uintptr_t next;
- int status;
-
- if (wsp->walk_addr == NULL)
- return (WALK_DONE);
-
- status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
- wsp->walk_cbdata);
-
- next = wsp->walk_addr + OFFSETOF(nsc_dev_t, nsc_next);
-
- if (mdb_vread(&wsp->walk_addr, sizeof (uintptr_t), next) == -1) {
- mdb_warn("failed to read nsc_dev_t.nsc_next at %p", next);
- return (WALK_DONE);
- }
-
- return (status);
-}
-
-
-/* ARGSUSED */
-
-static void
-nsc_dev_wfini(mdb_walk_state_t *wsp)
-{
- complex_walk = 0;
-}
-
-
-/* ---------------------------------------------------------------------- */
-
-/*
- * Walker for a chain of nsc_devval_t structures.
- * Global walks start from _nsc_devval_top;
- */
-
-static int
-nsc_devval_winit(mdb_walk_state_t *wsp)
-{
- if (wsp->walk_addr == NULL &&
- mdb_readvar(&wsp->walk_addr, "_nsc_devval_top") == -1) {
- mdb_warn("unable to read '_nsc_devval_top'");
- return (WALK_ERR);
- }
-
- return (WALK_NEXT);
-}
-
-
-static int
-nsc_devval_wstep(mdb_walk_state_t *wsp)
-{
- uintptr_t devval = wsp->walk_addr;
- int status;
-
- if (!devval)
- return (WALK_DONE);
-
- status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
- wsp->walk_cbdata);
-
- /* move on to next devval */
-
- if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr),
- devval + OFFSETOF(nsc_devval_t, dv_next)) == -1) {
- mdb_warn("failed to read nsc_devval_t.dv_next");
- return (WALK_ERR);
- }
-
- return (status);
-}
-
-
-/* ---------------------------------------------------------------------- */
-
-/*
- * Walker for a chain of nsc_fd_t structures.
- * No global walks.
- */
-
-static int
-nsc_fd_winit(mdb_walk_state_t *wsp)
-{
- if (wsp->walk_addr == NULL) {
- mdb_warn("nsc_fd doesn't support global walks");
- return (WALK_ERR);
- }
-
- return (WALK_NEXT);
-}
-
-
-static int
-nsc_fd_wstep(mdb_walk_state_t *wsp)
-{
- uintptr_t fd = wsp->walk_addr;
- int status;
-
- if (!fd)
- return (WALK_DONE);
-
- status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
- wsp->walk_cbdata);
-
- /* move on to next fd */
-
- if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr),
- fd + OFFSETOF(nsc_fd_t, sf_next)) == -1) {
- mdb_warn("failed to read nsc_fd_t.sf_next");
- return (WALK_ERR);
- }
-
- return (status);
-}
-
-
-/* ---------------------------------------------------------------------- */
-
-/*
- * Walker for a chain of nsc_iodev_t structures.
- * No global walks.
- */
-
-static int
-nsc_iodev_winit(mdb_walk_state_t *wsp)
-{
- if (wsp->walk_addr == NULL) {
- mdb_warn("nsc_iodev doesn't support global walks");
- return (WALK_ERR);
- }
-
- return (WALK_NEXT);
-}
-
-
-static int
-nsc_iodev_wstep(mdb_walk_state_t *wsp)
-{
- uintptr_t iodev = wsp->walk_addr;
- int status;
-
- if (!iodev)
- return (WALK_DONE);
-
- status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
- wsp->walk_cbdata);
-
- if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr),
- iodev + OFFSETOF(nsc_iodev_t, si_next)) == -1) {
- mdb_warn("failed to read nsc_iodev_t.si_next");
- return (WALK_ERR);
- }
-
- return (status);
-}
-
-
-/* ---------------------------------------------------------------------- */
-
-/*
- * Walker for a chain of nsc_service_t structures.
- * Global walks start at _nsc_services.
- */
-
-static int
-nsc_service_winit(mdb_walk_state_t *wsp)
-{
- if (wsp->walk_addr == NULL &&
- mdb_readvar(&wsp->walk_addr, "_nsc_services") == -1) {
- mdb_warn("unable to read '_nsc_services'");
- return (WALK_ERR);
- }
-
- return (WALK_NEXT);
-}
-
-
-static int
-nsc_service_wstep(mdb_walk_state_t *wsp)
-{
- uintptr_t service = wsp->walk_addr;
- int status;
-
- if (!service)
- return (WALK_DONE);
-
- status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
- wsp->walk_cbdata);
-
- /* move on to next service */
-
- if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr),
- service + OFFSETOF(nsc_service_t, s_next)) == -1) {
- mdb_warn("failed to read nsc_service_t.s_next");
- return (WALK_ERR);
- }
-
- return (status);
-}
-
-
-/* ---------------------------------------------------------------------- */
-
-/*
- * Walker for a chain of nsc_svc_t structures.
- * No global walks.
- */
-
-static int
-nsc_svc_winit(mdb_walk_state_t *wsp)
-{
- if (wsp->walk_addr == NULL) {
- mdb_warn("nsc_svc does not support global walks");
- return (WALK_ERR);
- }
-
- return (WALK_NEXT);
-}
-
-
-static int
-nsc_svc_wstep(mdb_walk_state_t *wsp)
-{
- uintptr_t svc = wsp->walk_addr;
- int status;
-
- if (!svc)
- return (WALK_DONE);
-
- status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
- wsp->walk_cbdata);
-
- /* move on to next svc */
-
- if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr),
- svc + OFFSETOF(nsc_svc_t, svc_next)) == -1) {
- mdb_warn("failed to read nsc_svc_t.svc_next");
- return (WALK_ERR);
- }
-
- return (status);
-}
-
-
-/* ---------------------------------------------------------------------- */
-
-/*
- * Walker for a chain of nsc_val_t structures.
- * No global walks.
- */
-
-static int
-nsc_val_winit(mdb_walk_state_t *wsp)
-{
- if (wsp->walk_addr == NULL) {
- mdb_warn("nsc_val doesn't support global walks");
- return (WALK_ERR);
- }
-
- return (WALK_NEXT);
-}
-
-
-static int
-nsc_val_wstep(mdb_walk_state_t *wsp)
-{
- uintptr_t val = wsp->walk_addr;
- int status;
-
- if (!val)
- return (WALK_DONE);
-
- status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
- wsp->walk_cbdata);
-
- /* move on to next val */
-
- if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr),
- val + OFFSETOF(nsc_val_t, sv_next)) == -1) {
- mdb_warn("failed to read nsc_val_t.sv_next");
- return (WALK_ERR);
- }
-
- return (status);
-}
-
-
-/* ---------------------------------------------------------------------- */
-
-/*
- * Walker for a chain of nstset_t structures.
- * Global walks start at _nst_sets.
- */
-
-static int
-nstset_winit(mdb_walk_state_t *wsp)
-{
- if (wsp->walk_addr == NULL &&
- mdb_readvar(&wsp->walk_addr, "nst_sets") == -1) {
- mdb_warn("unable to read 'nst_sets'");
- return (WALK_ERR);
- }
-
- return (WALK_NEXT);
-}
-
-
-static int
-nstset_wstep(mdb_walk_state_t *wsp)
-{
- uintptr_t set = wsp->walk_addr;
- int status;
-
- if (!set)
- return (WALK_DONE);
-
- status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
- wsp->walk_cbdata);
-
- /* move on to next set */
-
- if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr),
- set + OFFSETOF(nstset_t, set_next)) == -1) {
- mdb_warn("failed to read nstset_t.set_next");
- return (WALK_ERR);
- }
-
- return (status);
-}
-
-
-/* ---------------------------------------------------------------------- */
-
-/*
- * Walker for a chain of nsthread_t structures.
- * No global walks.
- */
-
-static int
-nsthread_winit(mdb_walk_state_t *wsp)
-{
- if (wsp->walk_addr == NULL) {
- mdb_warn("nsthread does not support global walks");
- return (WALK_ERR);
- }
-
- return (WALK_NEXT);
-}
-
-
-static int
-nsthread_wstep(mdb_walk_state_t *wsp)
-{
- uintptr_t thread = wsp->walk_addr;
- int status;
-
- if (!thread)
- return (WALK_DONE);
-
- status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
- wsp->walk_cbdata);
-
- /* move on to next iodev */
-
- if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr),
- thread + OFFSETOF(nsthread_t, tp_chain)) == -1) {
- mdb_warn("failed to read nsthread_t.tp_chain");
- return (WALK_ERR);
- }
-
- return (status);
-}
-
-
-/* ---------------------------------------------------------------------- */
-
-/*
- * Walker for nsthread_t free/reuse chain.
- * No global walks.
- */
-
-static int
-nst_free_winit(mdb_walk_state_t *wsp)
-{
- if (wsp->walk_addr == NULL) {
- mdb_warn("nst_free does not support global walks");
- return (WALK_ERR);
- }
-
- /* store starting address */
-
- wsp->walk_data = (void *)wsp->walk_addr;
-
- /* move on to next thread */
-
- if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr),
- wsp->walk_addr + OFFSETOF(nsthread_t, tp_link.q_forw)) == -1) {
- mdb_warn("failed to read nsthread_t.tp_link.q_forw");
- return (WALK_ERR);
- }
-
- return (WALK_NEXT);
-}
-
-
-static int
-nst_free_wstep(mdb_walk_state_t *wsp)
-{
- uintptr_t thread = wsp->walk_addr;
- int status;
-
- if (!thread)
- return (WALK_DONE);
-
- if (thread == (uintptr_t)wsp->walk_data)
- return (WALK_DONE);
-
- status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
- wsp->walk_cbdata);
-
- /* move on to next thread */
-
- if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr),
- thread + OFFSETOF(nsthread_t, tp_link.q_forw)) == -1) {
- mdb_warn("failed to read nsthread_t.tp_link.q_forw");
- return (WALK_ERR);
- }
-
- return (status);
-}
-
-
-/* ---------------------------------------------------------------------- */
-
-/*
- * Walker for a chain of nsc_mem_t structures.
- * Global walks start at _nsc_mem_top.
- */
-
-static int
-nsc_mem_winit(mdb_walk_state_t *wsp)
-{
- if (wsp->walk_addr == NULL &&
- mdb_readvar(&wsp->walk_addr, "_nsc_mem_top") == -1) {
- mdb_warn("unable to read '_nsc_mem_top'");
- return (WALK_ERR);
- }
-
- return (WALK_NEXT);
-}
-
-
-static int
-nsc_mem_wstep(mdb_walk_state_t *wsp)
-{
- uintptr_t mem = wsp->walk_addr;
- int status;
-
- if (!mem)
- return (WALK_DONE);
-
- status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
- wsp->walk_cbdata);
-
- /* move on to next mem */
-
- if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr),
- mem + OFFSETOF(nsc_mem_t, next)) == -1) {
- mdb_warn("failed to read nsc_mem_t.next");
- return (WALK_ERR);
- }
-
- return (status);
-}
-
-
-/* ---------------------------------------------------------------------- */
-
-struct {
- char *name;
- int id;
-} io_ids[] = {
- { "NSC_RAW_ID", NSC_RAW_ID },
- { "NSC_FILE_ID", NSC_FILE_ID },
- { "NSC_FREEZE_ID", NSC_FREEZE_ID },
- { "NSC_SDBC_ID", NSC_SDBC_ID },
- { "NSC_RDCLR_ID", NSC_RDCLR_ID },
- { "NSC_RDCL_ID", NSC_RDCL_ID },
- { "NSC_IIR_ID", NSC_IIR_ID },
- { "NSC_II_ID", NSC_II_ID },
- { "NSC_RDCHR_ID", NSC_RDCHR_ID },
- { "NSC_RDCH_ID", NSC_RDCH_ID },
- { NULL, 0 }
-};
-
-
-static char *
-nsc_io_id(const int id)
-{
- int i;
-
- for (i = 0; io_ids[i].name != NULL; i++) {
- if (io_ids[i].id == id) {
- return (io_ids[i].name);
- }
- }
-
- return ("unknown");
-}
-
-
-/*
- * Display a single nsc_io_t structure.
- * If called with no address, performs a global walk of all nsc_ios.
- */
-static int
-nsc_io(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- char io_name[128];
- nsc_io_t *io;
- int v_opt;
-
- v_opt = 0;
-
- if (mdb_getopts(argc, argv,
- 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc)
- return (DCMD_USAGE);
-
- if (!(flags & DCMD_ADDRSPEC)) {
- if (mdb_walk_dcmd("nsctl`nsc_io",
- "nsctl`nsc_io", argc, argv) == -1) {
- mdb_warn("failed to walk 'nsc_io'");
- return (DCMD_ERR);
- }
-
- return (DCMD_OK);
- }
-
- io = mdb_zalloc(sizeof (*io), UM_SLEEP | UM_GC);
- memset(io_name, 0, sizeof (io_name));
-
- if (mdb_vread(io, sizeof (*io), addr) != sizeof (*io)) {
- mdb_warn("failed to read nsc_io at %p", addr);
- return (DCMD_ERR);
- }
-
- if (io->name) {
- if (mdb_readstr(io_name, sizeof (io_name),
- (uintptr_t)io->name) == -1) {
- mdb_warn("failed to read nsc_io_t.name");
- return (DCMD_ERR);
- }
- }
-
- if (DCMD_HDRSPEC(flags)) {
- mdb_printf("%-?s %8Tid fl ref abuf name\n", "io");
- }
-
- mdb_printf("%0?p %8T%08x %2x %4d %4d %s\n",
- addr, io->id, io->flag, io->refcnt, io->abufcnt, io_name);
-
- if (!v_opt)
- return (DCMD_OK);
-
- mdb_inc_indent(4);
-
- mdb_printf("id: %08x <%s>\n", io->id, nsc_io_id(io->id));
-
- mdb_printf("provide: %08x <%b>\n", io->provide,
- io->provide, nsc_type_bits);
-
- mdb_printf("flag: %08x <%b>\n", io->flag, io->flag, nsc_ioflag_bits);
-
- mdb_printf("pend: %d\n", io->pend);
-
- mdb_dec_indent(4);
-
- return (DCMD_OK);
-}
-
-
-/* ---------------------------------------------------------------------- */
-
-/*
- * Display a single nsc_dev_t structure.
- * If called with no address, performs a global walk of all nsc_devs.
- */
-static int
-nsc_dev(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- char path[NSC_MAXPATH+1];
- nsc_devval_t *dv;
- nsc_dev_t *dev;
- uintptr_t dev_pend;
- int a_opt, v_opt;
-
- a_opt = v_opt = 0;
-
- if (mdb_getopts(argc, argv,
- 'a', MDB_OPT_SETBITS, TRUE, &a_opt,
- 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc)
- return (DCMD_USAGE);
-
- if (!(flags & DCMD_ADDRSPEC)) {
- mdb_printf("Active device structures:\n");
-
- if (mdb_walk_dcmd("nsctl`nsc_dev",
- "nsctl`nsc_dev", argc, argv) == -1) {
- mdb_warn("failed to walk 'nsc_dev'");
- return (DCMD_ERR);
- }
-
- if (a_opt) {
- if (mdb_readvar(&dev_pend, "_nsc_dev_pend") == -1) {
- mdb_warn("failed to read _nsc_dev_pend");
- return (DCMD_ERR);
- }
-
- mdb_printf("\nPending device structures:");
-
- if (dev_pend) {
- mdb_printf("\n");
-
- if (mdb_pwalk_dcmd("nsctl`nsc_dev",
- "nsctl`nsc_dev", argc, argv,
- dev_pend) == -1) {
- mdb_warn("failed to walk "
- "pending dev structs");
- return (DCMD_ERR);
- }
- } else {
- mdb_printf(" none\n");
- }
- }
-
- return (DCMD_OK);
- }
-
- memset(path, 0, sizeof (path));
- dev = mdb_zalloc(sizeof (*dev), UM_SLEEP | UM_GC);
-
- if (mdb_vread(dev, sizeof (*dev), addr) != sizeof (*dev)) {
- mdb_warn("failed to read nsc_dev at %p", addr);
- return (DCMD_ERR);
- }
-
- if (mdb_readstr(path, sizeof (path), (uintptr_t)dev->nsc_path) == -1) {
- mdb_warn("failed to read nsc_path at %p", dev->nsc_path);
- return (DCMD_ERR);
- }
-
- if (DCMD_HDRSPEC(flags)) {
- mdb_printf("%-?s %8Tref pend rpnd wait path\n", "dev");
- }
-
- mdb_printf("%0?p %8T%3d %4d %4d %4d %s\n",
- addr, dev->nsc_refcnt, dev->nsc_pend, dev->nsc_rpend,
- dev->nsc_wait, path);
-
- if (!v_opt)
- return (DCMD_OK);
-
- mdb_inc_indent(4);
-
- mdb_printf("next: %0?p %8Tclose: %0?p\n",
- dev->nsc_next, dev->nsc_close);
-
- mdb_printf("list: %0?p %8Tlock: %0?p\n",
- dev->nsc_list, addr + OFFSETOF(nsc_dev_t, nsc_lock));
-
- mdb_printf("cv: %0?p %8Tpath: %0?p %8Tphash: %016llx\n",
- addr + OFFSETOF(nsc_dev_t, nsc_cv),
- dev->nsc_path, dev->nsc_phash);
-
- mdb_printf("drop: %d %8Treopen: %d\n",
- dev->nsc_drop, dev->nsc_reopen);
-
- if (dev->nsc_values) {
- dv = mdb_zalloc(sizeof (*dv), UM_SLEEP | UM_GC);
- if (mdb_vread(dv, sizeof (*dv), (uintptr_t)dev->nsc_values) !=
- sizeof (*dv)) {
- mdb_warn("unable to read nsc_dev_t.nsc_values");
- mdb_dec_indent(4);
- return (DCMD_ERR);
- }
-
- if (dv->dv_values) {
- mdb_printf("device/values: (nsc_devval: %0?p)\n",
- dev->nsc_values);
-
- mdb_inc_indent(4);
-
- if (mdb_pwalk_dcmd("nsctl`nsc_val", "nsctl`nsc_val",
- 0, NULL, (uintptr_t)dv->dv_values) == -1) {
- mdb_dec_indent(8);
- return (DCMD_ERR);
- }
-
- mdb_dec_indent(4);
- }
- }
-
- mdb_dec_indent(4);
-
- return (DCMD_OK);
-}
-
-
-/* ---------------------------------------------------------------------- */
-
-/*
- * Display a single nsc_devval_t structure.
- * If called with no address, performs a global walk of all nsc_devs.
- */
-static int
-nsc_devval(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- nsc_devval_t *dv;
- int a_opt;
-
- a_opt = 0;
-
- if (mdb_getopts(argc, argv,
- 'a', MDB_OPT_SETBITS, TRUE, &a_opt) != argc)
- return (DCMD_USAGE);
-
- if (!(flags & DCMD_ADDRSPEC)) {
- if (mdb_walk_dcmd("nsctl`nsc_devval",
- "nsctl`nsc_devval", argc, argv) == -1) {
- mdb_warn("failed to walk 'nsc_devval'");
- return (DCMD_ERR);
- }
-
- return (DCMD_OK);
- }
-
- dv = mdb_zalloc(sizeof (*dv), UM_SLEEP | UM_GC);
-
- if (mdb_vread(dv, sizeof (*dv), addr) != sizeof (*dv)) {
- mdb_warn("failed to read nsc_devval at %p", addr);
- return (DCMD_ERR);
- }
-
- if (!a_opt && !dv->dv_values) {
- return (DCMD_OK);
- }
-
- if (DCMD_HDRSPEC(flags)) {
- mdb_printf("%-?s %8T%?-s %8Tpath\n", "devval", "phash");
- }
-
- mdb_printf("%0?p %8T%016llx %8T%s\n", addr,
- dv->dv_phash, dv->dv_path);
-
- mdb_inc_indent(4);
-
- if (dv->dv_values) {
- if (mdb_pwalk_dcmd("nsctl`nsc_val", "nsctl`nsc_val",
- 0, NULL, (uintptr_t)dv->dv_values) == -1) {
- return (DCMD_ERR);
- }
- } else {
- mdb_printf("No values\n");
- }
-
- mdb_dec_indent(4);
-
- return (DCMD_OK);
-}
-
-
-/* ---------------------------------------------------------------------- */
-
-/*
- * Part 2 callback for the all devices and fds walk. Called per iodev.
- */
-/* ARGSUSED */
-static int
-nsc_fd_iodev(uintptr_t addr, const void *data, void *cbdata)
-{
- struct complex_args *fdall = cbdata;
- struct nsc_fd_t *fd;
-
- if (mdb_vread(&fd, sizeof (fd),
- addr + OFFSETOF(nsc_iodev_t, si_open)) == -1) {
- mdb_warn("unable to read nsc_iodev_t.si_open");
- return (WALK_ERR);
- }
-
- if (fd != NULL) {
- if (mdb_pwalk_dcmd("nsctl`nsc_fd", "nsctl`nsc_fd",
- fdall->argc, fdall->argv, (uintptr_t)fd) == -1)
- return (WALK_ERR);
- }
-
- return (WALK_NEXT);
-}
-
-
-/*
- * Part 1 callback for the all devices and fds walk. Called per device.
- */
-/* ARGSUSED */
-static int
-nsc_fd_dev(uintptr_t addr, const void *data, void *cbdata)
-{
- struct complex_args *fdall = cbdata;
- nsc_iodev_t *iodev;
- nsc_fd_t *fd;
-
- if (mdb_vread(&iodev, sizeof (iodev),
- addr + OFFSETOF(nsc_dev_t, nsc_list)) == -1) {
- mdb_warn("unable to read nsc_dev_t.nsc_list at %p", addr);
- return (WALK_ERR);
- }
-
- /* walk iodev chains */
-
- if (iodev != NULL) {
- if (mdb_pwalk("nsctl`nsc_iodev",
- nsc_fd_iodev, fdall, (uintptr_t)iodev) == -1)
- return (WALK_ERR);
- }
-
- /* walk nsc_close (closing fds) chains */
-
- if (mdb_vread(&fd, sizeof (fd),
- addr + OFFSETOF(nsc_dev_t, nsc_close)) == -1) {
- mdb_warn("unable to read nsc_dev_t.nsc_close at %p", addr);
- return (WALK_ERR);
- }
-
- if (fd != NULL) {
- if (mdb_pwalk_dcmd("nsctl`nsc_fd", "nsctl`nsc_fd",
- fdall->argc, fdall->argv, (uintptr_t)fd) == -1)
- return (WALK_ERR);
- }
-
- return (WALK_NEXT);
-}
-
-
-/*
- * Walk all devices and fds in the system.
- */
-static int
-nsc_fd_all(int argc, const mdb_arg_t *argv)
-{
- struct complex_args fdall;
-
- fdall.argc = argc;
- fdall.argv = (mdb_arg_t *)argv;
-
- complex_walk = 1;
- complex_hdr = 0;
-
- if (mdb_walk("nsctl`nsc_dev", nsc_fd_dev, &fdall) == -1) {
- return (DCMD_ERR);
- }
-
- return (DCMD_OK);
-}
-
-
-
-/*
- * Display an nsd_fd_t structure, or walk all devices and fds in the system.
- */
-static int
-nsc_fd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- char io_name[128], *io_namep;
- char path[NSC_MAXPATH+1];
- uintptr_t pathp;
- nsc_fd_t *fd;
- nsc_io_t *io;
- int v_opt;
- int hdr;
-
- v_opt = 0;
-
- if (mdb_getopts(argc, argv,
- 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc)
- return (DCMD_USAGE);
-
- if (!(flags & DCMD_ADDRSPEC)) {
- return (nsc_fd_all(argc, argv));
- }
-
- memset(path, 0, sizeof (path));
- fd = mdb_zalloc(sizeof (*fd), UM_SLEEP | UM_GC);
- memset(io_name, 0, sizeof (io_name));
-
- if (mdb_vread(fd, sizeof (*fd), addr) != sizeof (*fd)) {
- mdb_warn("failed to read nsc_fd at %p", addr);
- return (DCMD_ERR);
- }
-
- if (mdb_vread(&pathp, sizeof (pathp),
- (uintptr_t)fd->sf_dev + OFFSETOF(nsc_dev_t, nsc_path)) !=
- sizeof (pathp)) {
- mdb_warn("failed to read nsc_dev.nsc_path");
- return (DCMD_ERR);
- }
-
- if (mdb_readstr(path, sizeof (path), pathp) == -1) {
- mdb_warn("failed to read nsc_path");
- return (DCMD_ERR);
- }
-
- if (fd->sf_iodev) {
- if (mdb_vread(&io, sizeof (io),
- (uintptr_t)fd->sf_iodev + OFFSETOF(nsc_iodev_t, si_io)) !=
- sizeof (io)) {
- mdb_warn("failed to read nsc_iodev.si_io");
- return (DCMD_ERR);
- }
-
- if (mdb_vread(&io_namep, sizeof (io_namep),
- (uintptr_t)io + OFFSETOF(nsc_io_t, name)) !=
- sizeof (io_namep)) {
- mdb_warn("failed to read nsc_io_t.name");
- return (DCMD_ERR);
- }
-
- if (mdb_readstr(io_name, sizeof (io_name),
- (uintptr_t)io_namep) == -1) {
- mdb_warn("failed to read nsc_io_t.name string");
- return (DCMD_ERR);
- }
- }
-
- hdr = 0;
- if (complex_walk) {
- if (!complex_hdr) {
- complex_hdr = 1;
- hdr = 1;
- }
- } else if (DCMD_HDRSPEC(flags)) {
- hdr = 1;
- }
-
- if (hdr) {
- mdb_printf("%-?s %8T%-?s %8T%-8s %-?s\n",
- "fd", "dev", "io", "cd");
- mdb_printf(" %-?s %8Trv pend av path\n", "arg");
- }
-
- mdb_printf("%0?p %8T%0?p %8T%-8s %p\n",
- addr, fd->sf_dev, io_name, fd->sf_cd);
- mdb_printf(" %0?p %8T%2d %4x %2x %s\n",
- fd->sf_arg, fd->sf_reserve, fd->sf_pend,
- fd->sf_avail, path);
-
- if (!v_opt)
- return (DCMD_OK);
-
- mdb_inc_indent(4);
-
- mdb_printf("open type: %08x <%b>\n", fd->sf_type,
- fd->sf_type, nsc_type_bits);
-
- mdb_printf("avail: %08x <%b>\n", fd->sf_avail,
- fd->sf_avail, nsc_availpend_bits);
-
- mdb_printf("flag: %08x <%b>\n", fd->sf_flag,
- fd->sf_flag, nsc_fdflag_bits);
-
- mdb_printf("rsrv mode: %08x <%b>\n", fd->sf_mode,
- fd->sf_mode, nsc_fdmode_bits);
-
- mdb_printf("open lbolt: %?x %8Treopen: %d\n", fd->sf_lbolt,
- fd->sf_reopen);
-
- mdb_dec_indent(4);
-
- return (DCMD_OK);
-}
-
-
-/* ---------------------------------------------------------------------- */
-
-/*
- * Callback for the all devices and iodevs walk. Called per device.
- */
-/* ARGSUSED */
-static int
-nsc_iodev_dev(uintptr_t addr, const void *data, void *cbdata)
-{
- struct complex_args *iodevall = cbdata;
- uintptr_t iodev;
-
- if (mdb_vread(&iodev, sizeof (iodev),
- addr + OFFSETOF(nsc_dev_t, nsc_list)) == -1) {
- mdb_warn("unable to read nsc_dev_t.nsc_list at %p", addr);
- return (WALK_ERR);
- }
-
- /* walk iodev chains */
-
- if (iodev != NULL) {
- if (mdb_pwalk_dcmd("nsctl`nsc_iodev", "nsctl`nsc_iodev",
- iodevall->argc, iodevall->argv, iodev) == -1)
- return (WALK_ERR);
- }
-
- return (WALK_NEXT);
-}
-
-
-/*
- * Walk all devices and iodevs in the system.
- */
-static int
-nsc_iodev_all(int argc, const mdb_arg_t *argv)
-{
- struct complex_args iodevall;
-
- iodevall.argc = argc;
- iodevall.argv = (mdb_arg_t *)argv;
-
- complex_walk = 1;
- complex_hdr = 0;
-
- if (mdb_walk("nsctl`nsc_dev", nsc_iodev_dev, &iodevall) == -1) {
- return (DCMD_ERR);
- }
-
- return (DCMD_OK);
-}
-
-
-/*
- * Display an nsc_iodev_t structure, or walk all devices and
- * iodevs in the system.
- */
-static int
-nsc_iodev(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- char io_name[128], *io_namep;
- char path[NSC_MAXPATH+1];
- nsc_iodev_t *iodev;
- uintptr_t pathp;
- int v_opt;
- int hdr;
-
- v_opt = 0;
-
- if (mdb_getopts(argc, argv,
- 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc)
- return (DCMD_USAGE);
-
- if (!(flags & DCMD_ADDRSPEC)) {
- return (nsc_iodev_all(argc, argv));
- }
-
- memset(path, 0, sizeof (path));
- iodev = mdb_zalloc(sizeof (*iodev), UM_SLEEP | UM_GC);
- memset(io_name, 0, sizeof (io_name));
-
- if (mdb_vread(iodev, sizeof (*iodev), addr) != sizeof (*iodev)) {
- mdb_warn("failed to read nsc_iodev at %p", addr);
- return (DCMD_ERR);
- }
-
- if (mdb_vread(&pathp, sizeof (pathp),
- (uintptr_t)iodev->si_dev + OFFSETOF(nsc_dev_t, nsc_path)) !=
- sizeof (pathp)) {
- mdb_warn("failed to read nsc_dev.nsc_path");
- return (DCMD_ERR);
- }
-
- if (mdb_readstr(path, sizeof (path), pathp) == -1) {
- mdb_warn("failed to read nsc_path");
- return (DCMD_ERR);
- }
-
- if (mdb_vread(&io_namep, sizeof (io_namep),
- (uintptr_t)iodev->si_io + OFFSETOF(nsc_io_t, name)) !=
- sizeof (io_namep)) {
- mdb_warn("failed to read nsc_io_t.name");
- return (DCMD_ERR);
- }
-
- if (mdb_readstr(io_name, sizeof (io_name),
- (uintptr_t)io_namep) == -1) {
- mdb_warn("failed to read nsc_io_t.name string");
- return (DCMD_ERR);
- }
-
- hdr = 0;
- if (complex_walk) {
- if (!complex_hdr) {
- complex_hdr = 1;
- hdr = 1;
- }
- } else if (DCMD_HDRSPEC(flags)) {
- hdr = 1;
- }
-
- if (hdr) {
- mdb_printf("%-?s %8T%-?s ref %-8s path\n",
- "iodev", "dev", "io");
- }
-
- mdb_printf("%0?p %8T%0?p %3d %-8s %s\n",
- addr, iodev->si_dev, iodev->si_refcnt, io_name, path);
-
- if (!v_opt)
- return (DCMD_OK);
-
- mdb_inc_indent(4);
-
- mdb_printf("open fds: %?p %8Tactive ios: %?p\n",
- iodev->si_open, iodev->si_active);
-
- mdb_printf("busy: %d %8Trsrv pend: %d\n",
- iodev->si_busy, iodev->si_rpend);
-
- mdb_printf("pend: %08x <%b>\n", iodev->si_pend,
- iodev->si_pend, nsc_availpend_bits);
-
- mdb_printf("avail: %08x <%b>\n", iodev->si_avail,
- iodev->si_avail, nsc_availpend_bits);
-
- mdb_dec_indent(4);
-
- return (DCMD_OK);
-}
-
-
-/* ---------------------------------------------------------------------- */
-
-/*
- * Display an nsc_service_t structure, or walk all services.
- */
-static int
-nsc_service(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- nsc_service_t *service;
- char s_name[32];
- int v_opt;
-
- v_opt = 0;
-
- if (mdb_getopts(argc, argv,
- 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc)
- return (DCMD_USAGE);
-
- if (!(flags & DCMD_ADDRSPEC)) {
- if (mdb_walk_dcmd("nsctl`nsc_service",
- "nsctl`nsc_service", argc, argv) == -1) {
- mdb_warn("failed to walk 'nsc_service'");
- return (DCMD_ERR);
- }
-
- return (DCMD_OK);
- }
-
- service = mdb_zalloc(sizeof (*service), UM_SLEEP | UM_GC);
-
- if (mdb_vread(service, sizeof (*service), addr) != sizeof (*service)) {
- mdb_warn("failed to read nsc_service at %p", addr);
- return (DCMD_ERR);
- }
-
- if (DCMD_HDRSPEC(flags)) {
- mdb_printf("%-?s %8Tname\n", "service");
- }
-
- memset(s_name, 0, sizeof (s_name));
- if (service->s_name) {
- if (mdb_readstr(s_name, sizeof (s_name),
- (uintptr_t)service->s_name) == -1) {
- mdb_warn("failed to read nsc_io_t.name");
- return (DCMD_ERR);
- }
- }
-
- mdb_printf("%0?p %8T%s\n", addr, s_name);
-
- if (!v_opt)
- return (DCMD_OK);
-
- mdb_inc_indent(4);
-
- mdb_printf("servers:\n");
- if (service->s_servers == NULL) {
- mdb_printf("<none>\n");
- } else {
- mdb_inc_indent(4);
- if (mdb_pwalk_dcmd("nsctl`nsc_svc", "nsctl`nsc_svc",
- argc, argv, (uintptr_t)service->s_servers) == -1) {
- mdb_dec_indent(8);
- return (DCMD_ERR);
- }
- mdb_dec_indent(4);
- }
-
- mdb_printf("clients:\n");
- if (service->s_clients == NULL) {
- mdb_printf("<none>\n");
- } else {
- mdb_inc_indent(4);
- if (mdb_pwalk_dcmd("nsctl`nsc_svc", "nsctl`nsc_svc",
- argc, argv, (uintptr_t)service->s_clients) == -1) {
- mdb_dec_indent(8);
- return (DCMD_ERR);
- }
- mdb_dec_indent(4);
- }
-
- mdb_dec_indent(4);
-
- return (DCMD_OK);
-}
-
-
-/* ---------------------------------------------------------------------- */
-
-/*
- * Display an nsc_svc_t structure.
- */
-/*ARGSUSED*/
-static int
-nsc_svc(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- nsc_svc_t *svc;
-
- if (!(flags & DCMD_ADDRSPEC))
- return (DCMD_USAGE);
-
- svc = mdb_zalloc(sizeof (*svc), UM_SLEEP | UM_GC);
-
- if (mdb_vread(svc, sizeof (*svc), addr) != sizeof (*svc)) {
- mdb_warn("failed to read nsc_svc at %p", addr);
- return (DCMD_ERR);
- }
-
- if (DCMD_HDRSPEC(flags)) {
- mdb_printf("%-?s %8T%-?s %8Tfunc\n", "svc", "service");
- }
-
- mdb_printf("%0?p %8T%0?p %8T%a\n", addr, svc->svc_svc, svc->svc_fn);
- return (DCMD_OK);
-}
-
-
-/* ---------------------------------------------------------------------- */
-
-/*
- * Display a single nsc_val_t structure.
- * If called with no address, performs a global walk of all nsc_devs.
- */
-/* ARGSUSED3 */
-static int
-nsc_val(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- nsc_val_t *vp;
-
- if (argc != 0)
- return (DCMD_USAGE);
-
- if (!(flags & DCMD_ADDRSPEC)) {
- mdb_warn("nsc_val requires an address");
- return (DCMD_ERR);
- }
-
- vp = mdb_zalloc(sizeof (*vp), UM_SLEEP | UM_GC);
-
- if (mdb_vread(vp, sizeof (*vp), addr) != sizeof (*vp)) {
- mdb_warn("failed to read nsc_val at %p", addr);
- return (DCMD_ERR);
- }
-
- if (DCMD_HDRSPEC(flags)) {
- mdb_printf("%-?s %8T%8-s %8Tname\n", "val", "value");
- }
-
- mdb_printf("%0?p %8T%08x %8T%s\n", addr, vp->sv_value, vp->sv_name);
-
- return (DCMD_OK);
-}
-
-
-/* ---------------------------------------------------------------------- */
-
-/*
- * Display an nstset_t structure, or walk all sets.
- */
-
-static int
-nstset(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- nstset_t *set;
- int f_opt, r_opt, t_opt, v_opt;
-
- f_opt = r_opt = t_opt = v_opt = 0;
-
- if (mdb_getopts(argc, argv,
- 'f', MDB_OPT_SETBITS, TRUE, &f_opt, /* free list */
- 'r', MDB_OPT_SETBITS, TRUE, &r_opt, /* reuse list */
- 't', MDB_OPT_SETBITS, TRUE, &t_opt, /* all threads */
- 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc)
- return (DCMD_USAGE);
-
- /* displaying threads implies verbose */
- if (f_opt || r_opt || t_opt)
- v_opt = 1;
-
- if (!(flags & DCMD_ADDRSPEC)) {
- if (mdb_walk_dcmd("nsctl`nstset",
- "nsctl`nstset", argc, argv) == -1) {
- mdb_warn("failed to walk 'nstset'");
- return (DCMD_ERR);
- }
-
- return (DCMD_OK);
- }
-
- set = mdb_zalloc(sizeof (*set), UM_SLEEP | UM_GC);
-
- if (mdb_vread(set, sizeof (*set), addr) != sizeof (*set)) {
- mdb_warn("failed to read nstset at %p", addr);
- return (DCMD_ERR);
- }
-
- if (DCMD_HDRSPEC(flags)) {
- mdb_printf("%-?s %8T live nthr flag name\n", "set");
- }
-
- mdb_printf("%0?p %8T%6d %6d %4x %s\n", addr,
- set->set_nlive, set->set_nthread, set->set_flag, set->set_name);
-
- if (!v_opt)
- return (DCMD_OK);
-
- mdb_inc_indent(4);
-
- mdb_printf("chain: %0?p %8Tpending: %4d res_cnt: %4d\n",
- set->set_chain, set->set_pending, set->set_res_cnt);
-
- if (set->set_reuse.q_forw == set->set_reuse.q_back &&
- (uintptr_t)set->set_reuse.q_forw ==
- (addr + OFFSETOF(nstset_t, set_reuse))) {
- mdb_printf("reuse.forw: %-?s %8Treuse.back: %s\n",
- "empty", "empty");
- } else {
- mdb_printf("reuse.forw: %0?p %8Treuse.back: %0?p\n",
- set->set_reuse.q_forw, set->set_reuse.q_back);
-
- /* display all threads in reuse list */
- if (r_opt &&
- mdb_pwalk_dcmd("nsctl`nst_free", "nsctl`nsthread",
- 0, (const mdb_arg_t *)NULL,
- (addr + OFFSETOF(nstset_t, set_reuse))) == -1) {
- mdb_dec_indent(4);
- return (DCMD_ERR);
- }
- }
-
- if (set->set_free.q_forw == set->set_free.q_back &&
- (uintptr_t)set->set_free.q_forw ==
- (addr + OFFSETOF(nstset_t, set_free))) {
- mdb_printf("free.forw: %-?s %8Tfree.back: %s\n",
- "empty", "empty");
- } else {
- mdb_printf("free.forw: %0?p %8Tfree.back: %0?p\n",
- set->set_free.q_forw, set->set_free.q_back);
-
- /* display all threads in free list */
- if (f_opt &&
- mdb_pwalk_dcmd("nsctl`nst_free", "nsctl`nsthread",
- 0, (const mdb_arg_t *)NULL,
- (addr + OFFSETOF(nstset_t, set_free))) == -1) {
- mdb_dec_indent(4);
- return (DCMD_ERR);
- }
- }
-
- mdb_printf("flag: %08x <%b>\n",
- set->set_flag, set->set_flag, nstset_flag_bits);
-
- /* display all threads in set */
- if (t_opt) {
- mdb_printf("all threads in set:\n");
- if (mdb_pwalk_dcmd("nsctl`nsthread", "nsctl`nsthread",
- 0, (const mdb_arg_t *)NULL,
- (uintptr_t)set->set_chain) == -1) {
- mdb_dec_indent(4);
- return (DCMD_ERR);
- }
- }
-
- mdb_dec_indent(4);
-
- return (DCMD_OK);
-}
-
-
-/* ---------------------------------------------------------------------- */
-
-/*
- * Callback for the all nstsets and threads walk. Called per set.
- */
-/* ARGSUSED */
-static int
-nst_thr_set(uintptr_t addr, const void *data, void *cbdata)
-{
- struct complex_args *thrall = cbdata;
- char set_name[48];
- uintptr_t tp;
-
- if (mdb_vread(&tp, sizeof (tp),
- addr + OFFSETOF(nstset_t, set_chain)) == -1) {
- mdb_warn("unable to read nstset_t.set_chain at %p", addr);
- return (WALK_ERR);
- }
-
- memset(set_name, 0, sizeof (set_name));
-
- if (mdb_readstr(set_name, sizeof (set_name),
- addr + OFFSETOF(nstset_t, set_name)) == -1) {
- mdb_warn("unable to read nstset_t.set_name at %p", addr);
- }
-
- mdb_printf("nstset: %0?p (%s)\n", addr, set_name);
-
- /* walk thread chains */
-
- if (tp != NULL) {
- if (mdb_pwalk_dcmd("nsctl`nsthread", "nsctl`nsthread",
- thrall->argc, thrall->argv, tp) == -1)
- return (WALK_ERR);
- } else
- mdb_printf(" no threads\n");
-
- mdb_printf("\n");
-
- return (WALK_NEXT);
-}
-
-
-/*
- * Walk all nstsets and threads in the system.
- */
-static int
-nst_thr_all(int argc, const mdb_arg_t *argv)
-{
- struct complex_args thrall;
-
- thrall.argc = argc;
- thrall.argv = (mdb_arg_t *)argv;
-
- if (mdb_walk("nsctl`nstset", nst_thr_set, &thrall) == -1)
- return (DCMD_ERR);
-
- return (DCMD_OK);
-}
-
-
-/*
- * Display an nsthread_t structure, or walk all threads.
- */
-
-static int
-nsthread(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- uintptr_t thrpend;
- nsthread_t *tp;
- int a_opt, v_opt;
- int rc;
-
- a_opt = v_opt = 0;
-
- if (mdb_getopts(argc, argv,
- 'a', MDB_OPT_SETBITS, TRUE, &a_opt,
- 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc)
- return (DCMD_USAGE);
-
- if (!(flags & DCMD_ADDRSPEC)) {
- if ((rc = nst_thr_all(argc, argv)) != DCMD_OK)
- return (rc);
-
- if (a_opt) {
- if (mdb_readvar(&thrpend, "nst_pending") == -1) {
- mdb_warn("unable to read 'nst_pending'");
- return (DCMD_ERR);
- }
-
- if (thrpend) {
- mdb_printf("\nPending threads:\n");
-
- if (mdb_pwalk_dcmd("nsctl`nsthread",
- "nsctl`nsthread", argc, argv,
- thrpend) == -1) {
- mdb_warn("failed to walk 'nsthread'");
- return (DCMD_ERR);
- }
- }
- }
-
- return (DCMD_OK);
- }
-
- tp = mdb_zalloc(sizeof (*tp), UM_SLEEP | UM_GC);
-
- if (mdb_vread(tp, sizeof (*tp), addr) != sizeof (*tp)) {
- mdb_warn("failed to read nsthread at %p", addr);
- return (DCMD_ERR);
- }
-
- if (DCMD_HDRSPEC(flags)) {
- mdb_printf("%-?s %8Tflag %-?s %8Tfunc\n", "thread", "arg");
- }
-
- mdb_printf("%0?p %8T%4x %0?p %8T%a\n",
- addr, tp->tp_flag, tp->tp_arg, tp->tp_func);
-
- if (!v_opt)
- return (DCMD_OK);
-
- mdb_inc_indent(4);
-
- mdb_printf("set: %0?p %8Tchain: %0?p\n",
- tp->tp_set, tp->tp_chain);
-
- mdb_printf("link.forw: %0?p %8Tlink.back: %0?p\n",
- tp->tp_link.q_forw, tp->tp_link.q_back);
-
- mdb_printf("flag: %08x <%b>\n",
- tp->tp_flag, tp->tp_flag, nst_flag_bits);
-
- mdb_dec_indent(4);
-
- return (DCMD_OK);
-}
-
-
-/* ---------------------------------------------------------------------- */
-
-static void
-nsc_rmap(char *name)
-{
- nsc_rmmap_t slot;
- uintptr_t addr;
- int nslot;
- char *cp;
-
- if (mdb_readvar(&addr, name) == -1) {
- mdb_warn("unable to read rmap '%s'", name);
- return;
- }
-
- if (mdb_vread(&slot, sizeof (slot), addr) != sizeof (slot)) {
- mdb_warn("unable to read rmap '%s' slot 0", name);
- return;
- }
-
- mdb_printf("\nmap name offset size nslot\n");
- mdb_printf("%16s %9d %9d %5d\n",
- slot.name, slot.offset, slot.size, slot.inuse);
-
- nslot = slot.inuse;
- mdb_printf("\nslot name offset size inuse\n");
-
- while (--nslot) {
- addr += sizeof (slot);
-
- if (mdb_vread(&slot, sizeof (slot), addr) != sizeof (slot)) {
- mdb_warn("unable to read rmap '%s' slot @ %p",
- name, addr);
- return;
- }
-
- if (!slot.inuse || !slot.size)
- continue;
-
- for (cp = slot.name; *cp; cp++)
- if (*cp == ':')
- *cp = ' ';
-
- mdb_printf("%16s %9d %9d %08x\n",
- slot.name, slot.offset, slot.size, slot.inuse);
- }
-}
-
-
-static void
-nsc_rmhdr(void)
-{
- nsc_rmhdr_t *rmhdr = mdb_zalloc(sizeof (*rmhdr), UM_SLEEP | UM_GC);
- uintptr_t addr;
-
- if (mdb_readvar(&addr, "_nsc_rmhdr_ptr") == -1) {
- mdb_warn("unable to read _nsc_rmhdr_ptr");
- return;
- }
-
- if (!addr) {
- mdb_printf("\n\nGlobal header not initialised\n");
- return;
- }
-
- if (mdb_vread(rmhdr, sizeof (*rmhdr), addr) != sizeof (*rmhdr)) {
- mdb_warn("unable to read global header at %p", addr);
- return;
- }
-
- mdb_printf("\n\nglobal header (magic %08x, version %d, size %d)\n",
- rmhdr->magic, rmhdr->ver, rmhdr->size);
-
- nsc_rmap("_nsc_global_map");
-}
-
-
-static nsc_mem_t *
-memptr(int type, int flag)
-{
- int i;
-
- type &= NSC_MEM_GLOBAL;
-
- if (type)
- flag = 0;
-
- if (!type && !flag)
- return (&type_mem[0]);
-
- for (i = 1; i < (sizeof (type_mem) / sizeof (nsc_mem_t)); i++) {
- if (!type_mem[i].flag && !type_mem[i].type) {
- type_mem[i].flag = flag;
- type_mem[i].type = type;
- return (&type_mem[i]);
- }
-
- if (type_mem[i].flag == flag && type_mem[i].type == type)
- return (&type_mem[i]);
- }
-
- return (&type_mem[i]);
-}
-
-
-#define typename(t) \
- (((t) & NSC_MEM_GLOBAL) ? "gbl" : " - ")
-
-#define memname(t) \
- (((t) & NSC_MEM_GLOBAL) ? "nsc_global" : "system kmem")
-
-static void
-nsc_mem_type(const int first, nsc_mem_t *mp)
-{
- char *type, *name;
-
- if (first) {
- mdb_printf("\nregion typ f ");
- mdb_printf("used hwm pgs alloc free\n");
- }
-
- type = typename(mp->type);
- name = memname(mp->type);
-
- mdb_printf("%16s %s %2x %9d %9d %6d %5d %5d\n",
- name, type, mp->flag, mp->used, mp->hwm, mp->pagehwm,
- mp->nalloc, mp->nfree);
-}
-
-
-static int
-nsc_mem_all(int argc, const mdb_arg_t *argv, int v_opt)
-{
- int first;
- int i;
-
- memset(type_mem, 0, sizeof (type_mem));
-
- if (mdb_walk_dcmd("nsctl`nsc_mem",
- "nsctl`nsc_mem", argc, argv) == -1) {
- mdb_warn("unable to walk 'nsc_mem'");
- return (DCMD_ERR);
- }
-
- for (first = 1, i = 0;
- i < (sizeof (type_mem) / sizeof (nsc_mem_t)); first = 0, i++) {
- if (type_mem[i].nalloc || type_mem[i].hwm) {
- nsc_mem_type(first, &type_mem[i]);
- }
- }
-
- if (v_opt)
- nsc_rmhdr();
-
- return (DCMD_OK);
-}
-
-
-static int
-nsc_mem(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- char name[16], *type, *cp;
- nsc_mem_t mem, *mp;
- int v_opt;
-
- v_opt = 0;
-
- if (mdb_getopts(argc, argv,
- 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc)
- return (DCMD_USAGE);
-
- if (!(flags & DCMD_ADDRSPEC)) {
- return (nsc_mem_all(argc, argv, v_opt));
- }
-
- if (mdb_vread(&mem, sizeof (mem), addr) != sizeof (mem)) {
- mdb_warn("failed to read nsc_mem_t at %p", addr);
- return (DCMD_ERR);
- }
-
- if (mdb_readstr(name, sizeof (name), (uintptr_t)mem.name) == -1) {
- mdb_warn("failed to read nsc_mem_t.name at %p", addr);
- return (DCMD_ERR);
- }
-
- if (!mem.nalloc && !mem.hwm && !v_opt)
- return (DCMD_OK);
-
- if (DCMD_HDRSPEC(flags)) {
- mdb_printf("name typ f ");
- mdb_printf("used hwm pgs alloc free base\n");
- }
-
- type = typename(mem.type);
- mp = memptr(mem.type, mem.flag);
-
- for (cp = name; *cp; cp++)
- if (*cp == ':')
- *cp = ' ';
-
- mdb_printf("%-16s %s %2x %9d %9d %5d %5d %5d %0?p\n",
- name, type, mem.flag, mem.used, mem.hwm, mem.pagehwm,
- mem.nalloc, mem.nfree, mem.base);
-
- mp->used += mem.used;
- mp->hwm += mem.hwm;
- mp->pagehwm += mem.pagehwm;
- mp->nalloc += mem.nalloc;
- mp->nfree += mem.nfree;
-
- return (DCMD_OK);
-}
-
-/*ARGSUSED*/
-static int
-nsc_vec(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- nsc_vec_t *vec;
-
- vec = mdb_zalloc(sizeof (*vec), UM_SLEEP | UM_GC);
- if (mdb_vread(vec, sizeof (*vec), addr) != sizeof (*vec)) {
- mdb_warn("failed to read nsc_vec at %p", addr);
- return (DCMD_ERR);
- }
- mdb_printf("nsc_vec_t @ 0x%p = {\n", addr);
- mdb_inc_indent(4);
- mdb_printf("sv_addr: %p\n", vec->sv_addr);
- mdb_printf("sv_vme: %lu\n", vec->sv_vme);
- mdb_printf("sv_len: %d\n", vec->sv_len);
- mdb_dec_indent(4);
- mdb_printf("};\n");
- if (vec->sv_addr)
- return (DCMD_OK);
- else
- return (DCMD_ERR);
-}
-
-/* ---------------------------------------------------------------------- */
-/*
- * Display an nsc_buf_t structure.
- */
-
-#ifdef NSC_MULTI_TERABYTE
-#define STRCONV "ll"
-#else
-#define STRCONV ""
-#endif
-
-/* ARGSUSED */
-static int
-nsc_buf(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- nsc_buf_t *bh;
- nsc_vec_t *v;
-
- if (!(flags & DCMD_ADDRSPEC))
- return (DCMD_USAGE);
-
- bh = mdb_zalloc(sizeof (*bh), UM_SLEEP | UM_GC);
-
- if (mdb_vread(bh, sizeof (*bh), addr) != sizeof (*bh)) {
- mdb_warn("failed to read nsc_buf at %p", addr);
- return (DCMD_ERR);
- }
-
- mdb_printf("nsc_buf_t @ 0x%p = {\n", addr);
- mdb_inc_indent(4);
- mdb_printf("sb_fd: 0x%p\n", bh->sb_fd);
- mdb_printf("sb_pos: 0x%" STRCONV "x\n", bh->sb_pos);
- mdb_printf("sb_len: 0x%" STRCONV "x\n", bh->sb_len);
- mdb_printf("sb_flag: 0x%08x <%b>\n", bh->sb_flag,
- bh->sb_flag, nsc_bhflag_bits);
- mdb_printf("sb_error: %d\n", bh->sb_error);
-#ifdef NSC_MULTI_TERABYTE
- mdb_printf("sb_user: 0x%p\n", bh->sb_user);
-#else
- mdb_printf("sb_user: 0x%x\n", bh->sb_user);
-#endif
- mdb_printf("sb_vec: 0x%p\n", bh->sb_vec);
- v = bh->sb_vec++;
- while (nsc_vec((uintptr_t)v, flags, argc, argv) == DCMD_OK)
- v++;
-
- mdb_dec_indent(4);
- mdb_printf("};\n");
-
- return (DCMD_OK);
-}
-
-/* ---------------------------------------------------------------------- */
-
-/* ARGSUSED */
-static int
-nsc_dbuf(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- nsc_dbuf_t *bh;
-
- if (!(flags & DCMD_ADDRSPEC))
- return (DCMD_USAGE);
-
- bh = mdb_zalloc(sizeof (*bh), UM_SLEEP | UM_GC);
-
- if (mdb_vread(bh, sizeof (*bh), addr) != sizeof (*bh)) {
- mdb_warn("failed to read nsc_dbuf at %p", addr);
- return (DCMD_ERR);
- }
-
- mdb_printf("nsc_dbuf_t @ 0x%p = {\n", addr);
- mdb_inc_indent(4);
- mdb_printf("db_disc: 0x%p\n", bh->db_disc);
- mdb_printf("db_addr: 0x%p\n", bh->db_addr);
- mdb_printf("db_next: 0x%p\n", bh->db_next);
- mdb_printf("db_maxfbas: 0x%d\n", bh->db_maxfbas);
-
-
- mdb_dec_indent(4);
- mdb_printf("};\n");
-
- return (DCMD_OK);
-}
-/* ---------------------------------------------------------------------- */
-
-/*
- * MDB module linkage information:
- */
-
-static const mdb_dcmd_t dcmds[] = {
-#if 0
- { "nsctl", NULL, "display nsctl module info", nsctl },
-#endif
- { "nsc_buf", ":", "list nsc_buf structure", nsc_buf },
- { "nsc_dbuf", ":", "list nsc_dbuf structure", nsc_dbuf },
- { "nsc_dev", "?[-av]", "list nsc_dev structure", nsc_dev },
- { "nsc_devval", "?[-a]", "list nsc_devval structure", nsc_devval },
- { "nsc_fd", "?[-v]", "list nsc_fd structure", nsc_fd },
- { "nsc_iodev", "?[-v]", "list nsc_iodev structure", nsc_iodev },
- { "nsc_io", "?[-v]", "list nsc_io structure", nsc_io },
- { "nsc_mem", "?[-v]", "list nsc_mem structure", nsc_mem },
- { "nsc_svc", ":", "list nsc_svc structure", nsc_svc },
- { "nsc_service", "?[-v]", "list nsc_service structure", nsc_service },
- { "nsc_val", ":", "list nsc_val structure", nsc_val },
- { "nstset", "?[-frtv]", "list nstset structure", nstset },
- { "nsthread", "?[-av]", "list nsthread structure", nsthread },
- { NULL }
-};
-
-
-static const mdb_walker_t walkers[] = {
- { "nsc_dev", "walk nsc_dev chain",
- nsc_dev_winit, nsc_dev_wstep, nsc_dev_wfini, NULL },
- { "nsc_devval", "walk nsc_devval chain",
- nsc_devval_winit, nsc_devval_wstep, NULL, NULL },
- { "nsc_fd", "walk nsc_fd chain",
- nsc_fd_winit, nsc_fd_wstep, NULL, NULL },
- { "nsc_io", "walk nsc_io chain",
- nsc_io_winit, nsc_io_wstep, NULL, NULL },
- { "nsc_iodev", "walk nsc_iodev chain",
- nsc_iodev_winit, nsc_iodev_wstep, NULL, NULL },
- { "nsc_mem", "walk nsc_mem chain",
- nsc_mem_winit, nsc_mem_wstep, NULL, NULL },
- { "nsc_service", "walk nsc_service chain",
- nsc_service_winit, nsc_service_wstep, NULL, NULL },
- { "nsc_svc", "walk nsc_svc chain",
- nsc_svc_winit, nsc_svc_wstep, NULL, NULL },
- { "nsc_val", "walk nsc_val chain",
- nsc_val_winit, nsc_val_wstep, NULL, NULL },
- { "nstset", "walk nstset chain",
- nstset_winit, nstset_wstep, NULL, NULL },
- { "nsthread", "walk nsthread chain",
- nsthread_winit, nsthread_wstep, NULL, NULL },
- { "nst_free", "walk nsthread free/reuse list",
- nst_free_winit, nst_free_wstep, NULL, NULL },
- { NULL }
-};
-
-
-static const mdb_modinfo_t modinfo = {
- MDB_API_VERSION, dcmds, walkers
-};
-
-
-const mdb_modinfo_t *
-_mdb_init(void)
-{
- return (&modinfo);
-}
diff --git a/usr/src/cmd/mdb/common/modules/rdc/Makefile.com b/usr/src/cmd/mdb/common/modules/rdc/Makefile.com
deleted file mode 100644
index 40975cea69..0000000000
--- a/usr/src/cmd/mdb/common/modules/rdc/Makefile.com
+++ /dev/null
@@ -1,24 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-CPPFLAGS += -DNSC_MULTI_TERABYTE
diff --git a/usr/src/cmd/mdb/common/modules/rdc/rdc.c b/usr/src/cmd/mdb/common/modules/rdc/rdc.c
deleted file mode 100644
index 48d8b28969..0000000000
--- a/usr/src/cmd/mdb/common/modules/rdc/rdc.c
+++ /dev/null
@@ -1,1563 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/mdb_modapi.h>
-
-#include <sys/nsctl/nsctl.h>
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_k.h>
-
-#include <rpc/auth.h>
-#include <rpc/auth_unix.h>
-#include <rpc/auth_des.h>
-#include <rpc/svc.h>
-#include <rpc/xdr.h>
-#include <rpc/svc_soc.h>
-
-/* HACK HACK so we can bring in rdc_io.h and friends */
-#define nstset_t char
-
-#include <sys/nsctl/rdc.h>
-#include <sys/nsctl/rdc_prot.h>
-#include <sys/nsctl/rdc_ioctl.h>
-#include <sys/nsctl/rdc_io.h>
-#include <sys/nsctl/rdc_bitmap.h>
-
-#include <sys/nsctl/nsvers.h>
-
-
-/*
- * Walker for an array of rdc_k_info_t structures.
- * A global walk is assumed to start at rdc_k_info.
- */
-
-struct rdc_kinfo_winfo {
- uintptr_t start;
- uintptr_t end;
-};
-
-char bitstr[33] = { '0' };
-
-static int
-rdc_k_info_winit(mdb_walk_state_t *wsp)
-{
- struct rdc_kinfo_winfo *winfo;
- rdc_k_info_t *rdc_k_info;
- int rdc_max_sets;
-
- winfo = mdb_zalloc(sizeof (struct rdc_kinfo_winfo), UM_SLEEP);
-
- if (mdb_readvar(&rdc_k_info, "rdc_k_info") == -1) {
- mdb_warn("failed to read 'rdc_k_info'");
- mdb_free(winfo, sizeof (struct rdc_kinfo_winfo));
- return (WALK_ERR);
- }
-
- if (mdb_readvar(&rdc_max_sets, "rdc_max_sets") == -1) {
- mdb_warn("failed to read 'rdc_max_sets'");
- mdb_free(winfo, sizeof (struct rdc_kinfo_winfo));
- return (WALK_ERR);
- }
-
- winfo->start = (uintptr_t)rdc_k_info;
- winfo->end = (uintptr_t)(rdc_k_info + rdc_max_sets);
-
- if (wsp->walk_addr == NULL)
- wsp->walk_addr = winfo->start;
-
- wsp->walk_data = winfo;
- return (WALK_NEXT);
-}
-
-
-static int
-rdc_k_info_wstep(mdb_walk_state_t *wsp)
-{
- struct rdc_kinfo_winfo *winfo = wsp->walk_data;
- int status;
-
- if (wsp->walk_addr == NULL)
- return (WALK_DONE);
-
- if (wsp->walk_addr >= winfo->end)
- return (WALK_DONE);
-
- status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
- wsp->walk_cbdata);
-
- wsp->walk_addr += sizeof (rdc_k_info_t);
- return (status);
-}
-
-
-static void
-rdc_k_info_wfini(mdb_walk_state_t *wsp)
-{
- mdb_free(wsp->walk_data, sizeof (struct rdc_kinfo_winfo));
-}
-
-/*
- * Walker for an array of rdc_u_info_t structures.
- * A global walk is assumed to start at rdc_u_info.
- */
-
-struct rdc_uinfo_winfo {
- uintptr_t start;
- uintptr_t end;
-};
-
-
-static int
-rdc_u_info_winit(mdb_walk_state_t *wsp)
-{
- struct rdc_uinfo_winfo *winfo;
- rdc_u_info_t *rdc_u_info;
- int rdc_max_sets;
-
- winfo = mdb_zalloc(sizeof (struct rdc_uinfo_winfo), UM_SLEEP);
-
- if (mdb_readvar(&rdc_u_info, "rdc_u_info") == -1) {
- mdb_warn("failed to read 'rdc_u_info'");
- mdb_free(winfo, sizeof (struct rdc_uinfo_winfo));
- return (WALK_ERR);
- }
-
- if (mdb_readvar(&rdc_max_sets, "rdc_max_sets") == -1) {
- mdb_warn("failed to read 'rdc_max_sets'");
- mdb_free(winfo, sizeof (struct rdc_uinfo_winfo));
- return (WALK_ERR);
- }
-
- winfo->start = (uintptr_t)rdc_u_info;
- winfo->end = (uintptr_t)(rdc_u_info + rdc_max_sets);
-
- if (wsp->walk_addr == NULL)
- wsp->walk_addr = winfo->start;
-
- wsp->walk_data = winfo;
- return (WALK_NEXT);
-}
-
-
-static int
-rdc_u_info_wstep(mdb_walk_state_t *wsp)
-{
- struct rdc_uinfo_winfo *winfo = wsp->walk_data;
- int status;
-
- if (wsp->walk_addr == NULL)
- return (WALK_DONE);
-
- if (wsp->walk_addr >= winfo->end)
- return (WALK_DONE);
-
- status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
- wsp->walk_cbdata);
-
- wsp->walk_addr += sizeof (rdc_u_info_t);
- return (status);
-}
-
-
-static void
-rdc_u_info_wfini(mdb_walk_state_t *wsp)
-{
- mdb_free(wsp->walk_data, sizeof (struct rdc_uinfo_winfo));
-}
-
-/*
- * Walker for the rdc_if chain.
- * A global walk is assumed to start at rdc_if_top.
- */
-
-static int
-rdc_if_winit(mdb_walk_state_t *wsp)
-{
- if (wsp->walk_addr == NULL &&
- mdb_readvar(&wsp->walk_addr, "rdc_if_top") == -1) {
- mdb_warn("unable to read 'rdc_if_top'");
- return (WALK_ERR);
- }
-
- wsp->walk_data = mdb_zalloc(sizeof (rdc_if_t), UM_SLEEP);
-
- return (WALK_NEXT);
-}
-
-
-static int
-rdc_if_wstep(mdb_walk_state_t *wsp)
-{
- int status;
-
- if (wsp->walk_addr == NULL)
- return (WALK_DONE);
-
- if (mdb_vread(wsp->walk_data,
- sizeof (rdc_if_t), wsp->walk_addr) == -1) {
- mdb_warn("failed to read rdc_if at %p", wsp->walk_addr);
- return (WALK_DONE);
- }
-
- status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
- wsp->walk_cbdata);
-
- wsp->walk_addr = (uintptr_t)(((rdc_if_t *)wsp->walk_data)->next);
- return (status);
-}
-
-
-static void
-rdc_if_wfini(mdb_walk_state_t *wsp)
-{
- mdb_free(wsp->walk_data, sizeof (rdc_if_t));
-}
-
-/*
- * Displays the asynchronous sleep q on the server.
- */
-/*ARGSUSED*/
-static int
-rdc_sleepq(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- rdc_sleepq_t sq;
-
- if (!(flags & DCMD_ADDRSPEC))
- return (DCMD_USAGE);
- while (addr) {
- if (mdb_vread(&sq, sizeof (sq), addr) != sizeof (sq)) {
- mdb_warn("failed to read rdc_sleepq at %p", addr);
- return (DCMD_ERR);
- }
- mdb_printf("sequence number %u qpos %d \n", sq.seq, sq.qpos);
- addr = (uintptr_t)sq.next;
- }
- return (DCMD_OK);
-}
-
-/*
- * display the header info for the pending diskq requests
- */
-/*ARGSUSED*/
-static int
-rdc_iohdr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- io_hdr hdr;
-
- if (!(flags & DCMD_ADDRSPEC))
- return (DCMD_USAGE);
-
- while (addr) {
- if (mdb_vread(&hdr, sizeof (io_hdr), addr) != sizeof (io_hdr)) {
- mdb_warn("failed to read io_hdr at %p", addr);
- return (DCMD_ERR);
- }
- mdb_printf("iohdr: type %d pos %d qpos %d len %d flag 0x%x"
- " iostatus %x setid %d next %p\n", hdr.dat.type, hdr.dat.pos,
- hdr.dat.qpos, hdr.dat.len, hdr.dat.flag, hdr.dat.iostatus,
- hdr.dat.setid, hdr.dat.next);
-
- addr = (uintptr_t)hdr.dat.next;
- }
- return (DCMD_OK);
-}
-
-/*
- * Display a krdc->group.
- * Requires an address.
- */
-/*ARGSUSED*/
-static int
-rdc_group(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- struct rdc_group *group;
- disk_queue *dq;
-
- if (!(flags & DCMD_ADDRSPEC))
- return (DCMD_USAGE);
-
-
- group = mdb_zalloc(sizeof (*group), UM_GC);
-
- if (mdb_vread(group, sizeof (*group), addr) != sizeof (*group)) {
- mdb_warn("failed to read rdc_group at %p", addr);
- return (DCMD_ERR);
- }
-#ifdef XXXJET
- if (DCMD_HDRSPEC(flags)) {
- mdb_printf("%-?s %8T%-8s %8T%s\n", "ADDR", "MAJOR", "INUSE");
- }
-#endif
- mdb_printf("count: %d %8Twriter: %d %8T flags: %d\n",
- group->count, group->rdc_writer, group->flags);
- mdb_printf("thread num %d\n", group->rdc_thrnum);
-
- dq = &group->diskq;
- if (RDC_IS_MEMQ(group)) {
- mdb_printf("queue type: Memory based\n");
- } else if (RDC_IS_DISKQ(group)) {
- mdb_printf("queue type: Disk based %8Tqstate 0x%x\n",
- QSTATE(dq));
- }
- mdb_printf("ra_queue head: 0x%p %8Ttail 0x%p\n",
- group->ra_queue.net_qhead, group->ra_queue.net_qtail);
- mdb_printf("ra_queue blocks: %d %8Titems %d\n",
- group->ra_queue.blocks, group->ra_queue.nitems);
- mdb_printf("ra_queue blockhwm: %d itemhwm: %d\n",
- group->ra_queue.blocks_hwm, group->ra_queue.nitems_hwm);
- mdb_printf("ra_queue hwmhit: %d qfillsleep: %d\n",
- group->ra_queue.hwmhit, group->ra_queue.qfill_sleeping);
- mdb_printf("ra_queue throttle: %ld\n",
- group->ra_queue.throttle_delay);
-
- if (RDC_IS_DISKQ(group)) {
- mdb_printf("head: %d %8Tnxtio: %d %8Ttail %d %8Tlastail: %d\n",
- QHEAD(dq), QNXTIO(dq), QTAIL(dq), LASTQTAIL(dq));
- mdb_printf("coalbounds: %d %8Tqwrap: %d\n", QCOALBOUNDS(dq),
- QWRAP(dq));
- mdb_printf("blocks: %d %8Titems %d qfflags 0x%x \n",
- QBLOCKS(dq), QNITEMS(dq), group->ra_queue.qfflags);
- mdb_printf("diskq throttle: %ld %8Tflags: %x\n",
- dq->throttle_delay, group->flags);
- mdb_printf("disk queue nitems_hwm: %d %8Tblocks_hwm: %d\n",
- dq->nitems_hwm, dq->blocks_hwm);
- mdb_printf("diskqfd: 0x%p %8Tdisqrsrv: %d lastio: 0x%p\n",
- group->diskqfd, group->diskqrsrv, dq->lastio);
- mdb_printf("outstanding req %d iohdrs 0x%p iohdrs_last 0x%p\n",
- dq->hdrcnt, dq->iohdrs, dq->hdr_last);
- }
- mdb_printf("seq: %u\n", group->seq);
- mdb_printf("seqack: %u\n", group->seqack);
- mdb_printf("sleepq: 0x%p\n", group->sleepq);
- mdb_printf("asyncstall %d\n", group->asyncstall);
- mdb_printf("asyncdis %d\n", group->asyncdis);
-
- mdb_inc_indent(4);
- if (group->sleepq) {
- rdc_sleepq((uintptr_t)group->sleepq, DCMD_ADDRSPEC,
- 0, 0);
- }
- mdb_dec_indent(4);
-
- return (DCMD_OK);
-}
-
-
-/*
- * Display a krdc->lsrv.
- * Requires an address.
- */
-/*ARGSUSED*/
-static int
-rdc_srv(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- rdc_srv_t *lsrv;
- char name[MAX_RDC_HOST_SIZE];
-
- if (!(flags & DCMD_ADDRSPEC))
- return (DCMD_USAGE);
-
-
- lsrv = mdb_zalloc(sizeof (*lsrv), UM_GC);
-
- if (mdb_vread(lsrv, sizeof (*lsrv), addr) != sizeof (*lsrv)) {
- mdb_warn("failed to read rdc_srv at %p", addr);
- return (DCMD_ERR);
- }
-
- if (mdb_readstr(name, sizeof (name),
- (uintptr_t)lsrv->ri_hostname) == -1) {
- mdb_warn("failed to read ri_hostname name at %p", addr);
- return (DCMD_ERR);
- }
-
- mdb_printf("host: %s %16Tri_knconf 0x%p\n", name, lsrv->ri_knconf);
-
- mdb_printf("ri_addr: 0x%p %8Tsecdata 0x%p\n",
- addr + OFFSETOF(rdc_srv_t, ri_addr), lsrv->ri_secdata);
-
- return (DCMD_OK);
-}
-
-/*
- * Display a rdc_if_t.
- * Requires an address.
- */
-static int
-rdc_if(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- rdc_if_t *ifp;
-
- if (!(flags & DCMD_ADDRSPEC)) {
- /*
- * paranoid mode on: qualify walker name with module name
- * using '`' syntax.
- */
- if (mdb_walk_dcmd("rdc`rdc_if",
- "rdc`rdc_if", argc, argv) == -1) {
- mdb_warn("failed to walk 'rdc_if'");
- return (DCMD_ERR);
- }
- return (DCMD_OK);
- }
-
- ifp = mdb_zalloc(sizeof (*ifp), UM_GC);
-
- if (mdb_vread(ifp, sizeof (*ifp), addr) != sizeof (*ifp)) {
- mdb_warn("failed to read rdc_srv at %p", addr);
- return (DCMD_ERR);
- }
-
- mdb_printf("next: 0x%p %8Tsrv 0x%p\n", ifp->next, ifp->srv);
- mdb_printf("if_addr: 0x%p %8Tr_ifaddr 0x%p\n",
- addr + OFFSETOF(rdc_if_t, ifaddr),
- addr + OFFSETOF(rdc_if_t, r_ifaddr));
- mdb_printf("if_down: %d %8Tprimary %d %8Tsecondary %d\n",
- ifp->if_down, ifp->isprimary, ifp->issecondary);
- mdb_printf("version %d %8Tnoping %d\n", ifp->rpc_version,
- ifp->no_ping);
- mdb_printf("\n");
-
- return (DCMD_OK);
-}
-
-
-/*
- * Display a rdc_buf_t
- * Requires an address.
- */
-/*ARGSUSED*/
-static int
-rdc_buf(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- rdc_buf_t *buf;
-
- if (!(flags & DCMD_ADDRSPEC))
- return (DCMD_USAGE);
-
-
- buf = mdb_zalloc(sizeof (*buf), UM_GC);
-
- if (mdb_vread(buf, sizeof (*buf), addr) != sizeof (*buf)) {
- mdb_warn("failed to read rdc_buf at %p", addr);
- return (DCMD_ERR);
- }
-
- mdb_printf("nsc_buf fd: 0x%p %8Tvec 0x%p\n",
- buf->rdc_bufh.sb_fd, buf->rdc_bufh.sb_vec);
-
- mdb_printf("nsc_buf pos: %d %8Tlen %d\n",
- buf->rdc_bufh.sb_pos, buf->rdc_bufh.sb_len);
-
- mdb_printf("nsc_buf flag: 0x%x %8Terror %d\n",
- buf->rdc_bufh.sb_flag, buf->rdc_bufh.sb_error);
-
- mdb_printf("anon_buf : 0x%p %8Tfd 0x%p %8Tbufp 0x%p\n",
- buf->rdc_anon, buf->rdc_fd, buf->rdc_bufp);
-
- mdb_printf("vsize: %d %8Tflags 0x%x\n",
- buf->rdc_vsize, buf->rdc_flags);
-
- return (DCMD_OK);
-}
-
-/*ARGSUSED*/
-static int
-rdc_aio(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- rdc_aio_t *aio;
-
- if (!(flags & DCMD_ADDRSPEC))
- return (DCMD_USAGE);
-
- aio = mdb_zalloc(sizeof (*aio), UM_GC);
-
- if (mdb_vread(aio, sizeof (*aio), addr) != sizeof (*aio)) {
- mdb_warn("failed to read rdc_aio at %p", addr);
- return (DCMD_ERR);
- }
- mdb_printf("rdc_aio next: %p %8T nsc_buf: %p %8T nsc_qbuf %p\n",
- aio->next, aio->handle, aio->qhandle);
- mdb_printf("pos: %d len: %d qpos: %d flag: %x iostatus: %d index: %d"
- " seq: %d\n", aio->pos, aio->len, aio->qpos, aio->flag,
- aio->iostatus, aio->index, aio->seq);
- return (DCMD_OK);
-}
-
-/*ARGSUSED*/
-static int
-rdc_dset(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- rdc_net_dataset_t *dset;
-
- if (!(flags & DCMD_ADDRSPEC))
- return (DCMD_USAGE);
-
- dset = mdb_zalloc(sizeof (*dset), UM_GC);
-
- if (mdb_vread(dset, sizeof (*dset), addr) != sizeof (*dset)) {
- mdb_warn("failed to read dset at %p", addr);
- return (DCMD_ERR);
- }
- mdb_printf("dset id: %d %8T dset inuse: %d %8T dset delpend: %d\n",
- dset->id, dset->inuse, dset->delpend);
- mdb_printf("dset items: %d %8T dset head %p %8T dset tail %p \n",
- dset->nitems, dset->head, dset->tail);
- mdb_printf("dset pos %d %8T dset len %d\n", dset->pos, dset->fbalen);
-
- return (DCMD_OK);
-}
-/*
- * Display a single rdc_k_info structure.
- * If called with no address, performs a global walk of all rdc_k_info.
- * -a : all (i.e. display all devices, even if disabled
- * -v : verbose
- */
-
-const mdb_bitmask_t sv_flag_bits[] = {
- { "NSC_DEVICE", NSC_DEVICE, NSC_DEVICE },
- { "NSC_CACHE", NSC_CACHE, NSC_CACHE },
- { NULL, 0, 0 }
-};
-
-static int
-rdc_kinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- rdc_k_info_t *krdc;
- rdc_u_info_t *rdc_u_info, *urdc;
- int a_opt, v_opt;
- int dev_t_chars;
-
- a_opt = v_opt = FALSE;
- dev_t_chars = sizeof (dev_t) * 2; /* # chars to display dev_t */
-
- if (mdb_getopts(argc, argv,
- 'a', MDB_OPT_SETBITS, TRUE, &a_opt,
- 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc)
- return (DCMD_USAGE);
-
- krdc = mdb_zalloc(sizeof (*krdc), UM_GC);
- urdc = mdb_zalloc(sizeof (*urdc), UM_GC);
-
- if (!(flags & DCMD_ADDRSPEC)) {
- /*
- * paranoid mode on: qualify walker name with module name
- * using '`' syntax.
- */
- if (mdb_walk_dcmd("rdc`rdc_kinfo",
- "rdc`rdc_kinfo", argc, argv) == -1) {
- mdb_warn("failed to walk 'rdc_kinfo'");
- return (DCMD_ERR);
- }
- return (DCMD_OK);
- }
- if (DCMD_HDRSPEC(flags)) {
- mdb_printf("%-?s %8T%-*s %8T%s\n", "ADDR",
- dev_t_chars, "TFLAG", "STATE");
- }
-
- if (mdb_vread(krdc, sizeof (*krdc), addr) != sizeof (*krdc)) {
- mdb_warn("failed to read rdc_k_info at %p", addr);
- return (DCMD_ERR);
- }
-
- if (mdb_readvar(&rdc_u_info, "rdc_u_info") == -1) {
- mdb_warn("failed to read 'rdc_u_info'");
- return (DCMD_ERR);
- }
-
- urdc = &rdc_u_info[krdc->index];
-
- if (!a_opt && ((krdc->type_flag & RDC_CONFIGURED) == 0))
- return (DCMD_OK);
-
- mdb_printf("%?p %8T%0*lx %8T", addr, dev_t_chars, krdc->type_flag);
-
-
- if (krdc->type_flag & RDC_DISABLEPEND)
- mdb_printf(" disable pending");
- if (krdc->type_flag & RDC_ASYNCMODE)
- mdb_printf(" async");
- if (krdc->type_flag & RDC_RESUMEPEND)
- mdb_printf(" resume pending");
- if (krdc->type_flag & RDC_BUSYWAIT)
- mdb_printf(" busywait");
-#ifdef RDC_SMALLIO
- if (krdc->type_flag & RDC_SMALLIO)
- mdb_printf(" smallio");
-#endif
-
- mdb_printf("\n");
-
- if (!v_opt)
- return (DCMD_OK);
-
- /*
- * verbose - print the rest of the structure as well.
- */
-
- mdb_inc_indent(4);
-
- mdb_printf("index: %d %8Trindex: %d %8Tbusyc: %d %8Tmaxfbas: %d\n",
- krdc->index, krdc->remote_index, krdc->busy_count, krdc->maxfbas);
-
- mdb_printf("info_dev: 0x%p %8Tiodev: 0x%p %8T %8T vers %d\n",
- krdc->devices, krdc->iodev, krdc->rpc_version);
-
- mdb_printf("iokstats: 0x%p\n", krdc->io_kstats);
- mdb_printf("group: 0x%p %8Tgroup_next: 0x%p\n",
- krdc->group, krdc->group_next);
- mdb_printf("group lock: 0x%p aux_state: %d\n",
- &krdc->group->lock, krdc->aux_state);
-
- mdb_inc_indent(4);
- if (krdc->type_flag & RDC_ASYNCMODE) {
- rdc_group((uintptr_t)krdc->group, DCMD_ADDRSPEC, 0, 0);
- }
- mdb_dec_indent(4);
-
- mdb_printf("servinfo: 0x%p %8Tintf: 0x%p\nbitmap: 0x%p %8T"
- "bitmap_ref: 0x%p\n",
- krdc->lsrv, krdc->intf, krdc->dcio_bitmap, krdc->bitmap_ref);
-
- mdb_printf("bmap_size: %d %8Tbmaprsrv: %d%8T bmap_write: %d\n",
- krdc->bitmap_size, krdc->bmaprsrv, krdc->bitmap_write);
-
- mdb_printf("bitmapfd: 0x%p %8Tremote_fd: 0x%p %8T\n", krdc->bitmapfd,
- krdc->remote_fd);
-
- mdb_printf("net_dataset: 0x%p %8Tdisk_status: %d %8T\n",
- krdc->net_dataset, krdc->disk_status);
-
- mdb_printf("many: 0x%p %8Tmulti: 0x%p %8T\n", krdc->many_next,
- krdc->multi_next);
-
- mdb_printf("rdc_uinfo: 0x%p\n\n", urdc);
- mdb_dec_indent(4);
- return (DCMD_OK);
-}
-
-
-static int
-rdc_uinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- rdc_u_info_t *urdc;
- rdc_k_info_t *rdc_k_info, *krdc, krdc1;
- rdc_group_t grp;
- disk_queue *dqp = NULL;
- int a_opt, v_opt;
- int dev_t_chars;
- int rdcflags;
-
- a_opt = v_opt = FALSE;
- dev_t_chars = sizeof (dev_t) * 2; /* # chars to display dev_t */
-
- if (mdb_getopts(argc, argv,
- 'a', MDB_OPT_SETBITS, TRUE, &a_opt,
- 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc)
- return (DCMD_USAGE);
-
- urdc = mdb_zalloc(sizeof (*urdc), UM_GC);
- krdc = mdb_zalloc(sizeof (*krdc), UM_GC);
-
- if (!(flags & DCMD_ADDRSPEC)) {
- /*
- * paranoid mode on: qualify walker name with module name
- * using '`' syntax.
- */
- if (mdb_walk_dcmd("rdc`rdc_uinfo",
- "rdc`rdc_uinfo", argc, argv) == -1) {
- mdb_warn("failed to walk 'rdc_uinfo'");
- return (DCMD_ERR);
- }
- return (DCMD_OK);
- }
- if (DCMD_HDRSPEC(flags)) {
- mdb_printf("%-?s %8T%-*s %8T%s\n", "ADDR",
- dev_t_chars, "FLAG", "STATE");
- }
-
- if (mdb_vread(urdc, sizeof (*urdc), addr) != sizeof (*urdc)) {
- mdb_warn("failed to read rdc_u_info at %p", addr);
- return (DCMD_ERR);
- }
-
- if (mdb_readvar(&rdc_k_info, "rdc_k_info") == -1) {
- mdb_warn("failed to read 'rdc_k_info'");
- return (DCMD_ERR);
- }
-
- krdc = &rdc_k_info[urdc->index];
-
- if (!a_opt && ((urdc->flags & RDC_ENABLED) == 0))
- return (DCMD_OK);
-
-
- if (mdb_vread(&krdc1, sizeof (krdc1),
- (uintptr_t)krdc) != sizeof (krdc1)) {
- mdb_warn("failed to read 'rdc_k_info1'");
- return (DCMD_ERR);
- }
-
- if (krdc1.group) {
- if (mdb_vread(&grp, sizeof (grp),
- (uintptr_t)krdc1.group) != sizeof (grp)) {
- mdb_warn("failed to read group info ");
- return (DCMD_ERR);
- }
- dqp = &grp.diskq;
- }
-
- rdcflags = (urdc->flags | urdc->sync_flags | urdc->bmap_flags);
- mdb_printf("%?p %8T%0*lx %8T", addr, dev_t_chars, rdcflags);
-
-
- if (rdcflags & RDC_PRIMARY)
- mdb_printf(" primary");
- if (rdcflags & RDC_SLAVE)
- mdb_printf(" slave");
- if (rdcflags & RDC_SYNCING)
- mdb_printf(" syncing");
- if (rdcflags & RDC_SYNC_NEEDED)
- mdb_printf(" sync_need");
- if (rdcflags & RDC_RSYNC_NEEDED)
- mdb_printf(" rsync_need");
- if (rdcflags & RDC_LOGGING)
- mdb_printf(" logging");
- if (rdcflags & RDC_QUEUING)
- mdb_printf(" queuing");
- if (rdcflags & RDC_DISKQ_FAILED)
- mdb_printf(" diskq failed");
- if (rdcflags & RDC_VOL_FAILED)
- mdb_printf(" vol failed");
- if (rdcflags & RDC_BMP_FAILED)
- mdb_printf(" bmp failed");
- if (rdcflags & RDC_ASYNC)
- mdb_printf(" async");
- if (rdcflags & RDC_CLR_AFTERSYNC)
- mdb_printf(" clr_bitmap_aftersync");
- if (dqp) {
- if (IS_QSTATE(dqp, RDC_QNOBLOCK))
- mdb_printf(" noblock");
- }
-#ifdef RDC_SMALLIO
- if (rdcflags & RDC_SMALLIO)
- mdb_printf(" smallio");
-#endif
-
- mdb_printf("\n");
-
- if (!v_opt)
- return (DCMD_OK);
-
- /*
- * verbose - print the rest of the structure as well.
- */
-
- mdb_inc_indent(4);
- mdb_printf("\n");
-
- mdb_printf("primary: %s %8Tfile: %s \nbitmap: %s ",
- urdc->primary.intf, urdc->primary.file, urdc->primary.bitmap);
- mdb_printf("netbuf: 0x%p\n", addr + OFFSETOF(rdc_set_t, primary));
- mdb_printf("secondary: %s %8Tfile: %s \nbitmap: %s ",
- urdc->secondary.intf, urdc->secondary.file, urdc->secondary.bitmap);
- mdb_printf("netbuf: 0x%p\n", addr + OFFSETOF(rdc_set_t, secondary));
-
- mdb_printf("sflags: %d %8Tbflags: %d%8T mflags: %d\n",
- urdc->sync_flags, urdc->bmap_flags, urdc->mflags);
- mdb_printf("index: %d %8Tsync_pos: %d%8T vsize: %d\n",
- urdc->index, urdc->sync_pos, urdc->volume_size);
- mdb_printf("setid: %d %8Tbits set: %d %8Tautosync: %d\n",
- urdc->setid, urdc->bits_set, urdc->autosync);
- mdb_printf("maxqfbas: %d %8Tmaxqitems: %d\n",
- urdc->maxqfbas, urdc->maxqitems);
- mdb_printf("netconfig: %p\n", urdc->netconfig);
- mdb_printf("group: %s %8TdirectIO: %s\n",
- urdc->group_name, urdc->direct_file);
- mdb_printf("diskqueue: %s ", urdc->disk_queue);
- if (dqp) {
- mdb_printf("diskqsize: %d\n", QSIZE(dqp));
- } else {
- mdb_printf("\n");
- }
- mdb_printf("rdc_k_info: 0x%p\n", krdc);
- mdb_printf("\n");
- mdb_dec_indent(4);
-
- mdb_printf("\n");
- return (DCMD_OK);
-}
-
-/*ARGSUSED*/
-static int
-rdc_infodev(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- rdc_info_dev_t *infodev;
- _rdc_info_dev_t *infp;
-
- if (!(flags & DCMD_ADDRSPEC))
- return (DCMD_USAGE);
-
- infodev = mdb_zalloc(sizeof (*infodev), UM_GC);
- infp = mdb_zalloc(sizeof (*infp), UM_GC);
-
- if (mdb_vread(infodev, sizeof (*infodev), addr) != sizeof (*infodev)) {
- mdb_warn("failed to read rdc_infodev at 0x%p\n", addr);
- return (DCMD_ERR);
- }
-
- infp = &infodev->id_cache_dev;
- mdb_inc_indent(4);
-
- mdb_printf("id_next: 0x%p\n", infodev->id_next);
- mdb_printf("id_cache_dev:\n");
-
- mdb_inc_indent(4);
- mdb_printf("bi_fd: 0x%p %8Tbi_iodev: 0x%p %8Tbi_krdc 0x%p\n",
- infp->bi_fd, infp->bi_iodev, infp->bi_krdc);
- mdb_printf("bi_rsrv: %d %8Tbi_orsrv: %d %8Tbi_failed: %d %8T\n"
- "bi_ofailed: %d %8Tbi_flag: %d\n", infp->bi_rsrv, infp->bi_orsrv,
- infp->bi_failed, infp->bi_ofailed, infp->bi_flag);
-
- infp = &infodev->id_raw_dev;
-
- mdb_dec_indent(4);
- mdb_printf("id_cache_dev:\n");
- mdb_inc_indent(4);
-
- mdb_printf("bi_fd: 0x%p %8Tbi_iodev: 0x%p %8Tbi_krdc 0x%p\n",
- infp->bi_fd, infp->bi_iodev, infp->bi_krdc);
- mdb_printf("bi_rsrv: %d %8Tbi_orsrv: %d %8Tbi_failed: %d %8T\n"
- "bi_ofailed: %d %8Tbi_flag: %d\n", infp->bi_rsrv, infp->bi_orsrv,
- infp->bi_failed, infp->bi_ofailed, infp->bi_flag);
-
- mdb_dec_indent(4);
-
- mdb_printf("id_sets: %d %8Tid_release: %d %8Tid_flag %d",
- infodev->id_sets, infodev->id_release, infodev->id_flag);
-
- if (infodev->id_flag & RDC_ID_CLOSING) {
- mdb_printf("closing");
- }
- mdb_printf("\n");
-
- mdb_dec_indent(4);
- return (DCMD_OK);
-}
-
-/*
- * Display general sv module information.
- */
-
-#define rdc_get_print(kvar, str, fmt, val) \
- if (mdb_readvar(&(val), #kvar) == -1) { \
- mdb_dec_indent(4); \
- mdb_warn("unable to read '" #kvar "'"); \
- return (DCMD_ERR); \
- } \
- mdb_printf("%-20s" fmt "\n", str ":", val)
-
-/*ARGSUSED*/
-static int
-rdc(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- int maj, min, mic, baseline, i;
-
- if (argc != 0)
- return (DCMD_USAGE);
-
- if (mdb_readvar(&maj, "sndr_major_rev") == -1) {
- mdb_warn("unable to read 'sndr_major_rev'");
- return (DCMD_ERR);
- }
-
- if (mdb_readvar(&min, "sndr_minor_rev") == -1) {
- mdb_warn("unable to read 'sndr_minor_rev'");
- return (DCMD_ERR);
- }
-
- if (mdb_readvar(&mic, "sndr_micro_rev") == -1) {
- mdb_warn("unable to read 'sndr_micro_rev'");
- return (DCMD_ERR);
- }
-
- if (mdb_readvar(&baseline, "sndr_baseline_rev") == -1) {
- mdb_warn("unable to read 'sndr_baseline_rev'");
- return (DCMD_ERR);
- }
-
- mdb_printf("Remote Mirror module version: kernel %d.%d.%d.%d; "
- "mdb %d.%d.%d.%d\n", maj, min, mic, baseline,
- ISS_VERSION_MAJ, ISS_VERSION_MIN, ISS_VERSION_MIC, ISS_VERSION_NUM);
- mdb_inc_indent(4);
-
- rdc_get_print(rdc_debug, "debug", "%d", i);
- rdc_get_print(rdc_bitmap_mode, "bitmap mode", "%d", i);
- rdc_get_print(rdc_max_sets, "max sndr devices", "%d", i);
- rdc_get_print(rdc_rpc_tmout, "client RPC timeout", "%d", i);
- rdc_get_print(rdc_health_thres, "health threshold", "%d", i);
- rdc_get_print(MAX_RDC_FBAS, "max trans fba", "%d", i);
-
- mdb_dec_indent(4);
- return (DCMD_OK);
-}
-
-static int
-rdc_k2u(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- rdc_k_info_t *krdc;
- rdc_u_info_t *rdc_u_info, *urdc;
- int rc;
-
- if (!(flags & DCMD_ADDRSPEC))
- return (DCMD_USAGE);
-
- krdc = mdb_zalloc(sizeof (*krdc), UM_GC);
- urdc = mdb_zalloc(sizeof (*urdc), UM_GC);
-
- if (mdb_vread(krdc, sizeof (*krdc), addr) != sizeof (*krdc)) {
- mdb_warn("failed to read krdc at %p", addr);
- return (DCMD_ERR);
- }
-
- if (mdb_readvar(&rdc_u_info, "rdc_u_info") == -1) {
- mdb_warn("failed to read 'rdc_u_info'");
- return (DCMD_ERR);
- }
-
- urdc = &rdc_u_info[krdc->index];
-
- rc = rdc_uinfo((uintptr_t)urdc, DCMD_ADDRSPEC, argc, argv);
- return (rc);
-}
-
-static int
-rdc_u2k(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- rdc_u_info_t *urdc;
- rdc_k_info_t *rdc_k_info, *krdc;
- int rc;
-
- if (!(flags & DCMD_ADDRSPEC))
- return (DCMD_USAGE);
-
- urdc = mdb_zalloc(sizeof (*urdc), UM_GC);
- krdc = mdb_zalloc(sizeof (*krdc), UM_GC);
-
- if (mdb_vread(urdc, sizeof (*urdc), addr) != sizeof (*urdc)) {
- mdb_warn("failed to read urdc at %p\n", addr);
- return (DCMD_ERR);
- }
-
- if (mdb_readvar(&rdc_k_info, "rdc_k_info") == -1) {
- mdb_warn("failed to read 'rdc_k_info'");
- return (DCMD_ERR);
- }
-
- krdc = &rdc_k_info[urdc->index];
-
- rc = rdc_kinfo((uintptr_t)krdc, DCMD_ADDRSPEC, argc, argv);
- return (rc);
-}
-
-#ifdef DEBUG
-/*
- * This routine is used to set the seq field in the rdc_kinfo->group
- * structure. Used to test that the queue code handles the integer
- * overflow correctly.
- * Takes two arguments index and value.
- * The index is the index into the kinfo structure array and
- * the value is the new value to set into the seq field.
- */
-/*ARGSUSED*/
-static int
-rdc_setseq(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- rdc_k_info_t *rdc_k_info;
- rdc_group_t *group;
- int index;
- uint_t val;
- uintptr_t pokeaddr;
-
- if (argc != 2) {
- mdb_warn("must have two arguments, index and value\n");
- return (DCMD_ERR);
- }
-
- index = (int)mdb_strtoull(argv[0].a_un.a_str);
- val = (uint_t)mdb_strtoull(argv[1].a_un.a_str);
-
- /*
- * Find out where in memory the seq field.
- * The structure offset first.
- */
-
- if (mdb_readvar(&rdc_k_info, "rdc_k_info") == -1) {
- mdb_warn("failed to read 'rdc_k_info'");
- return (DCMD_ERR);
- }
- pokeaddr = (uintptr_t)&rdc_k_info[index].group;
- if (mdb_vread(&group, sizeof (rdc_group_t *), pokeaddr) !=
- sizeof (rdc_group_t *)) {
- mdb_warn("failed to fetch the group structure for set %d\n",
- index);
- return (DCMD_ERR);
- }
- pokeaddr = (uintptr_t)(&group->seq);
- if (mdb_vwrite(&val, sizeof (val), pokeaddr) != sizeof (val)) {
- mdb_warn("failed to write seq at %p\n", pokeaddr);
- return (DCMD_ERR);
- }
-
- return (DCMD_OK);
-}
-
-
-/*
- * This routine is used to set the seqack field in the rdc_kinfo->group
- * structure. Used to test that the queue code handles the integer
- * overflow correctly.
- * Takes two arguments index and value.
- * The index is the index into the kinfo structure array and
- * the value is the new value to set into the seqack field.
- */
-/*ARGSUSED*/
-static int
-rdc_setseqack(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- rdc_k_info_t *rdc_k_info;
- rdc_group_t *group;
- int index;
- uint_t val;
- uintptr_t pokeaddr;
-
- if (argc != 2) {
- mdb_warn("must have two arguments, index and value\n");
- return (DCMD_ERR);
- }
-
- index = (int)mdb_strtoull(argv[0].a_un.a_str);
- val = (uint_t)mdb_strtoull(argv[1].a_un.a_str);
-
- /*
- * Find out where in memory the seqack field.
- * The structure offset first.
- */
-
- if (mdb_readvar(&rdc_k_info, "rdc_k_info") == -1) {
- mdb_warn("failed to read 'rdc_k_info'");
- return (DCMD_ERR);
- }
- pokeaddr = (uintptr_t)&rdc_k_info[index].group;
- if (mdb_vread(&group, sizeof (rdc_group_t *), pokeaddr) !=
- sizeof (rdc_group_t *)) {
- mdb_warn("failed to fetch the group structure for set %d\n",
- index);
- return (DCMD_ERR);
- }
- pokeaddr = (uintptr_t)(&group->seqack);
- if (mdb_vwrite(&val, sizeof (val), pokeaddr) != sizeof (val)) {
- mdb_warn("failed to write seqack at %p\n", pokeaddr);
- return (DCMD_ERR);
- }
-
- return (DCMD_OK);
-}
-
-/*
- * random define printing stuff, just does the define, and print the result
- */
-/*ARGSUSED*/
-static int
-fba_to_log_num(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- int num;
- if (argc < 1) {
- mdb_warn("must have an argument\n");
- return (DCMD_ERR);
- }
- num = (int)mdb_strtoull(argv[0].a_un.a_str);
- num = FBA_TO_LOG_NUM(num);
- mdb_printf("LOG NUM: %d (0x%x)", num, num);
-
- return (DCMD_OK);
-}
-
-/*ARGSUSED*/
-static int
-log_to_fba_num(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- int num;
- if (argc < 1) {
- mdb_warn("must have an argument\n");
- return (DCMD_ERR);
- }
- num = (int)mdb_strtoull(argv[0].a_un.a_str);
- num = LOG_TO_FBA_NUM(num);
- mdb_printf("LOG NUM: %d (0x%x)", num, num);
-
- return (DCMD_OK);
-}
-
-static int
-bmap_bit_isset(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- int st;
- int i, num;
- rdc_k_info_t *krdc;
- unsigned char *bmap;
- unsigned char *bmaddr;
- int bmsize;
-
- if (!(flags & DCMD_ADDRSPEC))
- return (DCMD_USAGE);
-
- if (argc < 1) {
- mdb_warn("must have an argument\n");
- return (DCMD_ERR);
- }
- krdc = mdb_zalloc(sizeof (*krdc), UM_GC);
-
- if (mdb_vread(krdc, sizeof (*krdc), addr) != sizeof (*krdc)) {
- mdb_warn("failed to read rdc_k_info at %p", addr);
- return (DCMD_ERR);
- }
-
- bmaddr = krdc->dcio_bitmap;
- bmsize = krdc->bitmap_size;
- bmap = mdb_zalloc(bmsize, UM_GC);
- if (mdb_vread(bmap, bmsize, (uintptr_t)bmaddr) != bmsize) {
- mdb_warn("failed to read bitmap");
- return (DCMD_ERR);
- }
-
- num = (int)mdb_strtoull(argv[0].a_un.a_str);
- st = FBA_TO_LOG_NUM(num);
- i = BMAP_BIT_ISSET(bmap, st);
- mdb_printf(" BIT (%d) for %x %s set (%02x)", st, num, i?"IS":"IS NOT",
- bmap[IND_BYTE(st)] & 0xff);
-
- return (DCMD_OK);
-}
-
-static int
-bmap_bitref_isset(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- int num, st, i;
- rdc_k_info_t *krdc;
- unsigned char *brefbyte;
- unsigned int *brefint;
- void *bradder;
- int brsize;
- size_t refcntsize = sizeof (unsigned char);
- struct bm_ref_ops *refops;
-
- if (!(flags & DCMD_ADDRSPEC))
- return (DCMD_USAGE);
-
- if (argc < 1) {
- mdb_warn("must have an argument\n");
- return (DCMD_ERR);
- }
-
- krdc = mdb_zalloc(sizeof (*krdc), UM_GC);
-
- if (mdb_vread(krdc, sizeof (*krdc), addr) != sizeof (*krdc)) {
- mdb_warn("failed to read rdc_k_info at %p", addr);
- return (DCMD_ERR);
- }
-
- bradder = krdc->bitmap_ref;
- refops = mdb_zalloc(sizeof (*refops), UM_GC);
- if (mdb_vread(refops, sizeof (*refops), (uintptr_t)krdc->bm_refs) !=
- sizeof (*refops)) {
- mdb_warn("failed to read bm_refops at %p", krdc->bm_refs);
- return (DCMD_ERR);
- }
- refcntsize = refops->bmap_ref_size;
- brsize = krdc->bitmap_size * BITS_IN_BYTE * refcntsize;
- if (refcntsize == sizeof (unsigned char)) {
- brefbyte = mdb_zalloc(brsize, UM_GC);
- if (mdb_vread(brefbyte, brsize, (uintptr_t)bradder) != brsize) {
- mdb_warn("failed to read bitmap");
- return (DCMD_ERR);
- }
- } else {
- brefint = mdb_zalloc(brsize, UM_GC);
- if (mdb_vread(brefint, brsize, (uintptr_t)bradder) != brsize) {
- mdb_warn("failed to read bitmap");
- return (DCMD_ERR);
- }
- }
-
- num = (int)mdb_strtoull(argv[0].a_un.a_str);
- st = FBA_TO_LOG_NUM(num);
- if (refcntsize == sizeof (unsigned char))
- i = brefbyte[st];
- else
- i = brefint[st];
-
- mdb_printf("BITREF (%d) for %x %s set (%02x)", st, num, i?"IS":"IS NOT",
- i);
-
- return (DCMD_OK);
-}
-
-/*ARGSUSED*/
-static int
-ind_byte(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- int num;
-
- if (argc < 1) {
- mdb_warn("must have an argument\n");
- return (DCMD_ERR);
- }
- num = FBA_TO_LOG_NUM((int)mdb_strtoull(argv[0].a_un.a_str));
- mdb_printf("IND_BYTE: %d", IND_BYTE(num));
-
- return (DCMD_OK);
-}
-
-/*ARGSUSED*/
-static int
-ind_bit(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- int num;
-
- if (argc < 1) {
- mdb_warn("must have an argument\n");
- return (DCMD_ERR);
- }
- num = FBA_TO_LOG_NUM((int)mdb_strtoull(argv[0].a_un.a_str));
- mdb_printf("IND_BIT: %d 0x%x", IND_BIT(num), IND_BIT(num));
-
- return (DCMD_OK);
-}
-
-static char *
-print_bit(uint_t bitmask)
-{
- int bitval = 1;
- int i;
-
- bitstr[32] = '\0';
-
- for (i = 31; i >= 0; i--) {
- if (bitmask & bitval) {
- bitstr[i] = '1';
- } else {
- bitstr[i] = '0';
- }
- bitval *= 2;
- }
- return (bitstr);
-}
-
-/*ARGSUSED*/
-static int
-rdc_bitmask(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- uint_t bitmask = 0;
- int first, st, en, pos, len;
-
- if (argc < 2) {
- mdb_warn("must have 2 args (pos, len)\n");
- return (DCMD_ERR);
- }
- pos = (int)mdb_strtoull(argv[0].a_un.a_str);
- len = (int)mdb_strtoull(argv[1].a_un.a_str);
-
- if (len <= 0) {
- mdb_printf("non positive len specified");
- return (DCMD_ERR);
- }
-
- if ((len - pos) > 2048) {
- mdb_printf("len out of range, 32 bit bitmask");
- return (DCMD_ERR);
- }
-
- first = st = FBA_TO_LOG_NUM(pos);
- en = FBA_TO_LOG_NUM(pos + len - 1);
- while (st <= en) {
- BMAP_BIT_SET((uchar_t *)&bitmask, st - first);
- st++;
- }
-
- mdb_printf("bitmask for POS: %d LEN: %d : 0x%08x (%s)", pos, len,
- bitmask & 0xffffffff, print_bit(bitmask));
- return (DCMD_OK);
-
-}
-
-/*
- * Dump the bitmap of the krdc structure indicated by the index
- * argument. Used by the ZatoIchi tests.
- */
-/*ARGSUSED*/
-static int
-rdc_bmapdump(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- rdc_k_info_t *rdc_k_info;
- int index;
- uintptr_t bmapaddr;
- uintptr_t bmapdata;
- unsigned char *data;
- int bmapsize;
- int i;
- int st = 0;
- int en = 0;
-
- if (argc < 1) {
- mdb_warn("must have index argument\n");
- return (DCMD_ERR);
- }
-
- i = argc;
- if (i == 3) {
- en = (int)mdb_strtoull(argv[2].a_un.a_str);
- en = FBA_TO_LOG_NUM(en);
- i--;
- }
- if (i == 2) {
- st = (int)mdb_strtoull(argv[1].a_un.a_str);
- st = FBA_TO_LOG_NUM(st);
- }
-
- index = (int)mdb_strtoull(argv[0].a_un.a_str);
- /*
- * Find out where in memory the rdc_k_kinfo array starts
- */
- if (mdb_readvar(&rdc_k_info, "rdc_k_info") == -1) {
- mdb_warn("failed to read 'rdc_k_info'");
- return (DCMD_ERR);
- }
- bmapaddr = (uintptr_t)(&rdc_k_info[index].bitmap_size);
- if (mdb_vread(&bmapsize, sizeof (bmapsize), bmapaddr)
- != sizeof (bmapsize)) {
- mdb_warn("failed to read dcio_bitmap at %p\n", bmapaddr);
- return (DCMD_ERR);
- }
-
- bmapaddr = (uintptr_t)(&rdc_k_info[index].dcio_bitmap);
- if (mdb_vread(&bmapdata, sizeof (bmapdata), bmapaddr)
- != sizeof (bmapdata)) {
- mdb_warn("failed to read dcio_bitmap at %p\n", bmapaddr);
- return (DCMD_ERR);
- }
- data = mdb_zalloc(bmapsize, UM_SLEEP);
-
- if (mdb_vread(data, bmapsize, bmapdata) != bmapsize) {
- mdb_warn("failed to read the bitmap data\n");
- mdb_free(data, bmapsize);
- return (DCMD_ERR);
- }
- mdb_printf("bitmap data address 0x%p bitmap size %d\n"
- "kinfo 0x%p\n", bmapdata, bmapsize, &rdc_k_info[index]);
-
- if ((st < 0) || ((st/8) > bmapsize) || (en < 0)) {
- mdb_warn("offset is out of range st %d bms %d en %d",
- st, bmapsize, en);
- return (DCMD_ERR);
- }
- if (((en/8) > bmapsize) || (en == 0))
- en = bmapsize * 8;
-
- mdb_printf("bit start pos: %d bit end pos: %d\n\n", st, en);
- st /= 8;
- en /= 8;
- for (i = st; i < en; i++) {
- mdb_printf("%02x ", data[i] & 0xff);
- if ((i % 16) == 15) {
- int s = LOG_TO_FBA_NUM((i-15)*8);
- int e = LOG_TO_FBA_NUM(((i+1)*8)) - 1;
- mdb_printf(" fbas: %x - %x\n", s, e);
- }
- }
- mdb_printf("\n");
- mdb_free(data, bmapsize);
- return (DCMD_OK);
-}
-
-/*
- * dump the bitmap reference count
- */
-/*ARGSUSED*/
-static int
-rdc_brefdump(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- rdc_k_info_t *rdc_k_info;
- int index;
- uintptr_t bmapaddr;
- uintptr_t bmapdata;
- unsigned char *data;
- int bmapsize;
- int i;
- int st = 0;
- int en = 0;
-
- if (argc < 1) {
- mdb_warn("must have index argument\n");
- return (DCMD_ERR);
- }
- index = (int)mdb_strtoull(argv[0].a_un.a_str);
-
- i = argc;
- if (i == 3) {
- en = (int)mdb_strtoull(argv[2].a_un.a_str);
- en = FBA_TO_LOG_NUM(en);
- i--;
-
- }
- if (i == 2) {
- st = (int)mdb_strtoull(argv[1].a_un.a_str);
- st = FBA_TO_LOG_NUM(st);
- }
-
- /*
- * Find out where in memory the rdc_k_kinfo array starts
- */
- if (mdb_readvar(&rdc_k_info, "rdc_k_info") == -1) {
- mdb_warn("failed to read 'rdc_k_info'");
- return (DCMD_ERR);
- }
- bmapaddr = (uintptr_t)(&rdc_k_info[index].bitmap_size);
-
- if (mdb_vread(&bmapsize, sizeof (bmapsize), bmapaddr)
- != sizeof (bmapsize)) {
- mdb_warn("failed to read dcio_bitmap at %p\n", bmapaddr);
- return (DCMD_ERR);
- }
-
- bmapsize *= 8;
- bmapaddr = (uintptr_t)(&rdc_k_info[index].bitmap_ref);
-
- if (mdb_vread(&bmapdata, sizeof (bmapdata), bmapaddr)
- != sizeof (bmapdata)) {
- mdb_warn("failed to read dcio_bitmap at %p\n", bmapaddr);
- return (DCMD_ERR);
- }
- data = mdb_zalloc(bmapsize, UM_SLEEP);
-
- if (mdb_vread(data, bmapsize, bmapdata) != bmapsize) {
- mdb_warn("failed to read the bitmap data\n");
- mdb_free(data, bmapsize);
- return (DCMD_ERR);
- }
- mdb_printf("bitmap data address 0x%p bitmap size %d\n"
- "kinfo 0x%p\n", bmapdata, bmapsize, &rdc_k_info[index]);
-
- if ((st < 0) || (st > bmapsize) || (en < 0)) {
- mdb_warn("offset is out of range");
- }
- if ((en > bmapsize) || (en == 0))
- en = bmapsize;
-
- mdb_printf("bit start pos: %d bit end pos: %d\n\n", st, en);
-
- for (i = st; i < en; i++) {
- mdb_printf("%02x ", data[i] & 0xff);
- if ((i % 16) == 15) {
- int s = LOG_TO_FBA_NUM(i-15);
- int e = LOG_TO_FBA_NUM(i+1) - 1;
- mdb_printf(" fbas: 0x%x - 0x%x \n", s, e);
- }
- }
- mdb_printf("\n");
- mdb_free(data, bmapsize);
- return (DCMD_OK);
-}
-
-static int
-rdc_bmapnref(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- mdb_printf("\nRDC bitmap info\n");
- rdc_bmapdump(addr, flags, argc, argv);
- mdb_printf("RDC bitmap reference count info\n");
- rdc_brefdump(addr, flags, argc, argv);
- return (DCMD_OK);
-}
-
-#endif
-/*
- * MDB module linkage information:
- */
-
-static const mdb_dcmd_t dcmds[] = {
- { "rdc", NULL, "display sndr module info", rdc },
- { "rdc_buf", "?[-v]", "rdc_buf structure", rdc_buf },
- { "rdc_kinfo", "?[-av]", "rdc_k_info structure", rdc_kinfo },
- { "rdc_uinfo", "?[-av]", "rdc_u_info structure", rdc_uinfo },
- { "rdc_group", "?", "rdc group structure", rdc_group },
- { "rdc_srv", "?", "rdc_srv structure", rdc_srv },
- { "rdc_if", "?", "rdc_if structure", rdc_if },
- { "rdc_infodev", "?", "rdc_info_dev structure", rdc_infodev },
- { "rdc_k2u", "?", "rdc_kinfo to rdc_uinfo", rdc_k2u },
- { "rdc_u2k", "?", "rdc_uinfo to rdc_kinfo", rdc_u2k },
- { "rdc_aio", "?", "rdc_aio structure", rdc_aio},
- { "rdc_iohdr", "?", "rdc_iohdr structure", rdc_iohdr},
-#ifdef DEBUG
- { "rdc_setseq", "?", "Write seq field in group", rdc_setseq },
- { "rdc_setseqack", "?", "Write seqack field in group", rdc_setseqack },
- { "rdc_dset", "?", "Dump dset info", rdc_dset },
- { "rdc_bmapdump", "?", "Dump bitmap", rdc_bmapdump },
- { "rdc_brefdump", "?", "Dump bitmap reference count", rdc_brefdump },
- { "rdc_bmapnref", "?", "Dump bitmap and ref count", rdc_bmapnref },
- { "rdc_fba2log", "?", "fba to log num", fba_to_log_num },
- { "rdc_log2fba", "?", "log to fba num", log_to_fba_num },
- { "rdc_bitisset", "?", "check bit set", bmap_bit_isset },
- { "rdc_brefisset", "?", "check bit ref set", bmap_bitref_isset },
- { "rdc_indbyte", "?", "print indbyte", ind_byte },
- { "rdc_indbit", "?", "print indbit", ind_bit },
- { "rdc_bitmask", "?", "print bitmask for pos->len", rdc_bitmask },
-#endif
- { NULL }
-};
-
-
-static const mdb_walker_t walkers[] = {
- { "rdc_kinfo", "walk the rdc_k_info array",
- rdc_k_info_winit, rdc_k_info_wstep, rdc_k_info_wfini },
- { "rdc_uinfo", "walk the rdc_u_info array",
- rdc_u_info_winit, rdc_u_info_wstep, rdc_u_info_wfini },
- { "rdc_if", "walk rdc_if chain",
- rdc_if_winit, rdc_if_wstep, rdc_if_wfini },
- { NULL }
-};
-
-
-static const mdb_modinfo_t modinfo = {
- MDB_API_VERSION, dcmds, walkers
-};
-
-
-const mdb_modinfo_t *
-_mdb_init(void)
-{
- return (&modinfo);
-}
diff --git a/usr/src/cmd/mdb/common/modules/sdbc/Makefile.com b/usr/src/cmd/mdb/common/modules/sdbc/Makefile.com
deleted file mode 100644
index 40975cea69..0000000000
--- a/usr/src/cmd/mdb/common/modules/sdbc/Makefile.com
+++ /dev/null
@@ -1,24 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-CPPFLAGS += -DNSC_MULTI_TERABYTE
diff --git a/usr/src/cmd/mdb/common/modules/sdbc/sdbc.c b/usr/src/cmd/mdb/common/modules/sdbc/sdbc.c
deleted file mode 100644
index 14c99abecf..0000000000
--- a/usr/src/cmd/mdb/common/modules/sdbc/sdbc.c
+++ /dev/null
@@ -1,3158 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/mdb_modapi.h>
-#include <sys/nsc_thread.h>
-
-/* needed to maintain identical _sd_bitmap_t sizes */
-#define _SD_8K_BLKSIZE
-#include <sys/nsctl/sd_bcache.h>
-
-#include <ns/sdbc/sd_io.h>
-#include <ns/sdbc/sd_ft.h>
-#include <ns/sdbc/safestore.h>
-
-/*
- * initialize cd filter options to this
- * to differentiate with kernel values in range [-1, sdbc_max_devs]
- */
-#define MDB_CD ((uintptr_t)~1)
-#define OPT_C_SELECTED (opt_c != MDB_CD)
-
-/* initialize block filters to this */
-#define MDB_BLKNUM ((uintptr_t)~1)
-#define OPT_B_SELECTED (opt_b != MDB_BLKNUM)
-
-enum vartype { UINTTYPE = 0, ADDRTYPE, LOCKTYPE, CVTYPE };
-
-static void display_var(char *, enum vartype);
-#ifdef SAFESTORE
-static void print_wrq(_sd_writeq_t *, uint_t);
-#endif
-
-struct walk_info {
- uintptr_t w_start;
- uintptr_t w_end;
-};
-
-
-mdb_bitmask_t host_states[] = {
- { "HOST_NONE", 0xff, _SD_HOST_NONE },
- { "HOST_CONFIGURED", 0xff, _SD_HOST_CONFIGURED },
- { "HOST_DECONFIGURED", 0xff, _SD_HOST_DECONFIGURED },
- { "HOST_NOCACHE", 0xff, _SD_HOST_NOCACHE },
- { NULL, 0, 0 }
-
-};
-
-mdb_bitmask_t cache_hints[] = {
- { "WRTHRU", NSC_WRTHRU, NSC_WRTHRU },
- { "FORCED_WRTHRU", NSC_FORCED_WRTHRU, NSC_FORCED_WRTHRU },
- { "NOCACHE", NSC_NOCACHE, NSC_NOCACHE },
- { "QUEUE", NSC_QUEUE, NSC_QUEUE },
- { "RDAHEAD", NSC_RDAHEAD, NSC_RDAHEAD },
- { "NO_FORCED_WRTHRU", NSC_NO_FORCED_WRTHRU, NSC_NO_FORCED_WRTHRU },
- { "METADATA", NSC_METADATA, NSC_METADATA },
- { "SEQ_IO", NSC_SEQ_IO, NSC_SEQ_IO },
- { NULL, 0, 0 }
-
-};
-
-
-/*
- * some cache general dcmds that do not use walkers
- */
-/*ARGSUSED*/
-static int
-sdbc_config(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- _sd_cache_param_t _sd_cache_config;
- _sd_net_t _sd_net_config;
- _sd_ft_info_t _sd_ft_data;
- uint_t _sd_node_hint;
- char sdbc_version[17];
-
- if (mdb_readvar(sdbc_version, "sdbc_version") == -1) {
- mdb_warn("failed to read sdbc_version symbol");
- } else {
- sdbc_version[16] = '\0'; /* make sure string is terminated */
- mdb_printf("sdbc_version %s\n", sdbc_version);
- }
-
- if (mdb_readvar(&_sd_cache_config, "_sd_cache_config") == -1) {
- mdb_warn("failed to read _sd_cache_config symbol");
- } else {
-
- mdb_printf("SDBC Configuration:\n");
- mdb_inc_indent(4);
- mdb_printf("user magic: %X kernel magic: %X (should match)\n",
- _SD_MAGIC, _sd_cache_config.magic);
- mdb_printf(
- "mirror host: %2d Block size: %4d threads %4d "
- "write cache: %4dM\n",
- _sd_cache_config.mirror_host,
- _sd_cache_config.blk_size,
- _sd_cache_config.threads,
- _sd_cache_config.write_cache);
- mdb_printf("num_handles %4-d cache_mem %4dM prot_lru %d\n",
- _sd_cache_config.num_handles,
- _sd_cache_config.cache_mem[0],
- _sd_cache_config.prot_lru);
- mdb_printf("gen_pattern %d fill_pattern %?-p num_nodes %d\n",
- _sd_cache_config.gen_pattern,
- _sd_cache_config.fill_pattern,
- _sd_cache_config.num_nodes);
- mdb_dec_indent(4);
- }
-
- if (mdb_readvar(&_sd_net_config, "_sd_net_config") == -1) {
- mdb_warn("failed to read _sd_net_config symbol");
- } else {
- mdb_inc_indent(4);
- mdb_printf(
- "psize %4-d configured %d csize %10-d wsize %10-d cpages %6d\n",
- _sd_net_config.sn_psize,
- _sd_net_config.sn_configured,
- _sd_net_config.sn_csize,
- _sd_net_config.sn_wsize,
- _sd_net_config.sn_cpages);
-
- mdb_dec_indent(4);
-#ifdef SAFESTORE
- print_wrq(&(_sd_net_config.sn_wr_queue), FALSE);
-#endif
- }
-
-
- if (mdb_readvar(&_sd_ft_data, "_sd_ft_data") == -1) {
- mdb_warn("failed to read _sd_ft_data symbol");
-
- } else {
- mdb_printf("FT data:\n");
- mdb_inc_indent(4);
- mdb_printf("crashed %d host_state <%b> numio %d\n",
- _sd_ft_data.fi_crashed,
- _sd_ft_data.fi_host_state, host_states,
- _sd_ft_data.fi_numio);
- mdb_printf("lock %?-p (owner) rem_sv %h-x sleep %?-p (owner)\n",
- _sd_ft_data.fi_lock._opaque[0],
- _sd_ft_data.fi_rem_sv._opaque,
- _sd_ft_data.fi_sleep._opaque[0]);
- mdb_dec_indent(4);
- }
-
- if (mdb_readvar(&_sd_node_hint, "_sd_node_hint") == -1) {
- mdb_warn("failed to read _sd_node_hint symbol");
-
- } else
- mdb_printf("Node Hints: %08x <%b>\n",
- _sd_node_hint, cache_hints);
-
- display_var("sdbc_wrthru_len", UINTTYPE);
- display_var("_sd_debug_level", UINTTYPE);
- display_var("_sdbc_attached", UINTTYPE);
-
- return (DCMD_OK);
-}
-
-static void
-sdbc_hit_percent(uint_t hits, uint_t misses, char *type)
-{
- uint64_t dhits, dmisses;
- uint64_t hit_rate = 0;
-
- mdb_printf("%s hits: %u\t %s misses: %u\n", type, hits, type, misses);
-
- /* a little crude. anything less than 1 percent will show as 0 */
- if (hits > 0 || misses > 0) {
- dhits = (uint64_t)hits;
- dmisses = (uint64_t)misses;
- hit_rate = (dhits * 100)/ (dhits + dmisses);
- mdb_printf("%s hit rate: %lld %%\n", type, hit_rate);
- }
- mdb_printf("\n");
-}
-
-/*ARGSUSED*/
-static int
-sdbc_stats(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- int i;
- char *fn;
- _sd_stats_t *_sd_cache_stats; /* local memory */
- uintptr_t _sd_cache_statsp; /* kernel pointer */
- _sd_shared_t *sh;
- int statssize;
- GElf_Sym sym;
- int maxdevs;
-
- if (argc != 0)
- return (DCMD_USAGE);
-
- /* get the number of volumes */
- if (mdb_readvar(&maxdevs, "sdbc_max_devs") == -1) {
- mdb_warn("failed to read sdbc_max_devs");
- return (DCMD_ERR);
- }
-
- statssize = sizeof (_sd_stats_t) + (maxdevs - 1) *
- sizeof (_sd_shared_t);
-
- _sd_cache_stats = mdb_zalloc(statssize, UM_SLEEP);
-
- if (mdb_lookup_by_obj("sdbc", "_sd_cache_stats", &sym) == -1) {
- mdb_warn("failed to lookup _sd_cache_stats symbol");
- return (DCMD_ERR);
- }
-
- if (mdb_vread(&_sd_cache_statsp, sizeof (uintptr_t),
- sym.st_value) == -1) {
- mdb_warn("failed to read _sd_stats_t pointer");
- return (DCMD_ERR);
- }
-
- if (mdb_vread(_sd_cache_stats, statssize, _sd_cache_statsp) == -1) {
- mdb_warn("failed to read _sd_stats_t structure");
- return (DCMD_ERR);
- }
-
- mdb_printf("Storage Device Block Cache Statistics\n");
- mdb_printf("-------------------------------------\n");
-
- i = _sd_cache_stats->st_blksize;
- mdb_printf("Blocksize: 0x%x (%d)\n", i, i);
-
- mdb_printf("\n");
- sdbc_hit_percent(_sd_cache_stats->st_rdhits, _sd_cache_stats->st_rdmiss,
- "Read");
- sdbc_hit_percent(_sd_cache_stats->st_wrhits, _sd_cache_stats->st_wrmiss,
- "Write");
-
- mdb_printf("%3s %10s %8s %8s %8s %8s %8s %7s %4s %4s %s\n",
- "Cd", "Dev", "Size",
- "CacheRd", "CacheWr", "DiskRd", "DiskWr",
- "DirtyBl", "#IO", "Fail", "F");
- for (i = 0; i < maxdevs; i++) {
- sh = &_sd_cache_stats->st_shared[i];
- if (!sh->sh_alloc)
- continue;
- fn = strrchr(sh->sh_filename, '/');
- fn = fn ? fn+1 : sh->sh_filename;
- mdb_printf("%3d %10s %7d %8d %8d %8d %8d %7d %4d %4d %d\n",
- sh->sh_cd, fn, sh->sh_filesize,
- sh->sh_cache_read, sh->sh_cache_write,
- sh->sh_disk_read, sh->sh_disk_write,
- sh->sh_numdirty, sh->sh_numio, sh->sh_numfail,
- sh->sh_failed);
- }
-
- mdb_free(_sd_cache_stats, statssize);
- return (DCMD_OK);
-}
-
-/*
- * display some variables and counters
- */
-static void
-display_var(char *name, enum vartype type)
-{
- uint_t uintval;
- uintptr_t addrval;
- kmutex_t lockval;
- kcondvar_t cvval;
-
- switch (type) {
- case UINTTYPE:
- if (mdb_readvar(&uintval, name) == -1) {
- mdb_warn("failed to read %s variable", name);
- } else
- mdb_printf("%s =\t%8x %12u\n",
- name, uintval, uintval);
- break;
- case ADDRTYPE:
- if (mdb_readvar(&addrval, name) == -1) {
- mdb_warn("failed to read %s variable", name);
- } else
- mdb_printf("%s =\t%?-p\n",
- name, addrval);
- break;
- case LOCKTYPE:
- if (mdb_readvar(&lockval, name) == -1) {
- mdb_warn("failed to read %s lock variable",
- name);
- } else
- mdb_printf("%s =\t%-p (owner)\n",
- name, lockval._opaque[0]);
- break;
- case CVTYPE:
- if (mdb_readvar(&cvval, name) == -1) {
- mdb_warn("failed to read %s condvar variable",
- name);
- } else
- mdb_printf("%s = \t%h-x\n",
- name, cvval._opaque);
- break;
- default:
- mdb_warn("display_var: unknown type");
- }
-}
-
-mdb_bitmask_t dealloc_flag_vals[] = {
- { "PROCESS_CACHE_DM", (u_longlong_t)~0, PROCESS_CACHE_DM },
- { "CACHE_SHUTDOWN_DM", (u_longlong_t)~0, CACHE_SHUTDOWN_DM },
- { "CACHE_THREAD_TERMINATED_DM",
- (u_longlong_t)~0, CACHE_THREAD_TERMINATED_DM },
- { "TIME_DELAY_LVL0", (u_longlong_t)~0, TIME_DELAY_LVL0 },
- { "TIME_DELAY_LVL1", (u_longlong_t)~0, TIME_DELAY_LVL1 },
- { "TIME_DELAY_LVL2", (u_longlong_t)~0, TIME_DELAY_LVL2 },
- { NULL, 0, 0 }
-};
-
-mdb_bitmask_t mdp_bits[] = {
- { "MONITOR_DYNMEM_PROCESS_DEFAULT",
- (u_longlong_t)~0, MONITOR_DYNMEM_PROCESS_DEFAULT},
- { "RPT_SHUTDOWN_PROCESS_DM",
- RPT_SHUTDOWN_PROCESS_DM, RPT_SHUTDOWN_PROCESS_DM },
- { "RPT_DEALLOC_STATS1_DM",
- RPT_DEALLOC_STATS1_DM, RPT_DEALLOC_STATS1_DM },
- { "RPT_DEALLOC_STATS2_DM",
- RPT_DEALLOC_STATS2_DM, RPT_DEALLOC_STATS2_DM },
- { NULL, 0, 0 }
-};
-
-mdb_bitmask_t process_directive_bits[] = {
- { "PROCESS_DIRECTIVE_DEFAULT",
- (u_longlong_t)~0, PROCESS_DIRECTIVE_DEFAULT },
- { "WAKE_DEALLOC_THREAD_DM",
- WAKE_DEALLOC_THREAD_DM, WAKE_DEALLOC_THREAD_DM },
- { "MAX_OUT_ACCEL_HIST_FLAG_DM",
- MAX_OUT_ACCEL_HIST_FLAG_DM, MAX_OUT_ACCEL_HIST_FLAG_DM},
- { NULL, 0, 0 }
-};
-
-/*ARGSUSED*/
-static int
-sdbc_vars(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- int sd_dealloc_flag_dm;
- _dm_process_vars_t dynmem_processing_dm;
-
- if (argc != 0)
- return (DCMD_USAGE);
-
- mdb_printf("counters and other variables:\n");
- mdb_inc_indent(4);
-
- display_var("xmem_inval_hit", UINTTYPE);
- display_var("xmem_inval_miss", UINTTYPE);
- display_var("xmem_inval_inuse", UINTTYPE);
-
- display_var("sdbc_allocb_pageio1", UINTTYPE);
- display_var("sdbc_allocb_pageio2", UINTTYPE);
- display_var("sdbc_allocb_inuse", UINTTYPE);
- display_var("sdbc_allocb_hit", UINTTYPE);
- display_var("sdbc_allocb_lost", UINTTYPE);
- display_var("sdbc_pageio_always", UINTTYPE);
- display_var("sdbc_do_page", UINTTYPE);
- display_var("sdbc_flush_pageio", UINTTYPE);
-
- display_var("sdbc_centry_hit", UINTTYPE);
- display_var("sdbc_centry_inuse", UINTTYPE);
- display_var("sdbc_centry_lost", UINTTYPE);
- display_var("sdbc_centry_deallocd", UINTTYPE);
-
- display_var("_sd_prefetch_opt", UINTTYPE);
-
- display_var("sdbc_ra_hash", UINTTYPE);
- display_var("sdbc_ra_none", UINTTYPE);
-
- display_var("sdbc_static_cache", UINTTYPE);
- display_var("sdbc_use_dmchain", UINTTYPE);
-
- /* in no particular order ... */
- display_var("sdbc_check_cot", UINTTYPE);
- display_var("_sd_cctl_groupsz", UINTTYPE);
- display_var("CBLOCKS", UINTTYPE);
- display_var("_SD_SELF_HOST", UINTTYPE);
- display_var("_SD_MIRROR_HOST", UINTTYPE);
- display_var("sdbc_bio_count", UINTTYPE);
- display_var("_sd_cblock_shift", UINTTYPE);
- display_var("_sd_nodes_configured", UINTTYPE);
- display_var("nv_alloc_factor", UINTTYPE);
- display_var("_sd_ft_exit", UINTTYPE);
- display_var("_sd_flush_exit", UINTTYPE);
- display_var("_sd_node_recovery", UINTTYPE);
- display_var("_sd_async_recovery", UINTTYPE);
- display_var("_sdbc_ft_hold_io", UINTTYPE);
- display_var("mirror_clean_shutdown", UINTTYPE);
- display_var("_sd_ft_warm_start", UINTTYPE);
- mdb_dec_indent(4);
- mdb_printf("\n");
-
- /* some addresses of various lists and tables */
- mdb_printf("Addresses:\n");
- mdb_inc_indent(4);
- display_var("_sd_htable", ADDRTYPE);
- display_var("_sdbc_gl_centry_info", ADDRTYPE);
- display_var("_sdbc_gl_centry_info_nvmem", ADDRTYPE);
- display_var("_sdbc_gl_centry_info_size", ADDRTYPE); /* size_t */
- display_var("_sdbc_gl_file_info", ADDRTYPE);
- display_var("_sdbc_gl_file_info_size", ADDRTYPE); /* size_t */
- mdb_dec_indent(4);
- mdb_printf("\n");
-
- /* dynamic memory variables */
- mdb_printf("Dynamic Memory variables and stats:\n");
- mdb_inc_indent(4);
- display_var("_sdbc_memtype_deconfigure_delayed", UINTTYPE);
-
- if (mdb_readvar(&sd_dealloc_flag_dm, "sd_dealloc_flag_dm") == -1) {
- mdb_warn("failed to read sd_dealloc_flag_dm symbol");
- } else
- mdb_printf("sd_dealloc_flag_dm %08x <%b>\n",
- sd_dealloc_flag_dm,
- sd_dealloc_flag_dm, dealloc_flag_vals);
-
- if (mdb_readvar(&dynmem_processing_dm, "dynmem_processing_dm") == -1) {
- mdb_warn("failed to read dynmem_processing_dm structure");
- } else {
- _dm_process_vars_t *dp;
-
- dp = &dynmem_processing_dm;
-
- mdb_printf(
- "thread_dm_cv %h-x thread_dm_lock %?-p (owner)\n",
- dp->thread_dm_cv._opaque,
- dp->thread_dm_lock._opaque[0]);
-
- mdb_printf("sd_dealloc_flagx %x %8Tmax_dyn_list %3-d\n",
- dp->sd_dealloc_flagx,
- dp->max_dyn_list);
-
- mdb_printf("monitor_dynmem_process <%b>\n",
- dp->monitor_dynmem_process, mdp_bits);
-
- mdb_printf(
- "cache_aging_ct1 %3-d %8Tcache_aging_ct2 %3-d cache_aging_ct3 %3-d\n",
- dp->cache_aging_ct1,
- dp->cache_aging_ct2,
- dp->cache_aging_ct3);
-
- mdb_printf(
- "cache_aging_sec1 %3-d %8Tcache_aging_sec2 %3-d"
- " cache_aging_sec3 %3-d\n",
- dp->cache_aging_sec1,
- dp->cache_aging_sec2,
- dp->cache_aging_sec3);
-
- mdb_printf("cache_aging_pcnt1 %3-d %8Tcache_aging_pcnt2 %3-d\n",
- dp->cache_aging_pcnt1,
- dp->cache_aging_pcnt2);
-
- mdb_printf(
- "max_holds_pcnt %3-d %8Talloc_ct %8-d dealloc_ct %8-d\n",
- dp->max_holds_pcnt,
- dp->alloc_ct,
- dp->dealloc_ct);
-
- mdb_printf(
- "history %4x %8Tnodatas %8-d notavail %8-d candidates %8-d\n",
- dp->history,
- dp->nodatas,
- dp->notavail,
- dp->candidates);
-
- mdb_printf(
- "deallocs %8-d %8Thosts %8-d pests %8-d metas %8-d\n",
- dp->deallocs,
- dp->hosts,
- dp->pests,
- dp->metas);
-
- mdb_printf("holds %8-d %8Tothers %8-d\n",
- dp->holds,
- dp->others);
-
- mdb_printf("process_directive <%b>\n",
- dp->process_directive, process_directive_bits);
-
- mdb_printf("read_hits %8-d %8Tread_misses %8-d\n",
- dp->read_hits,
- dp->read_misses);
-
- mdb_printf(
- "write_thru %8-d %8Twrite_hits %8-d write_misses %8-d\n",
- dp->write_hits,
- dp->write_misses,
- dp->write_thru);
-
- mdb_printf("prefetch_hits %8-d prefetch_misses %8-d\n",
- dp->prefetch_hits,
- dp->prefetch_misses);
- }
- mdb_dec_indent(4);
- mdb_printf("\n");
-
- /* some locks and condition variables */
- mdb_printf("Locks:\n");
- mdb_inc_indent(4);
- display_var("mutex_and_condvar_flag", UINTTYPE);
- display_var("_sd_cache_lock", LOCKTYPE);
- display_var("_sd_block_lk", LOCKTYPE);
- display_var("_sdbc_config_lock", LOCKTYPE);
- display_var("_sdbc_ft_hold_io_lk", LOCKTYPE);
- display_var("_sd_flush_cv", CVTYPE);
- display_var("_sdbc_ft_hold_io_cv", CVTYPE);
- mdb_dec_indent(4);
- mdb_printf("\n");
-
- return (DCMD_OK);
-}
-
-const mdb_bitmask_t nsc_buf_bits[] = {
- {"HALLOCATED", NSC_HALLOCATED, NSC_HALLOCATED},
- {"HACTIVE", NSC_HACTIVE, NSC_HACTIVE},
- {"RDBUF", NSC_RDBUF, NSC_RDBUF},
- {"WRBUF", NSC_WRBUF, NSC_WRBUF},
- {"NOBLOCK", NSC_NOBLOCK, NSC_NOBLOCK},
- {"WRTHRU", NSC_WRTHRU, NSC_WRTHRU},
- {"NOCACHE", NSC_NOCACHE, NSC_NOCACHE},
- {"BCOPY", NSC_BCOPY, NSC_BCOPY},
- {"PAGEIO", NSC_PAGEIO, NSC_PAGEIO},
- {"PINNABLE", NSC_PINNABLE, NSC_PINNABLE},
- {"FORCED_WRTHRU", NSC_FORCED_WRTHRU, NSC_FORCED_WRTHRU},
- {"METADATA", NSC_METADATA, NSC_METADATA},
- {"MIXED", NSC_MIXED, NSC_MIXED},
- {NULL, 0, 0}
-};
-
-
-/*
- * HELP functions for cache ctl type dcmds
- */
-
-static void
-cctl_help_common(char *name)
-{
- mdb_inc_indent(4);
- mdb_printf("-c cd displays cctls for cache descriptor 'cd'\n");
- mdb_dec_indent(4);
- mdb_printf("inclusive filters:\n");
- mdb_inc_indent(4);
- mdb_printf("-b blk displays cctls for cache block number 'blk'\n");
- mdb_printf("-d displays cctls with dirty bits\n");
- mdb_printf("-h displays cctls that are hashed\n");
- mdb_printf("-i displays cctls that are inuse\n");
- mdb_printf("-o displays cctls that have I/O in progress\n");
- mdb_printf("-p displays cctls that have pagio set\n");
- mdb_printf("-B displays cctls that are marked BAD\n");
- mdb_printf("-H displays cctls that are HOSTS\n");
- mdb_printf("-P displays cctls that are PARASITES\n");
- mdb_printf("-R displays cctls that are explicit (NSC_RDAHEAD) "
- "Prefetch bufs\n");
- mdb_printf("-r displays cctls that are implicit Prefetch bufs\n");
- mdb_printf("-V displays cctls that have valid bits set\n");
- mdb_printf("-v verbose\n");
- mdb_dec_indent(4);
-
- mdb_printf("Default: %s displays all cctls in the list\n", name);
- mdb_printf("\n");
-
- mdb_printf("Example:\n");
- mdb_inc_indent(4);
-
- mdb_printf("%s -io -c 5 displays all cctls for cd 5 that are\n"
- "in use or have I/O in progress\n", name);
- mdb_dec_indent(4);
-}
-
-#define CCTL_OPTIONSTRING "[-vdhiopBHPV][-c cd][-b blknum]"
-void
-cctl_help()
-{
- mdb_printf("sdbc_cctl displays cache ctl structures\n");
- mdb_printf("Usage: [address]::sdbc_cctl " CCTL_OPTIONSTRING "\n");
- cctl_help_common("sdbc_cctl");
-}
-
-void
-cchain_help()
-{
- mdb_printf("sdbc_cchain displays cache ctl structures in a"
- " (alloc) cc_chain\n");
- mdb_printf("Usage: address::sdbc_cchain " CCTL_OPTIONSTRING "\n");
- cctl_help_common("sdbc_cchain");
-}
-
-void
-dchain_help()
-{
- mdb_printf("sdbc_dchain displays cache ctl structures in a"
- " dirty chain\n");
- mdb_printf("Usage: address::sdbc_dchain " CCTL_OPTIONSTRING "\n");
- cctl_help_common("sdbc_dchain");
-}
-
-void
-dmchain_help()
-{
- mdb_printf("sdbc_dmchain displays cache ctl structures in a"
- " dynamic memory allocation chain\n");
- mdb_printf("order of display is:\n"
- "the cctl represented by the given address,\n"
- "the cc_head_dm cctl,\n"
- "the chain starting at cc_next_dm of the head cctl\n");
- mdb_printf("Usage: address::sdbc_dmchain " CCTL_OPTIONSTRING "\n");
- cctl_help_common("sdbc_dmchain");
-}
-
-void
-hashchain_help()
-{
- mdb_printf("sdbc_hashchain displays cache ctl structures in a"
- " hash chain\n");
- mdb_printf("Usage: address::sdbc_hashchain " CCTL_OPTIONSTRING "\n");
- cctl_help_common("sdbc_hashchain");
-}
-
-void
-hashtable_help()
-{
- mdb_printf("sdbc_hashtable displays the hash table and its chains\n");
- mdb_printf("Usage: address::sdbc_hashtable " CCTL_OPTIONSTRING "\n");
- cctl_help_common("sdbc_hashtable");
-}
-
-
-void
-lru_help()
-{
- mdb_printf("sdbc_lru displays cache ctl structures in the LRU queue\n");
- mdb_printf("Usage: [address]::sdbc_lru " CCTL_OPTIONSTRING "\n");
- cctl_help_common("sdbc_lru");
-}
-
-/*
- * help functions for write ctl dcmds
- */
-void
-wctl_help_common(char *name)
-{
- mdb_inc_indent(4);
- mdb_printf("-v verbose\n");
- mdb_printf("-c cd show ctl structs for cache descriptor 'cd'\n");
- mdb_printf("-d show ctl structs that have dirty bits set\n");
- mdb_dec_indent(4);
- mdb_printf("Default: %s displays all write ctl in the list\n", name);
-}
-
-void
-wctl_help()
-{
- mdb_printf(
- "sdbc_wctl displays the allocated array of write ctl structures\n");
- mdb_printf("Usage: [address]::sdbc_wctl [-vd][-c cd]\n");
- wctl_help_common("sdbc_wctl");
-}
-
-void
-wrq_help()
-{
- mdb_printf("sdbc_wrq displays the write ctl queue (wctl free list)\n");
- mdb_printf("Usage: [address]::sdbc_wrq [-vd][-c cd]\n");
- wctl_help_common("sdbc_wrq");
-}
-
-/* help function for the sdbc_cdinfo dcmd */
-void
-cdinfo_help()
-{
- mdb_printf(
- "sdbc_cdinfo displays cd information from the _sd_cache_files table\n");
- mdb_printf("Usage: [address]::sdbc_cdfinfo [-av][-c cd]\n");
- mdb_inc_indent(4);
- mdb_printf("-a displays info for all cd_info structures\n");
- mdb_printf("-c cd displays info for cache descriptor 'cd'\n");
- mdb_printf("-v verbose\n");
- mdb_dec_indent(4);
- mdb_printf("Default: display info for cd's that are allocated\n");
-}
-
-void
-ftctl_help()
-{
- mdb_printf(
- "sdbc_ftctl displays the array of fault tolerant structures \n");
- mdb_printf("Usage: [address]::sdbc_ftctl [-vd][-c cd]\n");
- wctl_help_common("sdbc_ftctl");
-}
-
-/*
- * help function for the sdbc_handles dcmd
- */
-void
-handle_help()
-{
- mdb_printf("sdbc_handles displays active or allocated"
- " cache buffer handles\n");
- mdb_printf("Usage: [address]::sdbc_handles [-avC][-c cd]\n");
- mdb_inc_indent(4);
- mdb_printf("-a displays all handles\n");
- mdb_printf("-c n displays handle for cd n\n");
- mdb_printf("-v displays detailed handle data\n");
- mdb_printf("-C displays the handle cc_chain\n");
- mdb_dec_indent(4);
- mdb_printf("Default: display only allocated or active handles\n");
-}
-
-/*
- * help functions for the "global" memory dcmds
- */
-void
-glcinfo_help()
-{
- mdb_printf("sdbc_glcinfo displays the global cache entry info\n");
- mdb_printf("Usage: [address]::sdbc_glcinfo [-adC][-c cd][-b fbapos]\n");
- mdb_inc_indent(4);
- mdb_printf("-a displays all global info structs\n");
- mdb_printf("-b fbapos displays structs that match FBA block"
- "(not cache block) 'fbapos'\n");
- mdb_printf("-c cd displays structs that match cache descriptor 'cd'\n");
- mdb_printf("-d displays structs with dirty bits set\n");
- mdb_printf("-C does consistency check against nvram copy\n");
- mdb_dec_indent(4);
- mdb_printf("Default: display entries with a valid cd\n");
-}
-
-void
-glfinfo_help()
-{
- mdb_printf("sdbc_glfinfo displays the global file info\n");
- mdb_printf("Usage: [address]::sdbc_glfinfo [-aptC]\n");
- mdb_inc_indent(4);
- mdb_printf("-a displays all global info structs\n");
- mdb_printf("-p displays structs for pinned volumes\n");
- mdb_printf("-t displays structs for attached volumes\n");
- mdb_printf("-C does consistency check against nvram copy\n");
- mdb_dec_indent(4);
- mdb_printf("Default: display entries with non-null filename\n");
-}
-
-
-/*
- * WALKERS
- */
-
-/*
- * walker for the cctl list using the cc_link_list_dm pointers
- */
-static int
-sdbc_cctl_winit(mdb_walk_state_t *wsp)
-{
- _sd_cctl_t *_sd_cctl[_SD_CCTL_GROUPS]; /* for getting first entry */
- struct walk_info *winfo;
-
- winfo = mdb_zalloc(sizeof (struct walk_info), UM_SLEEP);
-
- if (wsp->walk_addr == NULL) {
- /*
- * we get the "first" cctl from memory and then traverse
- * the cc_link_list_dm pointers.
- * this traversal could start from any cctl. here we start with
- * the first cctl in the _sd_cctl[] array.
- */
- if (mdb_readvar(_sd_cctl, "_sd_cctl") == -1) {
- mdb_warn("failed to read _sd_cctl array");
- return (DCMD_ERR);
- }
-
- wsp->walk_addr = (uintptr_t)_sd_cctl[0];
- }
-
- winfo->w_start = 0;
- winfo->w_end = wsp->walk_addr;
- wsp->walk_data = winfo;
-
- return (WALK_NEXT);
-}
-
-static int
-sdbc_cctl_wstep(mdb_walk_state_t *wsp)
-{
- struct walk_info *winfo = wsp->walk_data;
- _sd_cctl_t centry;
- int status;
-
- if (wsp->walk_addr == NULL) /* should not happen */
- return (WALK_DONE);
-
- /*
- * w_start is 0 on the first iteration so the test
- * will fail, allowing the first centry to be processed
- */
- if (wsp->walk_addr == winfo->w_start)
- return (WALK_DONE);
-
- status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
- wsp->walk_cbdata);
-
- if (mdb_vread(&centry, sizeof (_sd_cctl_t), wsp->walk_addr) == -1) {
- mdb_warn("failed to read centry at %p", wsp->walk_addr);
- return (WALK_ERR);
- }
- wsp->walk_addr = (uintptr_t)(centry.cc_link_list_dm);
- /* set termination condition. only needs to be done once */
- winfo->w_start = winfo->w_end;
-
- return (status);
-}
-
-static void
-sdbc_cctl_wfini(mdb_walk_state_t *wsp)
-{
- mdb_free(wsp->walk_data, sizeof (struct walk_info));
-}
-
-/*
- * walk the cc_chain list of a _sd_cctl_t
- * no global walks -- must be called with an address
- */
-static int
-sdbc_cchain_winit(mdb_walk_state_t *wsp)
-{
- if (wsp->walk_addr == NULL)
- return (WALK_ERR);
-
- wsp->walk_data = mdb_zalloc(sizeof (_sd_cctl_t), UM_SLEEP);
-
- return (WALK_NEXT);
-}
-
-static int
-sdbc_cchain_wstep(mdb_walk_state_t *wsp)
-{
- int status;
-
- if (wsp->walk_addr == NULL)
- return (WALK_DONE);
-
- if (mdb_vread(wsp->walk_data, sizeof (_sd_cctl_t), wsp->walk_addr)
- == -1) {
- mdb_warn("sdbc_cchain_wstep failed to read centry at %p",
- wsp->walk_addr);
- return (WALK_ERR);
- }
-
- status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
- wsp->walk_cbdata);
-
- wsp->walk_addr = (uintptr_t)(((_sd_cctl_t *)
- (wsp->walk_data))->cc_chain);
- return (status);
-}
-
-static void
-sdbc_cchain_wfini(mdb_walk_state_t *wsp)
-{
- mdb_free(wsp->walk_data, sizeof (_sd_cctl_t));
-}
-
-
-/*
- * walk the dirty chain list of a _sd_cctl_t
- * no global walks -- must be called with an address
- */
-static int
-sdbc_dchain_winit(mdb_walk_state_t *wsp)
-{
- if (wsp->walk_addr == NULL)
- return (WALK_ERR);
-
- wsp->walk_data = mdb_zalloc(sizeof (_sd_cctl_t), UM_SLEEP);
-
- /* walk data stores the first and subsequent cc_dirty_link */
- if (mdb_vread(wsp->walk_data, sizeof (_sd_cctl_t), wsp->walk_addr)
- == -1) {
- mdb_warn("sdbc_dchain_winit failed to read centry at %p",
- wsp->walk_addr);
- return (WALK_ERR);
- }
-
- return (WALK_NEXT);
-}
-
-static int
-sdbc_dchain_wstep(mdb_walk_state_t *wsp)
-{
- _sd_cctl_t centry;
- int status;
-
- if (wsp->walk_addr == NULL)
- return (WALK_DONE);
-
- status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
- wsp->walk_cbdata);
-
-
- if (mdb_vread(&centry, sizeof (_sd_cctl_t), wsp->walk_addr)
- == -1) {
- mdb_warn("sdbc_dchain_wstep failed to read centry at %p",
- wsp->walk_addr);
- return (WALK_ERR);
- }
-
- wsp->walk_addr =
- (uintptr_t)(centry.cc_dirty_next);
-
- /* end of dirty_next chain? start on subsequent dirty_link */
- if (wsp->walk_addr == NULL) {
- wsp->walk_addr =
- (uintptr_t)(((_sd_cctl_t *)(wsp->walk_data))->cc_dirty_link);
-
- /* update dirty link */
- /* walk data stores the first and subsequent cc_dirty_link */
- if (wsp->walk_addr) {
- if (mdb_vread(wsp->walk_data, sizeof (_sd_cctl_t),
- wsp->walk_addr) == -1) {
-
- mdb_warn(
- "sdbc_dchain_wstep failed to read centry at %p",
- wsp->walk_addr);
-
- return (WALK_ERR);
- }
- }
- }
-
- return (status);
-}
-
-static void
-sdbc_dchain_wfini(mdb_walk_state_t *wsp)
-{
- mdb_free(wsp->walk_data, sizeof (_sd_cctl_t));
-}
-
-/* for stepping thru the dynmem chain */
-#define GET_HEAD_DM 0x1
-#define GET_NEXT_DM 0x2
-
-/*
- * walk the dm chain of a cctl
- * start with current address, then cc_head_dm, then the cc_next_dm chain
- */
-static int
-sdbc_dmchain_winit(mdb_walk_state_t *wsp)
-{
- if (wsp->walk_addr == NULL)
- return (WALK_ERR);
-
- wsp->walk_data = (void *)GET_HEAD_DM;
-
- return (WALK_NEXT);
-}
-
-static int
-sdbc_dmchain_wstep(mdb_walk_state_t *wsp)
-{
- _sd_cctl_t centry;
- int status;
-
- if (wsp->walk_addr == NULL)
- return (WALK_DONE);
-
- if (mdb_vread(&centry, sizeof (_sd_cctl_t), wsp->walk_addr)
- == -1) {
- mdb_warn("sdbc_dmchain_wstep failed to read centry at %p",
- wsp->walk_addr);
- return (WALK_ERR);
- }
-
- status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
- wsp->walk_cbdata);
-
- if (wsp->walk_data == (void *)GET_HEAD_DM) {
- wsp->walk_addr = (uintptr_t)centry.cc_head_dm;
- wsp->walk_data = (void *)GET_NEXT_DM;
- } else
- wsp->walk_addr = (uintptr_t)centry.cc_next_dm;
-
- return (status);
-}
-
-/*ARGSUSED*/
-static void
-sdbc_dmchain_wfini(mdb_walk_state_t *wsp)
-{
-}
-
-/*
- * walk a hash chain
- * requires an address
- */
-/*ARGSUSED*/
-static int
-sdbc_hashchain_winit(mdb_walk_state_t *wsp)
-{
-
- if (wsp->walk_addr == NULL)
- return (WALK_ERR);
-
-
- return (WALK_NEXT);
-}
-
-static int
-sdbc_hashchain_wstep(mdb_walk_state_t *wsp)
-{
- int status;
- _sd_hash_hd_t hash_entry;
-
-
- if (wsp->walk_addr == NULL)
- return (WALK_DONE);
-
- status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
- wsp->walk_cbdata);
-
- if (mdb_vread(&hash_entry, sizeof (_sd_hash_hd_t),
- wsp->walk_addr) == -1) {
- mdb_warn(
- "sdbc_hashchain_wstep failed to read hash_entry at %p",
- wsp->walk_addr);
- return (WALK_ERR); /* will upper layer continue ? */
- }
-
- wsp->walk_addr = (uintptr_t)hash_entry.hh_next;
-
- return (status);
-}
-
-/*ARGSUSED*/
-static void
-sdbc_hashchain_wfini(mdb_walk_state_t *wsp)
-{
-}
-
-/*
- * walk the sdbc lru list
- */
-static int
-sdbc_lru_winit(mdb_walk_state_t *wsp)
-{
- struct walk_info *winfo;
- GElf_Sym sym;
-
- winfo = mdb_zalloc(sizeof (struct walk_info), UM_SLEEP);
-
- /* if called without an address, start at the head of the queue */
- if (wsp->walk_addr == NULL) {
-
- if (mdb_lookup_by_obj("sdbc", "_sd_lru_q", &sym) == -1) {
- mdb_warn("failed to lookup _sd_lru_q symbol");
- return (WALK_ERR);
- }
-
- /* &(_sd_lru_q.sq_qhead) */
- wsp->walk_addr = (uintptr_t)(sym.st_value);
- }
-
- winfo->w_start = 0;
- winfo->w_end = wsp->walk_addr;
- wsp->walk_data = winfo;
-
- return (WALK_NEXT);
-}
-
-static int
-sdbc_lru_wstep(mdb_walk_state_t *wsp)
-{
- struct walk_info *winfo = wsp->walk_data;
- _sd_cctl_t centry;
- int status;
-
- if (wsp->walk_addr == NULL) /* should not happen */
- return (WALK_DONE);
-
- /*
- * w_start is 0 on the first iteration so the test
- * will fail, allowing the first centry to be processed
- */
- if (wsp->walk_addr == winfo->w_start)
- return (WALK_DONE);
-
- status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
- wsp->walk_cbdata);
-
- if (mdb_vread(&centry, sizeof (_sd_cctl_t), wsp->walk_addr) == -1) {
- mdb_warn("failed to read centry at %p", wsp->walk_addr);
- return (WALK_ERR);
- }
- wsp->walk_addr = (uintptr_t)(centry.cc_next);
-
- /* set termination condition. only needs to be done once */
- winfo->w_start = winfo->w_end;
-
- return (status);
-}
-
-static void
-sdbc_lru_wfini(mdb_walk_state_t *wsp)
-{
- mdb_free(wsp->walk_data, sizeof (struct walk_info));
-}
-
-
-#ifdef SAFESTORE
-/*
- * walk the array of allocated write control structures
- */
-
-static int
-sdbc_wctl_winit(mdb_walk_state_t *wsp)
-{
- _sd_net_t _sd_net_config;
- _sd_writeq_t wrq;
- struct walk_info *winfo;
- int blk_shft;
- int count;
-
-
- winfo = mdb_zalloc(sizeof (struct walk_info), UM_SLEEP);
-
- /* need to calculate the end of the array */
- if (mdb_readvar(&_sd_net_config, "_sd_net_config") == -1) {
- mdb_warn("failed to read _sd_net_config structure");
- return (WALK_ERR);
- }
-
- if (wsp->walk_addr == NULL)
- wsp->walk_addr = (uintptr_t)(_sd_net_config.sn_wr_cctl);
-
- /*
- * this module assumes 8k block size so this code can
- * be commented out if necessary.
- */
- if (mdb_readvar(&blk_shft, "_sd_cblock_shift") == -1) {
- mdb_warn("failed to read _sd_cblock_shift."
- "assuming 8k cache block size");
- blk_shft = 13;
- }
-
- count = (_sd_net_config.sn_wpages * _sd_net_config.sn_psize) /
- (1 << blk_shft);
-
- winfo->w_end = (uintptr_t)(_sd_net_config.sn_wr_cctl + count);
- wsp->walk_data = winfo;
-
- return (WALK_NEXT);
-}
-
-static int
-sdbc_wctl_wstep(mdb_walk_state_t *wsp)
-{
- struct walk_info *winfo = wsp->walk_data;
- int status;
-
- if (wsp->walk_addr == NULL)
- return (WALK_DONE);
-
- if (wsp->walk_addr >= winfo->w_end)
- return (WALK_DONE);
-
- status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
- wsp->walk_cbdata);
-
- wsp->walk_addr += sizeof (_sd_wr_cctl_t);
-
- return (status);
-
-}
-
-static void
-sdbc_wctl_wfini(mdb_walk_state_t *wsp)
-{
- mdb_free(wsp->walk_data, sizeof (struct walk_info));
-}
-
-/*
- * walk the queue (free list) of write control structures
- */
-
-static int
-sdbc_wrq_winit(mdb_walk_state_t *wsp)
-{
- _sd_net_t _sd_net_config;
- _sd_writeq_t wrq;
-
- /* if called without an address, start at the head of the queue */
- if (wsp->walk_addr == NULL) {
-
- if (mdb_readvar(&_sd_net_config, "_sd_net_config") == -1) {
- mdb_warn("failed to read _sd_net_config structure");
- return (WALK_ERR);
- }
-
- wsp->walk_addr = (uintptr_t)
- (_sd_net_config.sn_wr_queue.wq_qtop);
- }
-
- return (WALK_NEXT);
-}
-
-static int
-sdbc_wrq_wstep(mdb_walk_state_t *wsp)
-{
- _sd_wr_cctl_t wctl;
- int status;
-
- if (wsp->walk_addr == NULL)
- return (WALK_DONE);
-
- status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
- wsp->walk_cbdata);
-
- if (mdb_vread(&wctl, sizeof (_sd_wr_cctl_t), wsp->walk_addr)
- == -1) {
- mdb_warn("sdbc_cchain_wstep failed to read wctl at %p",
- wsp->walk_addr);
- return (WALK_ERR);
- }
-
- /* special case -- mini-DSP fake wr_cctl */
- if (wsp->walk_addr == (uintptr_t)wctl.wc_next)
- return (WALK_DONE);
-
- wsp->walk_addr = (uintptr_t)(wctl.wc_next);
-
- return (WALK_NEXT);
-}
-
-static void
-sdbc_wrq_wfini(mdb_walk_state_t *wsp)
-{
-}
-#endif /* SAFESTORE */
-/*
- * walk the _sd_cache_files array of cd_info structures
- */
-static int
-sdbc_cdinfo_winit(mdb_walk_state_t *wsp)
-{
- struct walk_info *winfo;
- _sd_cd_info_t *_sd_cache_files_addr;
- int maxdevs;
-
- winfo = mdb_zalloc(sizeof (struct walk_info), UM_SLEEP);
-
-
- /* get the address of the cdinfo table */
- if (mdb_readvar(&_sd_cache_files_addr, "_sd_cache_files") == -1) {
- mdb_warn("failed to read _sd_cache_files address\n");
- return (WALK_ERR);
- }
-
- /* if called without an address, start at the head of the queue */
- if (wsp->walk_addr == NULL) {
- /* address of first _sd_cd_info_t */
- wsp->walk_addr = (uintptr_t)(_sd_cache_files_addr);
- }
-
- /* get the number of volumes */
- if (mdb_readvar(&maxdevs, "sdbc_max_devs") == -1) {
- mdb_warn("failed to read sdbc_max_devs");
- return (WALK_ERR);
- }
-
- winfo->w_end = (uintptr_t)(_sd_cache_files_addr + maxdevs);
- wsp->walk_data = winfo;
-
- return (WALK_NEXT);
-}
-
-static int
-sdbc_cdinfo_wstep(mdb_walk_state_t *wsp)
-{
- struct walk_info *winfo = wsp->walk_data;
- int status;
-
- if (wsp->walk_addr >= winfo->w_end)
- return (WALK_DONE);
-
- status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
- wsp->walk_cbdata);
-
- wsp->walk_addr += sizeof (_sd_cd_info_t);
-
- return (status);
-}
-
-static void
-sdbc_cdinfo_wfini(mdb_walk_state_t *wsp)
-{
- mdb_free(wsp->walk_data, sizeof (struct walk_info));
-}
-
-#ifdef SAFESTORE
-/*
- * walk the array of allocated fault tolerant control structures
- */
-static int
-sdbc_ftctl_winit(mdb_walk_state_t *wsp)
-{
- _sd_net_t _sd_net_config;
- struct walk_info *winfo;
- int blk_shft = 13; /* 8k default */
- int count;
-
-
- winfo = mdb_zalloc(sizeof (struct walk_info), UM_SLEEP);
-
- /* need to calculate the end of the array */
- if (mdb_readvar(&_sd_net_config, "_sd_net_config") == -1) {
- mdb_warn("failed to read _sd_net_config structure");
- return (WALK_ERR);
- }
-
- if (wsp->walk_addr == NULL)
- wsp->walk_addr = (uintptr_t)(_sd_net_config.sn_ft_cctl);
-
- /*
- * this module assumes 8k block size so this code can
- * be commented out if necessary.
- */
- if (mdb_readvar(&blk_shft, "_sd_cblock_shift") == -1) {
- mdb_warn("failed to read _sd_cblock_shift."
- "assuming 8k cache block size");
- blk_shft = 13;
- }
-
- count = (_sd_net_config.sn_wpages * _sd_net_config.sn_psize) /
- (1 << blk_shft);
-
- winfo->w_end = (uintptr_t)(_sd_net_config.sn_ft_cctl + count);
- wsp->walk_data = winfo;
-
- return (WALK_NEXT);
-}
-
-static int
-sdbc_ftctl_wstep(mdb_walk_state_t *wsp)
-{
- struct walk_info *winfo = wsp->walk_data;
- int status;
-
- if (wsp->walk_addr == NULL)
- return (WALK_DONE);
-
- if (wsp->walk_addr >= winfo->w_end)
- return (WALK_DONE);
-
- status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
- wsp->walk_cbdata);
-
- wsp->walk_addr += sizeof (_sd_ft_cctl_t);
-
- return (status);
-}
-
-static void
-sdbc_ftctl_wfini(mdb_walk_state_t *wsp)
-{
- mdb_free(wsp->walk_data, sizeof (struct walk_info));
-}
-#endif /* SAFESTORE */
-
-/*
- * walk the handle list
- */
-static int
-sdbc_handle_winit(mdb_walk_state_t *wsp)
-{
- _sd_buf_hlist_t hl;
- struct walk_info *winfo;
- GElf_Sym sym;
-
- if (mdb_readvar(&hl, "_sd_handle_list") == -1) {
- mdb_warn("failed to read _sd_handle_list structure");
- return (WALK_ERR);
- }
-
- if (mdb_lookup_by_obj("sdbc", "_sd_handle_list", &sym) == -1) {
- mdb_warn("failed to lookup _sd_handle_list symbol");
- return (WALK_ERR);
- }
-
- /* if called without an address, start at first element in list */
- if (wsp->walk_addr == NULL)
- wsp->walk_addr = (uintptr_t)(hl.hl_top.bh_next);
-
- winfo = mdb_zalloc(sizeof (struct walk_info), UM_SLEEP);
-
- winfo->w_end = (uintptr_t)(sym.st_value); /* &_sd_handle_list.hl_top */
- wsp->walk_data = winfo;
-
- return (WALK_NEXT);
-}
-
-static int
-sdbc_handle_wstep(mdb_walk_state_t *wsp)
-{
- struct walk_info *winfo = wsp->walk_data;
- _sd_buf_handle_t handle;
- int status;
-
- if (wsp->walk_addr == NULL)
- return (WALK_DONE);
-
- if (wsp->walk_addr == winfo->w_end)
- return (WALK_DONE);
-
- status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
- wsp->walk_cbdata);
-
- if (mdb_vread(&handle, sizeof (_sd_buf_handle_t), wsp->walk_addr)
- == -1) {
- mdb_warn("failed to read handle at %p", wsp->walk_addr);
- return (WALK_ERR);
- }
-
- wsp->walk_addr = (uintptr_t)(handle.bh_next);
-
- return (status);
-}
-
-static void
-sdbc_handle_wfini(mdb_walk_state_t *wsp)
-{
- mdb_free(wsp->walk_data, sizeof (struct walk_info));
-}
-
-/*
- * walk the global info array (dirty bits)
- */
-
-static int
-sdbc_glcinfo_winit(mdb_walk_state_t *wsp)
-{
- ss_centry_info_t *gl_centry_info;
- size_t gl_centry_info_size;
- struct walk_info *winfo;
-
-
- winfo = mdb_zalloc(sizeof (struct walk_info), UM_SLEEP);
-
- /* get start of the cache entry metadata */
- if (mdb_readvar(&gl_centry_info, "_sdbc_gl_centry_info") == -1) {
- mdb_warn("failed to read _sdbc_gl_centry_info");
- return (WALK_ERR);
- }
-
- /* need to calculate the end of the array */
- if (mdb_readvar(&gl_centry_info_size,
- "_sdbc_gl_centry_info_size") == -1) {
- mdb_warn("failed to read _sdbc_gl_centry_info_size");
- return (WALK_ERR);
- }
-
- if (wsp->walk_addr == NULL)
- wsp->walk_addr = (uintptr_t)(gl_centry_info);
-
-
-
- winfo->w_end = ((uintptr_t)(gl_centry_info)) + gl_centry_info_size;
- wsp->walk_data = winfo;
-
- return (WALK_NEXT);
-}
-
-static int
-sdbc_glcinfo_wstep(mdb_walk_state_t *wsp)
-{
- struct walk_info *winfo = wsp->walk_data;
- int status;
-
- if (wsp->walk_addr == NULL)
- return (WALK_DONE);
-
- if (wsp->walk_addr >= winfo->w_end)
- return (WALK_DONE);
- status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
- wsp->walk_cbdata);
-
- wsp->walk_addr += sizeof (ss_centry_info_t);
-
- return (status);
-}
-
-static void
-sdbc_glcinfo_wfini(mdb_walk_state_t *wsp)
-{
- mdb_free(wsp->walk_data, sizeof (struct walk_info));
-}
-
-/*
- * walk the global file info array
- */
-static int
-sdbc_glfinfo_winit(mdb_walk_state_t *wsp)
-{
- ss_voldata_t *gl_file_info;
- struct walk_info *winfo;
- int maxdevs;
-
-
- winfo = mdb_zalloc(sizeof (struct walk_info), UM_SLEEP);
-
- /* get start of the cache entry metadata */
- if (mdb_readvar(&gl_file_info, "_sdbc_gl_file_info") == -1) {
- mdb_warn("failed to read _sdbc_gl_file_info");
- return (WALK_ERR);
- }
-
-
- if (wsp->walk_addr == NULL)
- wsp->walk_addr = (uintptr_t)(gl_file_info);
-
- /* get the number of volumes */
- if (mdb_readvar(&maxdevs, "sdbc_max_devs") == -1) {
- mdb_warn("failed to read sdbc_max_devs");
- return (WALK_ERR);
- }
-
- /* end of the array */
- winfo->w_end = (uintptr_t)((gl_file_info) + maxdevs);
-
- wsp->walk_data = winfo;
-
- return (WALK_NEXT);
-}
-
-static int
-sdbc_glfinfo_wstep(mdb_walk_state_t *wsp)
-{
- struct walk_info *winfo = wsp->walk_data;
- int status;
-
- if (wsp->walk_addr == NULL)
- return (WALK_DONE);
-
- if (wsp->walk_addr >= winfo->w_end)
- return (WALK_DONE);
-
- status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
- wsp->walk_cbdata);
-
- wsp->walk_addr += sizeof (ss_voldata_t);
-
- return (status);
-
-}
-
-static void
-sdbc_glfinfo_wfini(mdb_walk_state_t *wsp)
-{
- mdb_free(wsp->walk_data, sizeof (struct walk_info));
-}
-
-/* end of WALKERS section */
-
-
-const mdb_bitmask_t cc_flag_bits[] = {
- {"PEND_DIRTY", CC_PEND_DIRTY, CC_PEND_DIRTY},
- {"PINNED", CC_PINNED, CC_PINNED},
- {"PINNABLE", CC_PINNABLE, CC_PINNABLE},
- {"QHEAD", CC_QHEAD, CC_QHEAD},
- {NULL, 0, 0}
-};
-
-const mdb_bitmask_t io_status_bits[] = {
- {"IO_NONE", 0xff, _SD_IO_NONE},
- {"IO_INITIATE", 0xff, _SD_IO_INITIATE},
- {"IO_DONE", 0xff, _SD_IO_DONE},
- {"IO_FAILED", 0xff, _SD_IO_FAILED},
- {"IO_DISCARDED", 0xff, _SD_IO_DISCARDED},
- {NULL, 0, 0}
-};
-
-const mdb_bitmask_t cc_aging_bits[] = {
- {"FOUND_IN_HASH", FOUND_IN_HASH_DM, FOUND_IN_HASH_DM},
- {"FOUND_HOLD_OVER", FOUND_HOLD_OVER_DM, FOUND_HOLD_OVER_DM},
- {"HOST_ENTRY", HOST_ENTRY_DM, HOST_ENTRY_DM},
- {"PARASITIC_ENTRY", PARASITIC_ENTRY_DM, PARASITIC_ENTRY_DM},
- {"STICKY_METADATA", STICKY_METADATA_DM, STICKY_METADATA_DM},
- {"ELIGIBLE_ENTRY", ELIGIBLE_ENTRY_DM, ELIGIBLE_ENTRY_DM},
- {"HASH_ENTRY", HASH_ENTRY_DM, HASH_ENTRY_DM},
- {"HOLD_ENTRY", HOLD_ENTRY_DM, HOLD_ENTRY_DM},
- {"AVAIL_ENTRY", AVAIL_ENTRY_DM, AVAIL_ENTRY_DM},
- {"BAD_CHAIN", BAD_CHAIN_DM, BAD_CHAIN_DM},
- {"BAD_ENTRY", BAD_ENTRY_DM, BAD_ENTRY_DM},
- {"PREFETCH_I", PREFETCH_BUF_I, PREFETCH_BUF_I},
- {"PREFETCH_E", PREFETCH_BUF_E, PREFETCH_BUF_E},
- {NULL, 0, 0}
-};
-
-
-/* DCMDS that use walkers */
-
-/*
- * dcmd to display cache entry control structures
- */
-static int
-sdbc_cctl(uintptr_t addr, uint_t flags, int argc,
- const mdb_arg_t *argv)
-{
- uint_t opt_a = FALSE;
- uintptr_t opt_c = MDB_CD; /* cd */
- uintptr_t opt_b = MDB_BLKNUM; /* block num */
- uint_t opt_B = FALSE; /* BAD CHAIN or ENTRY */
- uint_t opt_d = FALSE; /* dirty */
- uint_t opt_H = FALSE; /* HOST */
- uint_t opt_h = FALSE; /* hashed */
- uint_t opt_i = FALSE; /* inuse */
- uint_t opt_p = FALSE; /* pageio */
- uint_t opt_P = FALSE; /* PARASITE */
- uint_t opt_R = FALSE; /* explicit read-ahead (prefetch) */
- uint_t opt_r = FALSE; /* implicit read-ahead (prefetch) */
- uint_t opt_o = FALSE; /* io in progress */
- uint_t opt_m = FALSE; /* has memory allocated */
- uint_t opt_V = FALSE; /* valid bits */
- uint_t opt_v = FALSE; /* verbose */
- uint_t nofilter = FALSE; /* true if b, d, h, i, o, p, V are all false */
- _sd_cctl_t centry;
- _sd_cctl_sync_t cc_sync;
-
- /*
- * possible enhancements -- option to filter on flag bits
- * option that toggles other options.
- */
- if (mdb_getopts(argc, argv,
- 'a', MDB_OPT_SETBITS, TRUE, &opt_a,
- 'B', MDB_OPT_SETBITS, TRUE, &opt_B,
- 'b', MDB_OPT_UINTPTR, &opt_b,
- 'c', MDB_OPT_UINTPTR, &opt_c,
- 'd', MDB_OPT_SETBITS, TRUE, &opt_d,
- 'H', MDB_OPT_SETBITS, TRUE, &opt_H,
- 'h', MDB_OPT_SETBITS, TRUE, &opt_h,
- 'i', MDB_OPT_SETBITS, TRUE, &opt_i,
- 'o', MDB_OPT_SETBITS, TRUE, &opt_o,
- 'm', MDB_OPT_SETBITS, TRUE, &opt_m,
- 'P', MDB_OPT_SETBITS, TRUE, &opt_P,
- 'p', MDB_OPT_SETBITS, TRUE, &opt_p,
- 'R', MDB_OPT_SETBITS, TRUE, &opt_R,
- 'r', MDB_OPT_SETBITS, TRUE, &opt_r,
- 'V', MDB_OPT_SETBITS, TRUE, &opt_V,
- 'v', MDB_OPT_SETBITS, TRUE, &opt_v) != argc)
- return (DCMD_USAGE);
-
-
- nofilter = (!OPT_B_SELECTED && !opt_d && !opt_h && !opt_i &&
- !opt_o && !opt_m && !opt_p && !opt_V && !opt_B &&
- !opt_P && !opt_H && !opt_R && !opt_r); /* no options */
-
- if (!(flags & DCMD_ADDRSPEC)) {
- if (mdb_walk_dcmd("sdbc`sdbc_cctl", "sdbc`sdbc_cctl",
- argc, argv) == -1) {
- mdb_warn("failed to walk 'cctl' list");
- return (DCMD_ERR);
- }
- return (DCMD_OK);
- }
-
- if (DCMD_HDRSPEC(flags)) {
- mdb_printf("sdbc cache ctl structures:\n");
- }
-
-
- if (mdb_vread(&centry, sizeof (_sd_cctl_t), addr) == -1) {
- mdb_warn("dcmd failed to read centry at %p", addr);
- return (DCMD_ERR);
- }
-
- /* filter exclusively on a cd number if specified */
- if (OPT_C_SELECTED && (centry.cc_head.hh_cd != opt_c))
- return (DCMD_OK);
-
- /* all other filters are inclusive */
- if ((nofilter) ||
- (OPT_B_SELECTED && (centry.cc_head.hh_blk_num == opt_b)) ||
- (opt_B && (centry.cc_aging_dm &
- (BAD_ENTRY_DM | BAD_CHAIN_DM))) ||
- (opt_d && (centry.cc_dirty)) ||
- (opt_H && (centry.cc_aging_dm & HOST_ENTRY_DM)) ||
- (opt_h && (centry.cc_head.hh_hashed)) ||
- (opt_i && (centry.cc_inuse)) ||
- (opt_p && (centry.cc_pageio)) ||
- (opt_P && (centry.cc_aging_dm & PARASITIC_ENTRY_DM)) ||
- (opt_R && (centry.cc_aging_dm & PREFETCH_BUF_E)) ||
- (opt_r && (centry.cc_aging_dm & PREFETCH_BUF_I)) ||
- (opt_V && (centry.cc_valid)) ||
- (opt_m && (centry.cc_alloc_size_dm)) ||
- (opt_o && (centry.cc_iostatus != _SD_IO_NONE)))
- /*EMPTY*/;
- else
- return (DCMD_OK);
-
- mdb_inc_indent(4);
- mdb_printf(
- "%-?p cd %3-d blk_num %10-d valid %04hx dirty %04hx flag %02x\n",
- addr, centry.cc_head.hh_cd,
- centry.cc_head.hh_blk_num, centry.cc_valid,
- centry.cc_dirty, centry.cc_flag);
- mdb_dec_indent(4);
-
- if (!opt_v)
- return (DCMD_OK);
-
- /* verbose */
- mdb_inc_indent(4);
- mdb_printf(
- "hashed %d seq %4-d toflush %04hx %8Tawait_use %4-d await_page %4-d\n",
- centry.cc_head.hh_hashed, centry.cc_seq,
- centry.cc_toflush, centry.cc_await_use,
- centry.cc_await_page);
-
- mdb_printf("inuse %d pageio %d cc_flag <%b>\n",
- centry.cc_inuse, centry.cc_pageio,
- centry.cc_flag, cc_flag_bits);
-
- mdb_printf("iocount %2d iostatus <%b>\n",
- centry.cc_iocount, centry.cc_iostatus, io_status_bits);
-
- if (mdb_vread(&cc_sync, sizeof (struct _sd_cctl_sync),
- (uintptr_t)centry.cc_sync)
- == -1)
- mdb_warn("failed to read cc_sync"); /* not catastophic */
-
- else
- mdb_printf("cc_sync blkcv: %h-x %8Tlock: 0x%p (owner)\n",
- cc_sync._cc_blkcv._opaque,
- cc_sync._cc_lock._opaque[0]);
-
- mdb_printf("dynamic memory allocation:\n");
- mdb_inc_indent(4);
- mdb_printf("aging_dm age %3d %4Tage flags: <%b> 0x%x\n",
- centry.cc_aging_dm & 0xff,
- centry.cc_aging_dm, cc_aging_bits, centry.cc_aging_dm);
-
- mdb_printf("alloc_size_dm %10-d head_dm %?-p\n",
- centry.cc_alloc_size_dm, centry.cc_head_dm);
- mdb_printf("next_dm %?-p link_list_dm %?-p\n",
- centry.cc_next_dm, centry.cc_link_list_dm);
-
- mdb_printf("alloc_ct_dm %10-d dealloc_ct_dm %10-d\n",
- centry.cc_alloc_ct_dm, centry.cc_dealloc_ct_dm);
-
- mdb_dec_indent(4);
- /* pointers */
- mdb_printf("cctl pointers:\n");
- mdb_inc_indent(4);
-
- mdb_printf("next %?-p prev %?-p chain %?-p\n",
- centry.cc_next, centry.cc_prev, centry.cc_chain);
- mdb_printf("dirty_next %?-p dirty_link %?-p\n",
- centry.cc_dirty_next, centry.cc_dirty_link);
- mdb_printf("data %?-p write ctl %?-p\n",
- centry.cc_data, centry.cc_write);
-
- mdb_dec_indent(4);
-
- /* dynmem chain */
- mdb_printf("cctl dmqueue index cc_blocks %4-d\n", centry.cc_cblocks);
-
- mdb_printf("anon_addr %?-p anon_len %8-d\n",
- centry.cc_anon_addr.sa_virt, centry.cc_anon_len);
-
- /* stats */
- mdb_printf("cctl stats: ");
- mdb_inc_indent(4);
- mdb_printf("hits %8-d creat time %?-p\n", centry.cc_hits,
- centry.cc_creat);
- mdb_dec_indent(4);
-
- mdb_printf("\n");
-
- mdb_dec_indent(4);
-
- return (DCMD_OK);
-}
-
-
-/*
- * convenience dcmd to display the _sd_cctl cc_chain list (alloc list)
- * Must be called with an address of a cache entry (_sd_cctl_t)
- * same options as sdbc_cctl().
- * alternatively the user can call the sdbc_cchain walker
- * and pipe the addresses to sdbc_cctl dcmd.
- */
-static int
-sdbc_cchain(uintptr_t addr, uint_t flags, int argc,
- const mdb_arg_t *argv)
-{
-
- if (!(flags & DCMD_ADDRSPEC))
- return (DCMD_USAGE);
-
- if (mdb_pwalk_dcmd("sdbc`sdbc_cchain", "sdbc`sdbc_cctl",
- argc, argv, addr)
- == -1) {
- mdb_warn("failed to walk cc_chain at addr %p", addr);
- return (DCMD_ERR);
- }
-
- return (DCMD_OK);
-}
-
-
-/*
- * convenience dcmd to cdisplay the _sd_cctl dirty chain
- * (which is really a 2d chain).
- * Must be called with an address of a cache entry (_sd_cctl_t)
- * same options as sdbc_cctl().
- * alternatively the user can call the sdbc_dchain walker
- * and pipe the addresses to sdbc_cctl dcmd.
- */
-static int
-sdbc_dchain(uintptr_t addr, uint_t flags, int argc,
- const mdb_arg_t *argv)
-{
-
- if (!(flags & DCMD_ADDRSPEC))
- return (DCMD_USAGE);
-
- if (mdb_pwalk_dcmd("sdbc`sdbc_dchain", "sdbc`sdbc_cctl",
- argc, argv, addr)
- == -1) {
- mdb_warn("failed to walk dirty chain at addr %p", addr);
- return (DCMD_ERR);
- }
-
- return (DCMD_OK);
-}
-
-/*
- * convenience dcmd to display the _sd_cctl dm chain list
- * Must be called with an address of a cache entry (_sd_cctl_t)
- * same options as sdbc_cctl().
- * alternatively the user can call the sdbc_dmchain walker
- * and pipe the addresses to sdbc_cctl dcmd.
- */
-static int
-sdbc_dmchain(uintptr_t addr, uint_t flags, int argc,
- const mdb_arg_t *argv)
-{
-
- if (!(flags & DCMD_ADDRSPEC))
- return (DCMD_USAGE);
-
- if (mdb_pwalk_dcmd("sdbc`sdbc_dmchain", "sdbc`sdbc_cctl",
- argc, argv, addr)
- == -1) {
- mdb_warn("failed to walk dm chain at addr %p", addr);
- return (DCMD_ERR);
- }
-
- return (DCMD_OK);
-}
-
-/*
- * dcmd to walk a hash chain
- * requires an address. same options as sdbc_cctl dcmd
- */
-static int
-sdbc_hashchain(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- if (!(flags & DCMD_ADDRSPEC))
- return (DCMD_USAGE);
-
- if (mdb_pwalk_dcmd("sdbc`sdbc_hashchain", "sdbc`sdbc_cctl",
- argc, argv, addr) == -1) {
- mdb_warn("failed to walk hashchain at %p", addr);
- return (DCMD_ERR);
- }
-
- return (DCMD_OK);
-}
-
-
-static void
-display_hash_table(_sd_hash_table_t *addr, _sd_hash_table_t *ht)
-{
- mdb_printf("hash table (%p):\n", addr);
- mdb_inc_indent(4);
- mdb_printf("size %7-d bits %2-d mask %8-x nmask %8-x buckets %p\n",
- ht->ht_size, ht->ht_bits, ht->ht_mask,
- ht->ht_nmask, ht->ht_buckets);
- mdb_dec_indent(4);
-}
-
-static void
-display_hash_bucket(_sd_hash_bucket_t *addr, _sd_hash_bucket_t *hb)
-{
- kmutex_t lock;
- int rc;
-
- if ((rc = mdb_vread(&lock, sizeof (kmutex_t),
- (uintptr_t)hb->hb_lock)) == -1)
- mdb_warn("failed to read bucket lock at %p", hb->hb_lock);
-
- mdb_printf("hash bucket (%p):\n", addr);
- mdb_inc_indent(4);
- mdb_printf("head %?-p tail %?-p lock %?-p %s\n",
- hb->hb_head, hb->hb_tail,
- (rc == -1) ? hb->hb_lock : lock._opaque[0],
- (rc == -1) ? "" : "(owner)");
- mdb_printf("inlist %d seq %d\n", hb->hb_inlist, hb->hb_seq);
- mdb_dec_indent(4);
-}
-
-/*
- * dcmd to walk the hash table
- * defaults to _sd_htable the cache hash table,
- * but wil accept an address which is probably only useful
- * in the event that other hash tables are implemented in
- * the cache.
- *
- * calls sdbc_hashchain dcmd. same options as sdbc_cctl dcmd.
- */
-static int
-sdbc_hashtable(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- _sd_hash_table_t *sd_htable_addr;
- _sd_hash_table_t _sd_htable;
- _sd_hash_bucket_t hash_bucket;
- int i;
-
-
-
- if (!(flags & DCMD_ADDRSPEC)) {
- /* get the address of the standard cache hash table */
- if (mdb_readvar(&sd_htable_addr, "_sd_htable") == -1) {
- mdb_warn("failed to read _sd_htable address\n");
- return (DCMD_ERR);
- }
- } else
- sd_htable_addr = (_sd_hash_table_t *)addr;
-
- /* read in the hash table structure */
- if (mdb_vread(&_sd_htable, sizeof (_sd_hash_table_t),
- (uintptr_t)sd_htable_addr) == -1) {
- mdb_warn("failed to read _sd_htable structure at %p\n",
- sd_htable_addr);
- return (DCMD_ERR);
- }
-
- display_hash_table(sd_htable_addr, &_sd_htable);
-
- /*
- * read in the hash buckets
- * and display chains if there are any
- */
- for (i = 0; i < _sd_htable.ht_size; ++i) {
- if (mdb_vread(&hash_bucket, sizeof (_sd_hash_bucket_t),
- (uintptr_t)(_sd_htable.ht_buckets + i)) == -1) {
- mdb_warn("failed to read ht_buckets at %p\n",
- _sd_htable.ht_buckets + i);
- return (DCMD_ERR);
- }
-
- if (hash_bucket.hb_head != NULL) {
- display_hash_bucket(_sd_htable.ht_buckets + i,
- &hash_bucket);
- /*
- * if this walk fails, continue trying
- * to read hash buckets
- */
- if (mdb_call_dcmd("sdbc`sdbc_hashchain",
- (uintptr_t)hash_bucket.hb_head,
- flags|DCMD_ADDRSPEC, argc, argv)
- == -1)
- mdb_warn(
- "failed to walk hash chain at %p",
- hash_bucket.hb_head);
- mdb_printf("\n");
- }
- }
-
- return (DCMD_OK);
-}
-/*
- * dcmd to display the sdbc lru queue
- * same options as sdbc_cctl().
- * alternatively the user can call the sdbc_lru walker
- * and pipe the addresses to sdbc_cctl dcmd.
- */
-static int
-sdbc_lru(uintptr_t addr, uint_t flags, int argc,
- const mdb_arg_t *argv)
-{
- _sd_queue_t _sd_lru_q;
- GElf_Sym sym;
-
- if (!(flags & DCMD_ADDRSPEC)) {
- if (mdb_lookup_by_obj("sdbc", "_sd_lru_q", &sym) == -1) {
- mdb_warn("failed to lookup _sd_lru_q symbol");
- return (DCMD_ERR);
- }
-
- if (mdb_vread(&_sd_lru_q, sizeof (_sd_queue_t),
- sym.st_value) == -1) {
- mdb_warn("failed to read _sd_lru_q structure");
- return (DCMD_ERR);
- }
-
- mdb_printf("Cache LRU Queue\n");
- mdb_inc_indent(4);
- mdb_printf(
- "qlock: 0x%-p (owner) await %d seq %d inq %d req %d noreq %d\n",
- _sd_lru_q.sq_qlock._opaque[0],
- _sd_lru_q.sq_await,
- _sd_lru_q.sq_seq,
- _sd_lru_q.sq_inq,
- _sd_lru_q.sq_req_stat,
- _sd_lru_q.sq_noreq_stat);
-
- addr = (uintptr_t)(sym.st_value);
- }
-
- if (mdb_pwalk_dcmd("sdbc`sdbc_lru", "sdbc`sdbc_cctl",
- argc, argv, addr) == -1) {
- mdb_warn("failed to walk lru at addr %p", addr);
- return (DCMD_ERR);
- }
-
- return (DCMD_OK);
-}
-
-#ifdef SAFESTORE
-static void
-print_wrq(_sd_writeq_t *wrq, uint_t verbose)
-{
- int i;
-
- mdb_printf("Cache Write Ctl Queue:\n");
- mdb_inc_indent(4);
- mdb_printf("qtop %-p qlock: %-p (owner) inq %d\n",
- wrq->wq_qtop,
- wrq->wq_qlock._opaque[0],
- wrq->wq_inq);
-
- mdb_printf("slp_top %3-d slp_index %3-d slp_inq %3-d\n",
- wrq->wq_slp_top,
- wrq->wq_slp_index,
- wrq->wq_slp_inq);
-
- for (i = 0; verbose && i < SD_WR_SLP_Q_MAX; i += 2) {
- mdb_printf("%3d: cv %h-x wq_need %3-d wq_held %3-d%4T",
- i,
- wrq->wq_slp[i].slp_wqcv._opaque,
- wrq->wq_slp[i].slp_wqneed,
- wrq->wq_slp[i].slp_wqheld);
- if (SD_WR_SLP_Q_MAX > (i + 1)) {
- mdb_printf(
- "%3d: cv %h-x wq_need %3-d wq_held %3-d%\n",
- i+1,
- wrq->wq_slp[i+1].slp_wqcv._opaque,
- wrq->wq_slp[i+1].slp_wqneed,
- wrq->wq_slp[i+1].slp_wqheld);
- }
- }
- mdb_dec_indent(4);
-}
-
-/*
- * dcmd to display write control structures
- */
-
-static int
-sdbc_wctl(uintptr_t addr, uint_t flags, int argc,
- const mdb_arg_t *argv)
-{
- _sd_wr_cctl_t wctl;
- ss_centry_info_t gl_info;
- ss_centry_info_t nv_gl_info;
- uintptr_t opt_c = MDB_CD;
- uint_t opt_d = FALSE;
- uint_t opt_v = FALSE;
-
-
- /* TODO option for fba pos */
- if (mdb_getopts(argc, argv,
- 'd', MDB_OPT_SETBITS, TRUE, &opt_d,
- 'c', MDB_OPT_UINTPTR, &opt_c,
- 'v', MDB_OPT_SETBITS, TRUE, &opt_v) != argc)
- return (DCMD_USAGE);
-
-
- if (!(flags & DCMD_ADDRSPEC)) {
- if (mdb_walk_dcmd("sdbc`sdbc_wctl", "sdbc`sdbc_wctl",
- argc, argv) == -1) {
- mdb_warn("failed to walk write ctl array");
- return (DCMD_ERR);
- }
- return (DCMD_OK);
- }
-
- if (DCMD_HDRSPEC(flags)) {
- mdb_printf("write control block structures:\n");
- }
-
- if (mdb_vread(&wctl, sizeof (_sd_wr_cctl_t), addr) == -1) {
- mdb_warn("failed to read wctl at 0x%p", addr);
- return (DCMD_ERR);
- }
-
-
- /*
- * print "all" is the default.
- * filter conditions can only be checked by reading in wc_gl_info
- */
- if (opt_c || opt_d || opt_v)
- if (mdb_vread(&gl_info, sizeof (ss_centry_info_t),
- (uintptr_t)wctl.wc_gl_info) == -1) {
- mdb_warn("failed to read at wc_gl_info 0x%p", addr);
- return (DCMD_ERR);
- }
-
-
- if (OPT_C_SELECTED && (gl_info.gl_cd != opt_c))
- return (DCMD_OK);
-
- if (opt_d && !(gl_info.gl_dirty))
- return (DCMD_OK);
-
- mdb_inc_indent(4);
- mdb_printf("%-p data %-p gl_info %-p Ngl_info %-p flg %02x\n",
- addr,
- wctl.wc_data,
- wctl.wc_gl_info,
- wctl.wc_nvmem_gl_info,
- wctl.wc_flag);
- mdb_dec_indent(4);
-
- /* verbose */
- if (!opt_v)
- return (DCMD_OK);
-
- mdb_inc_indent(4);
- mdb_printf("next %?-p prev %?-p\n", wctl.wc_next, wctl.wc_prev);
- mdb_printf(" gl_info: ");
- mdb_printf("cd %3-d fpos %10-d dirty %04x flag <%b>\n",
- gl_info.gl_cd, gl_info.gl_fpos, gl_info.gl_dirty & 0xffff,
- gl_info.gl_flag, cc_flag_bits);
-
- if (wctl.wc_nvmem_gl_info) {
- if (mdb_vread(&nv_gl_info, sizeof (ss_centry_info_t),
- (uintptr_t)wctl.wc_nvmem_gl_info) == -1) {
- mdb_warn("failed to read at wc_nvmem_gl_info 0x%p",
- wctl.wc_nvmem_gl_info); /* not catastophic, continue */
- } else {
-
- /* consistency check */
- if (memcmp(&gl_info, &nv_gl_info,
- sizeof (ss_centry_info_t) != 0)) {
- mdb_warn("nvram and host memory are NOT identical!");
- mdb_printf("nvmem_gl_info: ");
- mdb_printf("cd %3-d fpos %10-d dirty %04x flag <%b>\n",
- nv_gl_info.gl_cd, nv_gl_info.gl_fpos,
- nv_gl_info.gl_dirty & 0xffff,
- nv_gl_info.gl_flag, cc_flag_bits);
- }
-
- }
- }
-
- mdb_dec_indent(4);
- mdb_printf("\n");
- return (DCMD_OK);
-}
-
-/*
- * dcmd to display write control structures in the free list
- * same options as sdbc_wctl
- */
-
-static int
-sdbc_wrq(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- _sd_net_t _sd_net_config;
- uintptr_t opt_c = MDB_CD;
- uint_t opt_d = FALSE;
- uint_t opt_v = FALSE;
-
-
- /* look for verbose option */
- if (mdb_getopts(argc, argv,
- 'd', MDB_OPT_SETBITS, TRUE, &opt_d,
- 'c', MDB_OPT_UINTPTR, &opt_c,
- 'v', MDB_OPT_SETBITS, TRUE, &opt_v) != argc)
- return (DCMD_USAGE);
-
- if (!(flags & DCMD_ADDRSPEC)) {
- if (mdb_readvar(&_sd_net_config, "_sd_net_config") == -1) {
- mdb_warn("failed to read _sd_net_config structure");
- return (DCMD_ERR);
- }
-
- print_wrq(&(_sd_net_config.sn_wr_queue), opt_v);
-
- addr = (uintptr_t)(_sd_net_config.sn_wr_queue.wq_qtop);
- }
-
- if (mdb_pwalk_dcmd("sdbc`sdbc_wrq", "sdbc`sdbc_wctl",
- argc, argv, addr) == -1) {
- mdb_warn("failed to walk write ctl queue at addr %p", addr);
- return (DCMD_ERR);
- }
- return (DCMD_OK);
-}
-#endif
-
-/*
- * dcmd to display the dm queues
- * use sdbc_lru walker to walk each queue.
- */
-/*ARGSUSED*/
-static int
-sdbc_dmqueues(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- _sd_queue_t *sdbc_dm_queues; /* kernel address of dm queues */
- int max_dm_queues;
- _sd_queue_t *queues = NULL; /* local copy */
- int i;
-
-
- if (argc != 0)
- return (DCMD_USAGE);
-
- if (!(flags & DCMD_ADDRSPEC)) {
- if (mdb_readvar(&sdbc_dm_queues, "sdbc_dm_queues") == -1) {
- mdb_warn("failed to read sdbc_dm_queues address\n");
- return (DCMD_ERR);
- }
-
- if (mdb_readvar(&max_dm_queues, "max_dm_queues") == -1) {
- mdb_warn("failed to read max_dm_queues variable\n");
- return (DCMD_ERR);
- }
-
- queues = mdb_zalloc(max_dm_queues * sizeof (_sd_queue_t),
- UM_SLEEP);
-mdb_printf("max_dm_queues %d sdbc_dm_queues %p queues %p\n",
- max_dm_queues, sdbc_dm_queues, queues);
-
- if (mdb_vread(queues, max_dm_queues * sizeof (_sd_queue_t),
- (uintptr_t)sdbc_dm_queues) == -1) {
- mdb_warn("failed to read sdbc_dm_queues");
- return (DCMD_ERR);
- }
-
- for (i = 0; i < max_dm_queues; ++i) {
- mdb_printf("Cache DM Queue %d %p\n",
- queues[i].sq_dmchain_cblocks,
- sdbc_dm_queues +i);
- mdb_inc_indent(4);
- mdb_printf("qlock: 0x%-p (owner) await %d "
- "seq %d inq %d req %d noreq %d\n",
- queues[i].sq_qlock._opaque[0],
- queues[i].sq_await,
- queues[i].sq_seq,
- queues[i].sq_inq,
- queues[i].sq_req_stat,
- queues[i].sq_noreq_stat);
-
- mdb_dec_indent(4);
- }
- }
-
- return (DCMD_OK);
-}
-
-
-mdb_bitmask_t cd_writer_bits[] = {
- { "NONE ", (u_longlong_t)~0, _SD_WRITER_NONE },
- { "CREATE ", (u_longlong_t)~0, _SD_WRITER_CREATE },
- { "RUNNING", (u_longlong_t)~0, _SD_WRITER_RUNNING },
- { NULL, 0, 0 }
-};
-
-mdb_bitmask_t sh_failed_status[] = {
- { "STATUS OK", (u_longlong_t)~0, 0 },
- { "I/O ERROR", (u_longlong_t)~0, 1 },
- { "OPEN FAIL", (u_longlong_t)~0, 2 },
- { NULL, 0, 0 }
-};
-
-mdb_bitmask_t sh_flag_bits[] = {
- { "ATTACHED", CD_ATTACHED, CD_ATTACHED },
- { NULL, 0, 0 }
-};
-
-mdb_bitmask_t sh_alloc_bits[] = {
- { "ALLOC_IN_PROGRESS", CD_ALLOC_IN_PROGRESS, CD_ALLOC_IN_PROGRESS },
- { "ALLOCATED", CD_ALLOCATED, CD_ALLOCATED },
- { "CLOSE_IN_PROGRESS", CD_CLOSE_IN_PROGRESS, CD_CLOSE_IN_PROGRESS },
- { NULL, 0, 0 }
-};
-
-/*
- * dcmd to display cd information
- */
-static int
-sdbc_cdinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- _sd_shared_t sd_shared;
- _sd_cd_info_t cdi;
- ss_voldata_t gl_file;
- char *fn = "nopath"; /* filename if sd_shared info cannot be read */
- uchar_t sh_alloc = 0; /* assume not alloc'd if sd_shared info unavail */
- uintptr_t opt_c = MDB_CD;
- uint_t opt_a = FALSE;
- uint_t opt_v = FALSE;
- int dev_t_chars;
-
- dev_t_chars = sizeof (dev_t) * 2; /* # chars to display dev_t */
-
-
- if (mdb_getopts(argc, argv,
- 'a', MDB_OPT_SETBITS, TRUE, &opt_a,
- 'c', MDB_OPT_UINTPTR, &opt_c,
- 'v', MDB_OPT_SETBITS, TRUE, &opt_v) != argc)
- return (DCMD_USAGE);
-
- if (!(flags & DCMD_ADDRSPEC)) {
- if (mdb_walk_dcmd("sdbc`sdbc_cdinfo", "sdbc`sdbc_cdinfo",
- argc, argv) == -1) {
- mdb_warn("failed to walk cd info array");
- return (DCMD_ERR);
- }
- return (DCMD_OK);
- }
-
- if (DCMD_HDRSPEC(flags)) {
- mdb_printf("cd info structures:\n");
- }
-
- if (mdb_vread(&cdi, sizeof (_sd_cd_info_t), addr) == -1) {
- mdb_warn("failed to read cd info at 0x%p", addr);
- return (DCMD_ERR);
- }
-
- /*
- * need to do this read even for non-verbose option to
- * get the filename and the sh_alloc field
- */
- if (cdi.cd_info) {
- if (mdb_vread(&sd_shared, sizeof (_sd_shared_t),
- (uintptr_t)cdi.cd_info) == -1) {
- mdb_warn("failed to read shared cd info at 0x%p",
- cdi.cd_info);
- /* not catastrophic, keep truckin' */
- } else {
- fn = sd_shared.sh_filename;
- sh_alloc = sd_shared.sh_alloc;
- }
- }
-
- if (!opt_a && (sh_alloc == 0))
- return (DCMD_OK);
-
- if (OPT_C_SELECTED && (opt_c != cdi.cd_desc))
- return (DCMD_OK);
-
- mdb_inc_indent(4);
- mdb_printf("%p cd %3-d filename %s\n",
- addr, cdi.cd_desc, fn);
- mdb_printf("alloc <%b> hint <%b>\n",
- sh_alloc, sh_alloc_bits,
- cdi.cd_hint, cache_hints);
- mdb_dec_indent(4);
-
- if (!opt_v)
- return (DCMD_OK);
-
- /* verbose */
- mdb_inc_indent(4);
- mdb_printf("rawfd %?-p crdev %0*lx iodev %?-p\n",
- cdi.cd_rawfd,
- dev_t_chars,
- cdi.cd_crdev,
- cdi.cd_iodev);
- mdb_printf("flag %x %8Tlock %?-p writer <%b>\n",
- cdi.cd_flag,
- cdi.cd_lock._opaque[0],
- cdi.cd_writer, cd_writer_bits);
- mdb_printf("global %?-p dirty_head %?-p\n",
- cdi.cd_global, cdi.cd_dirty_head);
- mdb_printf("last_ent %?-p lastchain_ptr %?-p lastchain %d\n",
- cdi.cd_last_ent, cdi.cd_lastchain_ptr,
- cdi.cd_lastchain);
- mdb_printf("io_head %?-p io_tail %?-p fail_head %?-p\n",
- cdi.cd_io_head, cdi.cd_io_tail, cdi.cd_fail_head);
- mdb_printf(
- "cd_info %?-p failover %d recovering %d write_inprogress %d\n",
- cdi.cd_info, cdi.cd_failover,
- cdi.cd_recovering,
- cdi.cd_write_inprogress);
-
- if (cdi.cd_global != NULL) {
- if (mdb_vread(&gl_file, sizeof (ss_voldata_t),
- (uintptr_t)cdi.cd_global) == -1)
- mdb_warn("failed to read cd_global at %p",
- cdi.cd_global);
- else {
- mdb_printf("cd_global: %s\n", gl_file.sv_volname);
- mdb_printf("pinned %2-d attached %2-d devidsz %3-d\n",
- gl_file.sv_pinned, gl_file.sv_attached,
- gl_file.sv_devidsz);
- mdb_printf("devid %s\n", gl_file.sv_devid);
- mdb_printf("vol %?p\n", gl_file.sv_vol);
- }
- /* TODO do a consistency check here against the nvram copy */
- }
-
- if (cdi.cd_info == NULL) {
- mdb_printf("no shared info\n");
- } else {
- mdb_printf("shared:\n");
- mdb_printf("failed <%b> cd %3-d",
- sd_shared.sh_failed, sh_failed_status,
- sd_shared.sh_cd);
- mdb_printf("cache_read %10-d cache_write %10-d\n",
- sd_shared.sh_cache_read, sd_shared.sh_cache_write);
- mdb_printf("disk_read %10-d disk_write %10-d filesize %10-d\n",
- sd_shared.sh_disk_read, sd_shared.sh_disk_write,
- sd_shared.sh_filesize);
- mdb_printf("numdirty %8-d numio %8-d numfail %8-d\n",
- sd_shared.sh_numdirty,
- sd_shared.sh_numio,
- sd_shared.sh_numfail);
- mdb_printf("flushloop %2-d sh_flag <%b>\n",
- sd_shared.sh_flushloop, sd_shared.sh_flag, sh_flag_bits);
-
- /* this can be really verbose */
- if (cdi.cd_dirty_head) {
- mdb_printf("Dirty Chain (cd_dirty_head):");
- /* TODO reconstruct argv without opt_a */
- if (!opt_a)
- mdb_call_dcmd("sdbc_dchain",
- (uintptr_t)cdi.cd_dirty_head,
- flags, argc, argv);
- else /* print with no options */
- mdb_call_dcmd("sdbc_dchain",
- (uintptr_t)cdi.cd_dirty_head,
- flags, 0, NULL);
- }
-
- if (cdi.cd_io_head) {
- mdb_printf("I/O Pending Chain (cd_io_head):");
- /* TODO reconstruct argv without opt_a */
- if (!opt_a)
- mdb_call_dcmd("sdbc_dchain",
- (uintptr_t)cdi.cd_io_head,
- flags, argc, argv);
- else /* print with no options */
- mdb_call_dcmd("sdbc_dchain",
- (uintptr_t)cdi.cd_dirty_head,
- flags, 0, NULL);
- }
-
- if (cdi.cd_fail_head) {
- mdb_printf("Failed Chain (cd_fail_head):");
- /* TODO reconstruct argv without opt_a */
- if (!opt_a)
- mdb_call_dcmd("sdbc_dchain",
- (uintptr_t)cdi.cd_fail_head,
- flags, argc, argv);
- else /* print with no options */
- mdb_call_dcmd("sdbc_dchain",
- (uintptr_t)cdi.cd_dirty_head,
- flags, 0, NULL);
- }
- }
-
- mdb_dec_indent(4);
-
- mdb_printf("\n");
-
- return (DCMD_OK);
-}
-
-#ifdef SAFESTORE
-/*
- * dcmd to display fault tolerant control structures
- */
-static int
-sdbc_ftctl(uintptr_t addr, uint_t flags, int argc,
- const mdb_arg_t *argv)
-{
- _sd_ft_cctl_t ft_cent;
- ss_centry_info_t gl_info;
- ss_centry_info_t nv_gl_info;
- uintptr_t opt_c = MDB_CD;
- uint_t opt_d = FALSE;
- uint_t opt_v = FALSE;
-
-
- /* TODO option to select on fpos */
- if (mdb_getopts(argc, argv,
- 'd', MDB_OPT_SETBITS, TRUE, &opt_d,
- 'c', MDB_OPT_UINTPTR, &opt_c,
- 'v', MDB_OPT_SETBITS, TRUE, &opt_v) != argc)
- return (DCMD_USAGE);
-
-
- if (!(flags & DCMD_ADDRSPEC)) {
- if (mdb_walk_dcmd("sdbc`sdbc_ftctl", "sdbc`sdbc_ftctl",
- argc, argv) == -1) {
- mdb_warn("failed to walk write ctl array");
- return (DCMD_ERR);
- }
- return (DCMD_OK);
- }
-
- if (DCMD_HDRSPEC(flags)) {
- mdb_printf("Ft control block structures:\n");
- }
-
- if (mdb_vread(&ft_cent, sizeof (_sd_ft_cctl_t), addr) == -1) {
- mdb_warn("failed to read ft_cent at 0x%p", addr);
- return (DCMD_ERR);
- }
-
-
- /*
- * print "all" is the default.
- * filter conditions can only be checked by reading in wc_gl_info
- */
- if (opt_c || opt_d || opt_v)
- if (mdb_vread(&gl_info, sizeof (ss_centry_info_t),
- (uintptr_t)ft_cent.ft_gl_info) == -1) {
- mdb_warn("failed to read at wc_gl_info 0x%p", addr);
- return (DCMD_ERR);
- }
-
-
- if (OPT_C_SELECTED && (gl_info.gl_cd != opt_c))
- return (DCMD_OK);
-
- if (opt_d && !(gl_info.gl_dirty))
- return (DCMD_OK);
-
- mdb_inc_indent(4);
- mdb_printf("%-p data %?-p qnext %?-p\n",
- addr,
- ft_cent.ft_qnext,
- ft_cent.ft_data);
- mdb_printf("gl_info %?-p nvmem_gl_info %?-p\n",
- ft_cent.ft_gl_info,
- ft_cent.ft_nvmem_gl_info);
- mdb_dec_indent(4);
-
- /* verbose */
- if (!opt_v) {
- mdb_printf("\n");
- return (DCMD_OK);
- }
-
- mdb_inc_indent(4);
- mdb_printf(" gl_info: ");
- mdb_printf("cd %3-d fpos %10-d dirty %04x flag <%b>\n",
- gl_info.gl_cd, gl_info.gl_fpos, gl_info.gl_dirty & 0xffff,
- gl_info.gl_flag, cc_flag_bits);
-
- if (ft_cent.ft_nvmem_gl_info) {
- if (mdb_vread(&nv_gl_info, sizeof (ss_centry_info_t),
- (uintptr_t)ft_cent.ft_nvmem_gl_info) == -1) {
- mdb_warn("failed to read at ft_nvmem_gl_info 0x%p",
- ft_cent.ft_nvmem_gl_info); /* not catastophic, continue */
- } else {
- mdb_printf("nvmem_gl_info: ");
- mdb_printf("cd %3-d fpos %10-d dirty %04x flag <%b>\n",
- nv_gl_info.gl_cd, nv_gl_info.gl_fpos,
- nv_gl_info.gl_dirty & 0xffff,
- nv_gl_info.gl_flag, cc_flag_bits);
-
- /* consistency check */
- if (memcmp(&gl_info, &nv_gl_info, sizeof (ss_centry_info_t))
- != 0) {
- mdb_warn("nvram and host memory are NOT identical!");
- }
-
- }
- }
-
- mdb_dec_indent(4);
- mdb_printf("\n");
- return (DCMD_OK);
-}
-#endif /* SAFESTORE */
-
-
-/* dcmd to display buffer handles */
-static int
-sdbc_handles(uintptr_t addr, uint_t flags, int argc,
- const mdb_arg_t *argv)
-{
- uint_t opt_a = FALSE;
- uintptr_t opt_c = MDB_CD;
- uint_t opt_v = FALSE;
- uint_t opt_C = FALSE;
- _sd_buf_hlist_t hl;
- _sd_buf_handle_t bh;
-
-
- if (mdb_getopts(argc, argv,
- 'a', MDB_OPT_SETBITS, TRUE, &opt_a,
- 'c', MDB_OPT_UINTPTR, &opt_c,
- 'C', MDB_OPT_SETBITS, TRUE, &opt_C,
- 'v', MDB_OPT_SETBITS, TRUE, &opt_v) != argc)
- return (DCMD_USAGE);
-
-
- if (mdb_readvar(&hl, "_sd_handle_list") == -1) {
- mdb_warn("failed to read _sd_handle_list structure");
- return (DCMD_ERR);
- }
-
-
- if (!(flags & DCMD_ADDRSPEC)) {
- if (mdb_walk_dcmd("sdbc`sdbc_handles", "sdbc`sdbc_handles",
- argc, argv) == -1) {
- mdb_warn("failed to walk 'sdbc_handle_list'");
- return (DCMD_ERR);
- }
- return (DCMD_OK);
- }
-
- if (DCMD_HDRSPEC(flags)) {
- mdb_printf("Handle List Info:\n");
-
- mdb_inc_indent(4);
- mdb_printf("hl_top.bh_next: 0x%p\n", hl.hl_top.bh_next);
- mdb_printf("hl_lock: 0x%p (owner)\n", hl.hl_lock._opaque[0]);
- mdb_printf("hl_count: %hd\n", hl.hl_count);
- mdb_dec_indent(4);
- mdb_printf("buf handles:\n");
- }
-
- if (mdb_vread(&bh, sizeof (bh), addr) == -1) {
- mdb_warn("failed to read buf handle at 0x%p", addr);
- return (DCMD_ERR);
- }
-
- if (!opt_a && !(bh.bh_flag & (NSC_HALLOCATED | NSC_HACTIVE)))
- return (DCMD_OK);
-
- /*
- * may get false matches on cd option --
- * a cleared bh_cd field will match if user specified cd 0
- */
- if (OPT_C_SELECTED && (bh.bh_cd != opt_c))
- return (DCMD_OK);
-
- mdb_inc_indent(4);
- mdb_printf("%p %8T cd %3-d %4T<%b> %x\n", addr, bh.bh_cd,
- bh.bh_flag, nsc_buf_bits, bh.bh_flag);
-
- /* check for verbose, avoid printing twice */
- if (!opt_v && opt_C) {
- mdb_printf("cc_chain: ");
- if (bh.bh_centry)
- mdb_call_dcmd("sdbc`sdbc_cchain",
- (uintptr_t)bh.bh_centry, DCMD_ADDRSPEC, 0, NULL);
- }
-
- mdb_dec_indent(4);
-
- if (!opt_v)
- return (DCMD_OK);
-
- /* verbose */
- mdb_inc_indent(4);
-
- mdb_printf("callbacks: %-20a%-20a%-20a\n",
- bh.bh_disconnect_cb, bh.bh_read_cb, bh.bh_write_cb);
-
- mdb_printf("centry %?p %8T next %?p\n",
- bh.bh_centry, bh.bh_next);
- mdb_printf("buffer:\n");
-
- mdb_inc_indent(4);
- mdb_printf("fd 0x%p pos %10d len %6d flag 0x%x\n",
- bh.bh_buf.sb_fd, bh.bh_fba_pos, bh.bh_fba_len, bh.bh_flag);
-
- mdb_printf("alloc_thread %p busy_thread %p\n", bh.bh_alloc_thread,
- bh.bh_busy_thread);
-
- mdb_printf("err %4d %8T bh_vec 0x%p\n", bh.bh_error, bh.bh_vec);
- mdb_dec_indent(4);
-
- mdb_printf("bufvec (scatter gather list): %-?s %8T%-s\n",
- "ADDR", "LEN");
- {
- _sd_bufvec_t *bv, *endvec;
-
-
- /* todo check for (bh_vec != bh_bufvec) => readahead? */
-
- bv = bh.bh_bufvec;
- endvec = bv + _SD_MAX_BLKS;
- mdb_inc_indent(30);
- while (bv->bufaddr) {
- mdb_printf("%p %8T%d\n", bv->bufaddr, bv->buflen);
- ++bv;
- if (bv > endvec) {
- mdb_warn("END of bh_bufvec ARRAY");
- break;
- }
- }
- mdb_dec_indent(30);
- }
-
- if (opt_C) {
- mdb_printf("cc_chain: ");
- if (bh.bh_centry)
- mdb_call_dcmd("sdbc`sdbc_cchain",
- (uintptr_t)bh.bh_centry, DCMD_ADDRSPEC, 0, NULL);
- }
-
- mdb_dec_indent(4);
- mdb_printf("\n");
-
- return (DCMD_OK);
-}
-/*
- * dcmd to display ss_centry_info_t structures and
- * do optional consistency check with the nvram copy
- * if configured for nvram safe storage.
- */
-
-static int
-sdbc_glcinfo(uintptr_t addr, uint_t flags, int argc,
- const mdb_arg_t *argv)
-{
- ss_centry_info_t gl_centry_info;
- /* for doing consistency check */
-
- ss_centry_info_t *gl_centry_info_start;
- ss_centry_info_t *nv_gl_centry_info_start;
- uintptr_t nv_addr;
- ss_centry_info_t nv_gl_centry_info;
-
- /* options */
- uint_t opt_a = FALSE;
- uintptr_t opt_b = MDB_BLKNUM; /* fba pos match */
- uintptr_t opt_c = MDB_CD;
- uintptr_t opt_C = FALSE; /* consistency check */
- uint_t opt_d = FALSE;
-
-
-
- if (mdb_getopts(argc, argv,
- 'a', MDB_OPT_SETBITS, TRUE, &opt_a,
- 'b', MDB_OPT_UINTPTR, &opt_b,
- 'c', MDB_OPT_UINTPTR, &opt_c,
- 'C', MDB_OPT_SETBITS, TRUE, &opt_C,
- 'd', MDB_OPT_SETBITS, TRUE, &opt_d) != argc)
- return (DCMD_USAGE);
-
-
- if (!(flags & DCMD_ADDRSPEC)) {
- if (mdb_walk_dcmd("sdbc`sdbc_glcinfo", "sdbc`sdbc_glcinfo",
- argc, argv) == -1) {
- mdb_warn("failed to walk global centry info array");
- return (DCMD_ERR);
- }
- return (DCMD_OK);
- }
-
- if (DCMD_HDRSPEC(flags)) {
- mdb_printf("global cache entry info:\n");
- }
-
- if (mdb_vread(&gl_centry_info, sizeof (ss_centry_info_t), addr) == -1) {
- mdb_warn("failed to read gl_centry_info at 0x%p", addr);
- return (DCMD_ERR);
- }
-
-
- /*
- * default is to print entries initialized with a cd. return if
- * no options are selected and cd is invalid.
- */
- if (!opt_a && (!OPT_B_SELECTED) && (!OPT_C_SELECTED) && !opt_d &&
- (gl_centry_info.sc_cd == -1))
- return (DCMD_OK);
-
-
- /*
- * opt_c is exclusive filter. if opt_c is selected and there
- * is no match on the cd then return
- */
- if (!opt_a &&
- (OPT_C_SELECTED && (gl_centry_info.sc_cd != opt_c)))
- return (DCMD_OK);
-
- /*
- * opt_d and opt_b are inclusive. print if either one is chosen
- * and the selection condition is true.
- */
- if (opt_a ||
- (!opt_d && (!OPT_B_SELECTED)) || /* no options chosen */
- (opt_d && gl_centry_info.sc_dirty) ||
- (OPT_B_SELECTED && (gl_centry_info.sc_fpos == opt_b)))
- /*EMPTY*/;
- else
- return (DCMD_OK);
-
- mdb_inc_indent(4);
- mdb_printf("%?-p cd %3-d fpos %10-d dirty %04x flag <%b>\n",
- addr,
- gl_centry_info.sc_cd,
- gl_centry_info.sc_fpos,
- gl_centry_info.sc_dirty & 0xffff,
- gl_centry_info.sc_flag, cc_flag_bits);
-
- if (opt_C) {
- /* get start of the cache entry metadata */
- if (mdb_readvar(&gl_centry_info_start,
- "_sdbc_gl_centry_info") == -1) {
- mdb_warn("failed to read _sdbc_gl_centry_info");
- /* not catastrophic */
- goto end;
- }
-
- /* get start of the nvram copy cache entry metadata */
- if (mdb_readvar(&nv_gl_centry_info_start,
- "_sdbc_gl_centry_info_nvmem") == -1) {
- mdb_warn("failed to read _sdbc_gl_centry_info_nvmem");
- /* not catastrophic */
- goto end;
- }
-
- nv_addr = (addr - (uintptr_t)gl_centry_info_start) +
- (uintptr_t)nv_gl_centry_info_start;
-
- if (mdb_vread(&nv_gl_centry_info, sizeof (ss_centry_info_t),
- nv_addr) == -1) {
- mdb_warn("failed to read at nvmem_gl_info 0x%p",
- nv_addr);
- /* not catastophic, continue */
- } else {
-
- /* consistency check */
- mdb_inc_indent(4);
- if (memcmp(&gl_centry_info, &nv_gl_centry_info,
- sizeof (ss_centry_info_t) != 0)) {
- mdb_warn(
- "nvram and host memory are NOT identical!");
- mdb_printf("nvmem_gl_centry_info: ");
- mdb_printf(
- "%?-p cd %3-d fpos %10-d dirty %04x flag <%b>\n",
- nv_addr,
- nv_gl_centry_info.sc_cd,
- nv_gl_centry_info.sc_fpos,
- nv_gl_centry_info.sc_dirty & 0xffff,
- nv_gl_centry_info.sc_flag, cc_flag_bits);
- mdb_printf("\n");
- } else
- mdb_printf("NVRAM ok\n");
-
- mdb_dec_indent(4);
-
- }
- }
-
- end:
- mdb_dec_indent(4);
- return (DCMD_OK);
-}
-
-/*
- * dcmd to display ss_voldata_t structures and
- * do optional consistency check with the nvram copy
- * if configured for nvram safe storage.
- */
-
-static int
-sdbc_glfinfo(uintptr_t addr, uint_t flags, int argc,
- const mdb_arg_t *argv)
-{
- ss_voldata_t gl_file_info;
- /* for doing consistency check */
-
- ss_voldata_t *gl_file_info_start;
- ss_voldata_t *nv_gl_file_info_start;
- uintptr_t nv_addr;
- ss_voldata_t nv_gl_file_info;
-
- /* options default: valid filename */
- uint_t opt_a = FALSE; /* all */
- uint_t opt_p = FALSE; /* PINNED */
- uint_t opt_t = FALSE; /* attached */
- uint_t opt_C = FALSE; /* consistency check */
-
-
-
- /*
- * possible enhancement -- match on filename,
- * or filename part (e.g. controller number)
- */
- if (mdb_getopts(argc, argv,
- 'a', MDB_OPT_SETBITS, TRUE, &opt_a,
- 'C', MDB_OPT_SETBITS, TRUE, &opt_C,
- 'p', MDB_OPT_SETBITS, TRUE, &opt_p,
- 't', MDB_OPT_SETBITS, TRUE, &opt_t) != argc)
- return (DCMD_USAGE);
-
-
- if (!(flags & DCMD_ADDRSPEC)) {
- if (mdb_walk_dcmd("sdbc`sdbc_glfinfo", "sdbc`sdbc_glfinfo",
- argc, argv) == -1) {
- mdb_warn("failed to walk global file info array");
- return (DCMD_ERR);
- }
- return (DCMD_OK);
- }
-
- if (DCMD_HDRSPEC(flags)) {
- mdb_printf("global file entry info:\n");
- }
-
- if (mdb_vread(&gl_file_info, sizeof (ss_voldata_t), addr) == -1) {
- mdb_warn("failed to read gl_file_info at 0x%p", addr);
- return (DCMD_ERR);
- }
-
-
- /*
- * default is to print entries initialized with non-null filename.
- * return if no options are selected and filename is invalid.
- */
- if (!opt_a && !opt_p && !opt_t &&
- (strlen(gl_file_info.sv_volname) == 0))
- return (DCMD_OK);
-
-
- if (opt_a ||
- (!opt_p && !opt_t) || /* no options chosen */
- (opt_p && (gl_file_info.sv_pinned != _SD_NO_HOST)) ||
- (opt_t && (gl_file_info.sv_attached != _SD_NO_HOST)))
- /*EMPTY*/;
- else
- return (DCMD_OK);
-
- mdb_inc_indent(4);
- mdb_printf("%?-p %s\n", addr, gl_file_info.sv_volname);
- mdb_printf("pinned %2-d attached %2-d devidsz %3-d\n",
- gl_file_info.sv_pinned,
- gl_file_info.sv_attached,
- gl_file_info.sv_devidsz);
- mdb_printf("devid %s\n", gl_file_info.sv_devid);
-
- if (opt_C) {
- /* get start of the cache entry metadata */
- if (mdb_readvar(&gl_file_info_start,
- "_sdbc_gl_file_info") == -1) {
- mdb_warn("failed to read _sdbc_gl_file_info");
- /* not catastrophic */
- goto end;
- }
-
- /* get start of the nvram copy cache entry metadata */
- if (mdb_readvar(&nv_gl_file_info_start,
- "_sdbc_gl_file_info_nvmem") == -1) {
- mdb_warn("failed to read _sdbc_gl_file_info_nvmem");
- /* not catastrophic */
- goto end;
- }
-
- nv_addr = (addr - (uintptr_t)gl_file_info_start) +
- (uintptr_t)nv_gl_file_info_start;
-
- if (mdb_vread(&nv_gl_file_info, sizeof (ss_voldata_t),
- nv_addr) == -1) {
- mdb_warn("failed to read nvmem_gl_info at 0x%p",
- nv_addr);
- /* not catastophic, continue */
- } else {
-
- /* consistency check */
- mdb_inc_indent(4);
- if (memcmp(&gl_file_info, &nv_gl_file_info,
- sizeof (ss_centry_info_t) != 0)) {
- mdb_warn("nvram and host memory are NOT identical!");
- mdb_printf("nvmem_gl_file_info: ");
- mdb_printf("%?-p %s\n", nv_addr,
- nv_gl_file_info.sv_volname);
- mdb_printf("pinned %2-d attached %2-d devidsz %3-d\n",
- nv_gl_file_info.sv_pinned,
- nv_gl_file_info.sv_attached,
- nv_gl_file_info.sv_devidsz);
- mdb_printf("devid %s\n", nv_gl_file_info.sv_devid);
- } else
- mdb_printf("NVRAM ok\n");
-
- mdb_dec_indent(4);
-
- }
- }
-
- end:
- mdb_dec_indent(4);
- mdb_printf("\n");
- return (DCMD_OK);
-}
-
-
-/*
- * MDB module linkage information:
- *
- * We declare a list of structures describing our dcmds, and a function
- * named _mdb_init to return a pointer to our module information.
- */
-
-static const mdb_dcmd_t dcmds[] = {
- /* general dcmds */
- { "sdbc_config", NULL,
- "display sdbc configuration information",
- sdbc_config },
- { "sdbc_stats", NULL,
- "display sdbc stats information",
- sdbc_stats },
- { "sdbc_vars", NULL,
- "display some sdbc variables, counters and addresses",
- sdbc_vars },
-
- /* cctl dcmds */
- {"sdbc_cctl", "?[-vdhioV][-c cd][-b blknum]",
- "display sdbc cache ctl structures",
- sdbc_cctl, cctl_help },
- {"sdbc_cchain", ":[-vdhioV][-c cd][-b blknum]",
- "display cache ctl structure cc_chain",
- sdbc_cchain, cchain_help },
- {"sdbc_dchain", ":[-vdhioV][-c cd][-b blknum]",
- "display cache ctl structure dirty chain",
- sdbc_dchain, dchain_help },
- {"sdbc_dmchain", ":[-vdhioV][-c cd][-b blknum]",
- "display dynamic memory cache ctl chain",
- sdbc_dmchain, dmchain_help },
- {"sdbc_hashchain", ":[-vdhioV][-c cd][-b blknum]",
- "display a hash chain", sdbc_hashchain, hashchain_help },
- {"sdbc_hashtable", "?[-vdhioV][-c cd][-b blknum]",
- "display hash table", sdbc_hashtable, hashtable_help },
- {"sdbc_lru", "?[-vdhioV][-c cd][-b blknum]",
- "display the cache lru queue",
- sdbc_lru, lru_help },
-#ifdef SAFESTORE
- /* wctl dcmds */
- {"sdbc_wctl", "?[-vd][-c cd]",
- "display the write control structures",
- sdbc_wctl, wctl_help },
- {"sdbc_wrq", "?[-vd][-c cd]",
- "display the write control queue",
- sdbc_wrq, wrq_help },
-#endif /* SAFESTORE */
-
- /* others */
- {"sdbc_cdinfo", "?[-av][-c cd]",
- "display cache descriptor information",
- sdbc_cdinfo, cdinfo_help },
-#ifdef SAFESTORE
- {"sdbc_ftctl", "?[-vd][-c cd]",
- "display the fault tolerant control structures",
- sdbc_ftctl, ftctl_help },
-#endif /* SAFESTORE */
- {"sdbc_handles", "?[-avC][-c cd]",
- "display sdbc buffer handle information",
- sdbc_handles, handle_help },
-
- { "sdbc_dmqueues", NULL,
- "display sdbc dynamic memory buffer queues information",
- sdbc_dmqueues },
-
- /* "global" metadata dcmds */
- {"sdbc_glcinfo", "?[-adC][-c cd][-b fbapos]",
- "display the global cache entry info structures",
- sdbc_glcinfo, glcinfo_help },
- {"sdbc_glfinfo", "?[-aptC]",
- "display the global file info structures",
- sdbc_glfinfo, glfinfo_help },
- { NULL }
-};
-
-static const mdb_walker_t walkers[] = {
- /* walkers of cctl list and arrays */
- { "sdbc_cchain", "walk the cc_chain (alloc chain) of a cache ctl",
- sdbc_cchain_winit, sdbc_cchain_wstep, sdbc_cchain_wfini },
- { "sdbc_cctl", "walk the cache ctl structure list",
- sdbc_cctl_winit, sdbc_cctl_wstep, sdbc_cctl_wfini },
- { "sdbc_dchain", "walk the dirty chain of a cache ctl",
- sdbc_dchain_winit, sdbc_dchain_wstep, sdbc_dchain_wfini },
- { "sdbc_dmchain", "walk the dynamic memory chain of a cache cctl",
- sdbc_dmchain_winit, sdbc_dmchain_wstep, sdbc_dmchain_wfini },
- { "sdbc_hashchain", "walk a hash chain",
- sdbc_hashchain_winit, sdbc_hashchain_wstep,
- sdbc_hashchain_wfini },
- { "sdbc_lru", "walk the cache lru queue",
- sdbc_lru_winit, sdbc_lru_wstep, sdbc_lru_wfini },
-
-#ifdef SAFESTORE
- /* walkers of wctl lists and arrays */
- { "sdbc_wctl", "walk the allocated write ctl array",
- sdbc_wctl_winit, sdbc_wctl_wstep, sdbc_wctl_wfini },
- { "sdbc_wrq", "walk the write ctl queue (free list)",
- sdbc_wrq_winit, sdbc_wrq_wstep, sdbc_wrq_wfini },
-#endif /* SAFESTORE */
- /* others */
- { "sdbc_cdinfo",
- "walk the _sd_cache_files array of cache descriptor information",
- sdbc_cdinfo_winit, sdbc_cdinfo_wstep, sdbc_cdinfo_wfini },
-#ifdef SAFESTORE
- { "sdbc_ftctl",
- "walk the allocated array of fault tolerant structures",
- sdbc_ftctl_winit, sdbc_ftctl_wstep, sdbc_ftctl_wfini },
-#endif /* SAFESTORE */
- { "sdbc_handles", "walk array of _sd_buf_handle_t structures",
- sdbc_handle_winit, sdbc_handle_wstep, sdbc_handle_wfini },
-
- /* walkers for metadata arrays */
- { "sdbc_glcinfo", "walk the allocated global cache entry info array",
- sdbc_glcinfo_winit, sdbc_glcinfo_wstep, sdbc_glcinfo_wfini },
- { "sdbc_glfinfo", "walk the allocated global file info array",
- sdbc_glfinfo_winit, sdbc_glfinfo_wstep, sdbc_glfinfo_wfini },
- { NULL }
-};
-
-static const mdb_modinfo_t modinfo = {
- MDB_API_VERSION, dcmds, walkers
-};
-
-const mdb_modinfo_t *
-_mdb_init(void)
-{
- return (&modinfo);
-}
diff --git a/usr/src/cmd/mdb/common/modules/sv/Makefile.com b/usr/src/cmd/mdb/common/modules/sv/Makefile.com
deleted file mode 100644
index 40975cea69..0000000000
--- a/usr/src/cmd/mdb/common/modules/sv/Makefile.com
+++ /dev/null
@@ -1,24 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-CPPFLAGS += -DNSC_MULTI_TERABYTE
diff --git a/usr/src/cmd/mdb/common/modules/sv/sv.c b/usr/src/cmd/mdb/common/modules/sv/sv.c
deleted file mode 100644
index 5c6ab5924f..0000000000
--- a/usr/src/cmd/mdb/common/modules/sv/sv.c
+++ /dev/null
@@ -1,624 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/mdb_modapi.h>
-#include <sys/ddi.h>
-#include <sys/sunddi.h>
-#include <sys/sunldi.h>
-
-#include <sys/nsctl/nsctl.h>
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_k.h>
-
-#include <sys/nsctl/sv.h>
-#include <sys/nsctl/sv_impl.h>
-
-#include <sys/nsctl/nsvers.h>
-
-/*
- * Walker for an array of sv_dev_t structures.
- * A global walk is assumed to start at sv_devs.
- */
-
-struct sv_dev_winfo {
- uintptr_t start;
- uintptr_t end;
-};
-
-
-static int
-sv_dev_winit(mdb_walk_state_t *wsp)
-{
- struct sv_dev_winfo *winfo;
- sv_dev_t *sv_devs;
- int sv_max_devices;
-
- winfo = mdb_zalloc(sizeof (struct sv_dev_winfo), UM_SLEEP);
-
- if (mdb_readvar(&sv_devs, "sv_devs") == -1) {
- mdb_warn("failed to read 'sv_devs'");
- mdb_free(winfo, sizeof (struct sv_dev_winfo));
- return (WALK_ERR);
- }
-
- if (mdb_readvar(&sv_max_devices, "sv_max_devices") == -1) {
- mdb_warn("failed to read 'sv_max_devices'");
- mdb_free(winfo, sizeof (struct sv_dev_winfo));
- return (WALK_ERR);
- }
-
- winfo->start = (uintptr_t)sv_devs;
- winfo->end = (uintptr_t)(sv_devs + sv_max_devices);
-
- if (wsp->walk_addr == NULL)
- wsp->walk_addr = winfo->start;
-
- wsp->walk_data = winfo;
- return (WALK_NEXT);
-}
-
-
-static int
-sv_dev_wstep(mdb_walk_state_t *wsp)
-{
- struct sv_dev_winfo *winfo = wsp->walk_data;
- int status;
-
- if (wsp->walk_addr == NULL)
- return (WALK_DONE);
-
- if (wsp->walk_addr >= winfo->end)
- return (WALK_DONE);
-
- status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
- wsp->walk_cbdata);
-
- wsp->walk_addr += sizeof (sv_dev_t);
- return (status);
-}
-
-
-static void
-sv_dev_wfini(mdb_walk_state_t *wsp)
-{
- mdb_free(wsp->walk_data, sizeof (struct sv_dev_winfo));
-}
-
-
-/*
- * Walker for an sv hash chain.
- * Global walks are disallowed.
- */
-
-static int
-sv_hash_winit(mdb_walk_state_t *wsp)
-{
- if (wsp->walk_addr == NULL)
- return (WALK_ERR);
-
- wsp->walk_data = mdb_zalloc(sizeof (sv_dev_t), UM_SLEEP);
-
- return (WALK_NEXT);
-}
-
-
-static int
-sv_hash_wstep(mdb_walk_state_t *wsp)
-{
- int status;
-
- if (wsp->walk_addr == NULL)
- return (WALK_DONE);
-
- if (mdb_vread(wsp->walk_data,
- sizeof (sv_dev_t), wsp->walk_addr) == -1) {
- mdb_warn("failed to read sv_dev at %p", wsp->walk_addr);
- return (WALK_DONE);
- }
-
- status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
- wsp->walk_cbdata);
-
- wsp->walk_addr = (uintptr_t)(((sv_dev_t *)wsp->walk_data)->sv_hash);
- return (status);
-}
-
-
-static void
-sv_hash_wfini(mdb_walk_state_t *wsp)
-{
- mdb_free(wsp->walk_data, sizeof (sv_dev_t));
-}
-
-
-/*
- * Walker for an array of sv_maj_t structures.
- * A global walk is assumed to start at sv_majors.
- */
-
-sv_maj_t *sv_majors[SV_MAJOR_HASH_CNT + 1] = {0};
-
-static int
-sv_maj_winit(mdb_walk_state_t *wsp)
-{
- if (wsp->walk_addr == NULL) {
- if (mdb_readvar(&sv_majors, "sv_majors") == -1) {
- mdb_warn("failed to read 'sv_majors'");
- return (WALK_ERR);
- }
- } else {
- sv_majors[0] = (sv_maj_t *)wsp->walk_addr;
- }
-
- wsp->walk_addr = (uintptr_t)&sv_majors[0];
- wsp->walk_data = mdb_zalloc(sizeof (sv_maj_t), UM_SLEEP);
-
- return (WALK_NEXT);
-}
-
-
-static int
-sv_maj_wstep(mdb_walk_state_t *wsp)
-{
- uintptr_t addr;
- int status = DCMD_OK;
-
- if (wsp->walk_addr == NULL)
- return (WALK_DONE);
-
- if (wsp->walk_addr >= (uintptr_t)&sv_majors[SV_MAJOR_HASH_CNT])
- return (WALK_DONE);
-
- for (addr = *(uintptr_t *)wsp->walk_addr; addr;
- addr = (uintptr_t)(((sv_maj_t *)wsp->walk_data)->sm_next)) {
-
- if (mdb_vread(wsp->walk_data, sizeof (sv_maj_t), addr)
- != sizeof (sv_maj_t)) {
- mdb_warn("failed to read sv_maj at %p", addr);
- status = DCMD_ERR;
- break;
- }
-
- status = wsp->walk_callback(addr, wsp->walk_data,
- wsp->walk_cbdata);
- if (status != DCMD_OK)
- break;
- }
-
- wsp->walk_addr += sizeof (sv_maj_t *);
- return (status);
-}
-
-
-static void
-sv_maj_wfini(mdb_walk_state_t *wsp)
-{
- mdb_free(wsp->walk_data, sizeof (sv_maj_t));
-}
-
-
-/*
- * Walker for an sv gclient chain.
- * A global walk is assumed to start at sv_gclients.
- */
-
-static int
-sv_gclient_winit(mdb_walk_state_t *wsp)
-{
- if (wsp->walk_addr == NULL &&
- mdb_readvar(&wsp->walk_addr, "sv_gclients") == -1) {
- mdb_warn("unable to read 'sv_gclients'");
- return (WALK_ERR);
- }
-
- wsp->walk_data = mdb_zalloc(sizeof (sv_gclient_t), UM_SLEEP);
-
- return (WALK_NEXT);
-}
-
-
-static int
-sv_gclient_wstep(mdb_walk_state_t *wsp)
-{
- int status;
-
- if (wsp->walk_addr == NULL)
- return (WALK_DONE);
-
- if (mdb_vread(wsp->walk_data,
- sizeof (sv_gclient_t), wsp->walk_addr) == -1) {
- mdb_warn("failed to read sv_gclient at %p", wsp->walk_addr);
- return (WALK_DONE);
- }
-
- status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
- wsp->walk_cbdata);
-
- wsp->walk_addr = (uintptr_t)(((sv_gclient_t *)wsp->walk_data)->sg_next);
- return (status);
-}
-
-
-static void
-sv_gclient_wfini(mdb_walk_state_t *wsp)
-{
- mdb_free(wsp->walk_data, sizeof (sv_gclient_t));
-}
-
-
-/*
- * Display a single sv_glcient_t structure.
- * If called with no address, performs a global walk of all sv_gclients.
- */
-static int
-sv_gclient(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- sv_gclient_t sg;
- char name[64];
-
- if (argc != 0)
- return (DCMD_USAGE);
-
- if (!(flags & DCMD_ADDRSPEC)) {
- /*
- * paranoid mode on: qualify walker name with module name
- * using '`' syntax.
- */
- if (mdb_walk_dcmd("sv`sv_gclient",
- "sv`sv_gclient", argc, argv) == -1) {
- mdb_warn("failed to walk 'sv_gclient'");
- return (DCMD_ERR);
- }
- return (DCMD_OK);
- }
-
- if (mdb_vread(&sg, sizeof (sg), addr) != sizeof (sg)) {
- mdb_warn("failed to read sv_gclient at %p", addr);
- return (DCMD_ERR);
- }
-
- if (DCMD_HDRSPEC(flags)) {
- mdb_printf("%-?s %8T%-?s %8T%-16s %8T%s\n",
- "ADDR", "NEXT", "ID", "NAME");
- }
-
- if (mdb_readstr(name, sizeof (name), (uintptr_t)sg.sg_name) == -1) {
- mdb_warn("failed to read sv_gclient name at %p", addr);
- return (DCMD_ERR);
- }
-
- mdb_printf("%p %8T%p %8T%llx %8T%s",
- addr, sg.sg_next, sg.sg_id, name);
-
- return (DCMD_OK);
-}
-
-
-/*
- * Display a single sv_maj_t structure.
- * If called with no address, performs a global walk of all sv_majs.
- * -a : all (i.e. display all devices, even if disabled
- * -v : verbose
- */
-static int
-sv_maj(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- sv_maj_t *maj;
- int a_opt, v_opt;
- int i;
-
- a_opt = v_opt = FALSE;
-
- if (mdb_getopts(argc, argv,
- 'a', MDB_OPT_SETBITS, TRUE, &a_opt,
- 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc)
- return (DCMD_USAGE);
-
- if (!(flags & DCMD_ADDRSPEC)) {
- /*
- * paranoid mode on: qualify walker name with module name
- * using '`' syntax.
- */
- if (mdb_walk_dcmd("sv`sv_maj", "sv`sv_maj", argc, argv) == -1) {
- mdb_warn("failed to walk 'sv_maj'");
- return (DCMD_ERR);
- }
- return (DCMD_OK);
- }
-
- if (DCMD_HDRSPEC(flags)) {
- mdb_printf("%-?s %8T%s\n", "ADDR", "INUSE");
- }
-
- maj = mdb_zalloc(sizeof (*maj), UM_GC);
- if (mdb_vread(maj, sizeof (*maj), addr) != sizeof (*maj)) {
- mdb_warn("failed to read sv_maj at %p", addr);
- return (DCMD_ERR);
- }
-
- if (!a_opt && maj->sm_inuse == 0)
- return (DCMD_OK);
-
- mdb_printf("%?p %8T%d\n", addr, maj->sm_inuse);
-
- if (!v_opt)
- return (DCMD_OK);
-
- /*
- * verbose - print the rest of the structure as well.
- */
-
- mdb_inc_indent(4);
- mdb_printf("\n");
-
- mdb_printf("dev_ops: %a (%p)\n", maj->sm_dev_ops, maj->sm_dev_ops);
- mdb_printf("flag: %08x %8Tsequence: %d %8Tmajor: %d\n",
- maj->sm_flag, maj->sm_seq, maj->sm_major);
-
- mdb_printf("function pointers:\n");
- mdb_inc_indent(4);
- mdb_printf("%-20a%-20a%\n%-20a%-20a%\n%-20a%-20a%\n%-20a%-20a%\n",
- maj->sm_open, maj->sm_close,
- maj->sm_read, maj->sm_write,
- maj->sm_aread, maj->sm_awrite,
- maj->sm_strategy, maj->sm_ioctl);
- mdb_dec_indent(4);
-
-
- mdb_printf("hash chain:\n");
- mdb_inc_indent(4);
- for (i = 0; i < SV_MINOR_HASH_CNT; i++) {
- mdb_printf("%?p", maj->sm_hash[i]);
- mdb_printf(((i % 4) == 3) ? "\n" : " %8T");
- }
- mdb_printf("\n\n");
- mdb_dec_indent(4);
- mdb_dec_indent(4);
- return (DCMD_OK);
-}
-
-
-/*
- * Display a sv_dev_t hash chain.
- * Requires an address.
- * Same options as sv_dev().
- */
-static int
-sv_hash(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- if (!(flags & DCMD_ADDRSPEC))
- return (DCMD_USAGE);
-
- /*
- * paranoid mode on: qualify walker name with module name
- * using '`' syntax.
- */
- if (mdb_pwalk_dcmd("sv`sv_hash", "sv`sv_dev", argc, argv, addr) == -1) {
- mdb_warn("failed to walk sv_dev hash chain");
- return (DCMD_ERR);
- }
-
- return (DCMD_OK);
-}
-
-
-/*
- * Display a single sv_dev_t structure.
- * If called with no address, performs a global walk of all sv_devs.
- * -a : all (i.e. display all devices, even if disabled
- * -v : verbose
- */
-
-const mdb_bitmask_t sv_flag_bits[] = {
- { "NSC_DEVICE", NSC_DEVICE, NSC_DEVICE },
- { "NSC_CACHE", NSC_CACHE, NSC_CACHE },
- { NULL, 0, 0 }
-};
-
-static int
-sv_dev(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- sv_dev_t *svp;
- int a_opt, v_opt;
- int dev_t_chars;
-
- a_opt = v_opt = FALSE;
- dev_t_chars = sizeof (dev_t) * 2; /* # chars to display dev_t */
-
- if (mdb_getopts(argc, argv,
- 'a', MDB_OPT_SETBITS, TRUE, &a_opt,
- 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc)
- return (DCMD_USAGE);
-
- svp = mdb_zalloc(sizeof (*svp), UM_GC);
-
- if (!(flags & DCMD_ADDRSPEC)) {
- /*
- * paranoid mode on: qualify walker name with module name
- * using '`' syntax.
- */
- if (mdb_walk_dcmd("sv`sv_dev", "sv`sv_dev", argc, argv) == -1) {
- mdb_warn("failed to walk 'sv_dev'");
- return (DCMD_ERR);
- }
- return (DCMD_OK);
- }
-
- if (DCMD_HDRSPEC(flags)) {
- mdb_printf("%-?s %8T%-*s %8T%s\n", "ADDR",
- dev_t_chars, "DEV", "STATE");
- }
-
- if (mdb_vread(svp, sizeof (*svp), addr) != sizeof (*svp)) {
- mdb_warn("failed to read sv_dev at %p", addr);
- return (DCMD_ERR);
- }
-
- if (!a_opt && svp->sv_state == SV_DISABLE)
- return (DCMD_OK);
-
- mdb_printf("%?p %8T%0*lx %8T", addr, dev_t_chars, svp->sv_dev);
-
- if (svp->sv_state == SV_DISABLE)
- mdb_printf("disabled");
- else if (svp->sv_state == SV_PENDING)
- mdb_printf("pending");
- else if (svp->sv_state == SV_ENABLE)
- mdb_printf("enabled");
-
- mdb_printf("\n");
-
- if (!v_opt)
- return (DCMD_OK);
-
- /*
- * verbose - print the rest of the structure as well.
- */
-
- mdb_inc_indent(4);
- mdb_printf("\n");
-
- mdb_printf("hash chain: 0x%p %8Tlock: 0x%p %8Tolock: 0x%p\n",
- svp->sv_hash,
- addr + OFFSETOF(sv_dev_t, sv_lock),
- addr + OFFSETOF(sv_dev_t, sv_olock));
-
- mdb_printf("fd: 0x%p %8T\n", svp->sv_fd);
-
- mdb_printf("maxfbas: %d %8Tnblocks: %d %8Tstate: %d\n",
- svp->sv_maxfbas, svp->sv_nblocks, svp->sv_state);
-
- mdb_printf("gclients: 0x%llx %8Tgkernel: 0x%llx\n",
- svp->sv_gclients, svp->sv_gkernel);
-
- mdb_printf("openlcnt: %d %8Ttimestamp: 0x%lx\n",
- svp->sv_openlcnt, svp->sv_timestamp);
-
- mdb_printf("flags: 0x%08x <%b>\n",
- svp->sv_flag, svp->sv_flag, sv_flag_bits);
-
- mdb_printf("lh: 0x%p %8Tpending: 0x%p\n",
- svp->sv_lh, svp->sv_pending);
-
- mdb_dec_indent(4);
- return (DCMD_OK);
-}
-
-
-/*
- * Display general sv module information.
- */
-
-#define sv_get_print(kvar, str, fmt, val) \
- if (mdb_readvar(&(val), #kvar) == -1) { \
- mdb_dec_indent(4); \
- mdb_warn("unable to read '" #kvar "'"); \
- return (DCMD_ERR); \
- } \
- mdb_printf("%-20s" fmt "\n", str ":", val)
-
-/* ARGSUSED */
-static int
-sv(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- clock_t clock;
- int maj, min, mic, baseline, i;
-
- if (argc != 0)
- return (DCMD_USAGE);
-
- if (mdb_readvar(&maj, "sv_major_rev") == -1) {
- mdb_warn("unable to read 'sv_major_rev'");
- return (DCMD_ERR);
- }
-
- if (mdb_readvar(&min, "sv_minor_rev") == -1) {
- mdb_warn("unable to read 'sv_minor_rev'");
- return (DCMD_ERR);
- }
-
- if (mdb_readvar(&mic, "sv_micro_rev") == -1) {
- mdb_warn("unable to read 'sv_micro_rev'");
- return (DCMD_ERR);
- }
-
- if (mdb_readvar(&baseline, "sv_baseline_rev") == -1) {
- mdb_warn("unable to read 'sv_baseline_rev'");
- return (DCMD_ERR);
- }
-
- mdb_printf("SV module version: kernel %d.%d.%d.%d; mdb %d.%d.%d.%d\n",
- maj, min, mic, baseline,
- ISS_VERSION_MAJ, ISS_VERSION_MIN, ISS_VERSION_MIC, ISS_VERSION_NUM);
- mdb_inc_indent(4);
-
- sv_get_print(sv_config_time, "last config time", "0x%lx", clock);
- sv_get_print(sv_stats_on, "stats on", "%d", i);
- sv_get_print(sv_debug, "debug", "%d", i);
- sv_get_print(sv_max_devices, "max sv devices", "%d", i);
-
- mdb_dec_indent(4);
- return (DCMD_OK);
-}
-
-
-/*
- * MDB module linkage information:
- */
-
-static const mdb_dcmd_t dcmds[] = {
- { "sv", NULL, "display sv module info", sv },
- { "sv_dev", "?[-av]", "list sv_dev structure", sv_dev },
- { "sv_gclient", "?", "list sv_gclient structure", sv_gclient },
- { "sv_hash", ":[-av]", "display sv_dev hash chain", sv_hash },
- { "sv_maj", "?[-av]", "list sv_maj structure", sv_maj },
- { NULL }
-};
-
-
-static const mdb_walker_t walkers[] = {
- { "sv_dev", "walk array of sv_dev structures",
- sv_dev_winit, sv_dev_wstep, sv_dev_wfini },
- { "sv_gclient", "walk sb_gclient chain",
- sv_gclient_winit, sv_gclient_wstep, sv_gclient_wfini },
- { "sv_hash", "walk sv_dev hash chain",
- sv_hash_winit, sv_hash_wstep, sv_hash_wfini },
- { "sv_maj", "walk array of sv_maj structures",
- sv_maj_winit, sv_maj_wstep, sv_maj_wfini },
- { NULL }
-};
-
-
-static const mdb_modinfo_t modinfo = {
- MDB_API_VERSION, dcmds, walkers
-};
-
-
-const mdb_modinfo_t *
-_mdb_init(void)
-{
- return (&modinfo);
-}
diff --git a/usr/src/cmd/mdb/intel/amd64/ii/Makefile b/usr/src/cmd/mdb/intel/amd64/ii/Makefile
deleted file mode 100644
index 5aa8957b11..0000000000
--- a/usr/src/cmd/mdb/intel/amd64/ii/Makefile
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-MODULE = ii.so
-MDBTGT = kvm
-
-MODSRCS = ii.c
-
-include ../../../../Makefile.cmd
-include ../../../../Makefile.cmd.64
-include ../../Makefile.amd64
-include ../../../Makefile.module
-include ../../../common/modules/ii/Makefile.com
diff --git a/usr/src/cmd/mdb/intel/amd64/nsctl/Makefile b/usr/src/cmd/mdb/intel/amd64/nsctl/Makefile
deleted file mode 100644
index 40a0400919..0000000000
--- a/usr/src/cmd/mdb/intel/amd64/nsctl/Makefile
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-MODULE = nsctl.so
-MDBTGT = kvm
-
-MODSRCS = nsctl.c
-
-include ../../../../Makefile.cmd
-include ../../../../Makefile.cmd.64
-include ../../Makefile.amd64
-include ../../../Makefile.module
-include ../../../common/modules/nsctl/Makefile.com
diff --git a/usr/src/cmd/mdb/intel/amd64/rdc/Makefile b/usr/src/cmd/mdb/intel/amd64/rdc/Makefile
deleted file mode 100644
index e9dd4a514c..0000000000
--- a/usr/src/cmd/mdb/intel/amd64/rdc/Makefile
+++ /dev/null
@@ -1,38 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-MODULE = rdc.so
-MDBTGT = kvm
-
-MODSRCS = rdc.c
-
-include ../../../../Makefile.cmd
-include ../../../../Makefile.cmd.64
-include ../../Makefile.amd64
-include ../../../Makefile.module
-include ../../../common/modules/rdc/Makefile.com
-CPPFLAGS += -erroff=E_STATIC_UNUSED
-
-CERRWARN += -_gcc=-Wno-unused-function
diff --git a/usr/src/cmd/mdb/intel/amd64/sdbc/Makefile b/usr/src/cmd/mdb/intel/amd64/sdbc/Makefile
deleted file mode 100644
index a6a4f78b49..0000000000
--- a/usr/src/cmd/mdb/intel/amd64/sdbc/Makefile
+++ /dev/null
@@ -1,38 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-MODULE = sdbc.so
-MDBTGT = kvm
-
-AVSBASE = ../../../../../uts/common/avs
-
-MODSRCS = sdbc.c
-
-include ../../../../Makefile.cmd
-include ../../../../Makefile.cmd.64
-include ../../Makefile.amd64
-include ../../../Makefile.module
-include ../../../common/modules/sdbc/Makefile.com
-CPPFLAGS += -I$(AVSBASE)
diff --git a/usr/src/cmd/mdb/intel/amd64/sv/Makefile b/usr/src/cmd/mdb/intel/amd64/sv/Makefile
deleted file mode 100644
index 626e54c59d..0000000000
--- a/usr/src/cmd/mdb/intel/amd64/sv/Makefile
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-MODULE = sv.so
-MDBTGT = kvm
-
-MODSRCS = sv.c
-
-include ../../../../Makefile.cmd
-include ../../../../Makefile.cmd.64
-include ../../Makefile.amd64
-include ../../../Makefile.module
-include ../../../common/modules/sv/Makefile.com
diff --git a/usr/src/cmd/mdb/intel/ia32/ii/Makefile b/usr/src/cmd/mdb/intel/ia32/ii/Makefile
deleted file mode 100644
index 6e8855c023..0000000000
--- a/usr/src/cmd/mdb/intel/ia32/ii/Makefile
+++ /dev/null
@@ -1,34 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-MODULE = ii.so
-MDBTGT = kvm
-
-MODSRCS = ii.c
-
-include ../../../../Makefile.cmd
-include ../../Makefile.ia32
-include ../../../Makefile.module
-include ../../../common/modules/ii/Makefile.com
diff --git a/usr/src/cmd/mdb/intel/ia32/nsctl/Makefile b/usr/src/cmd/mdb/intel/ia32/nsctl/Makefile
deleted file mode 100644
index a361fbe67e..0000000000
--- a/usr/src/cmd/mdb/intel/ia32/nsctl/Makefile
+++ /dev/null
@@ -1,34 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-MODULE = nsctl.so
-MDBTGT = kvm
-
-MODSRCS = nsctl.c
-
-include ../../../../Makefile.cmd
-include ../../Makefile.ia32
-include ../../../Makefile.module
-include ../../../common/modules/nsctl/Makefile.com
diff --git a/usr/src/cmd/mdb/intel/ia32/rdc/Makefile b/usr/src/cmd/mdb/intel/ia32/rdc/Makefile
deleted file mode 100644
index 63d95aefb3..0000000000
--- a/usr/src/cmd/mdb/intel/ia32/rdc/Makefile
+++ /dev/null
@@ -1,37 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-MODULE = rdc.so
-MDBTGT = kvm
-
-MODSRCS = rdc.c
-
-include ../../../../Makefile.cmd
-include ../../Makefile.ia32
-include ../../../Makefile.module
-include ../../../common/modules/rdc/Makefile.com
-CPPFLAGS += -erroff=E_STATIC_UNUSED
-
-CERRWARN += -_gcc=-Wno-unused-function
diff --git a/usr/src/cmd/mdb/intel/ia32/sdbc/Makefile b/usr/src/cmd/mdb/intel/ia32/sdbc/Makefile
deleted file mode 100644
index 359088f689..0000000000
--- a/usr/src/cmd/mdb/intel/ia32/sdbc/Makefile
+++ /dev/null
@@ -1,37 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-MODULE = sdbc.so
-MDBTGT = kvm
-
-AVSBASE = ../../../../../uts/common/avs
-
-MODSRCS = sdbc.c
-
-include ../../../../Makefile.cmd
-include ../../Makefile.ia32
-include ../../../Makefile.module
-include ../../../common/modules/sdbc/Makefile.com
-CPPFLAGS += -I$(AVSBASE)
diff --git a/usr/src/cmd/mdb/intel/ia32/sv/Makefile b/usr/src/cmd/mdb/intel/ia32/sv/Makefile
deleted file mode 100644
index 0636b1f0bb..0000000000
--- a/usr/src/cmd/mdb/intel/ia32/sv/Makefile
+++ /dev/null
@@ -1,34 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-MODULE = sv.so
-MDBTGT = kvm
-
-MODSRCS = sv.c
-
-include ../../../../Makefile.cmd
-include ../../Makefile.ia32
-include ../../../Makefile.module
-include ../../../common/modules/sv/Makefile.com
diff --git a/usr/src/cmd/mdb/sparc/v9/ii/Makefile b/usr/src/cmd/mdb/sparc/v9/ii/Makefile
deleted file mode 100644
index dffc51365c..0000000000
--- a/usr/src/cmd/mdb/sparc/v9/ii/Makefile
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-MODULE = ii.so
-MDBTGT = kvm
-
-MODSRCS = ii.c
-
-include ../../../../Makefile.cmd
-include ../../../../Makefile.cmd.64
-include ../../Makefile.sparcv9
-include ../../../Makefile.module
-include ../../../common/modules/ii/Makefile.com
diff --git a/usr/src/cmd/mdb/sparc/v9/nsctl/Makefile b/usr/src/cmd/mdb/sparc/v9/nsctl/Makefile
deleted file mode 100644
index a7209d9313..0000000000
--- a/usr/src/cmd/mdb/sparc/v9/nsctl/Makefile
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-MODULE = nsctl.so
-MDBTGT = kvm
-
-MODSRCS = nsctl.c
-
-include ../../../../Makefile.cmd
-include ../../../../Makefile.cmd.64
-include ../../Makefile.sparcv9
-include ../../../Makefile.module
-include ../../../common/modules/nsctl/Makefile.com
diff --git a/usr/src/cmd/mdb/sparc/v9/rdc/Makefile b/usr/src/cmd/mdb/sparc/v9/rdc/Makefile
deleted file mode 100644
index 5810ed3fb0..0000000000
--- a/usr/src/cmd/mdb/sparc/v9/rdc/Makefile
+++ /dev/null
@@ -1,38 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-MODULE = rdc.so
-MDBTGT = kvm
-
-MODSRCS = rdc.c
-
-include ../../../../Makefile.cmd
-include ../../../../Makefile.cmd.64
-include ../../Makefile.sparcv9
-include ../../../Makefile.module
-include ../../../common/modules/rdc/Makefile.com
-CPPFLAGS += -erroff=E_STATIC_UNUSED
-
-CERRWARN += -_gcc=-Wno-unused-function
diff --git a/usr/src/cmd/mdb/sparc/v9/sdbc/Makefile b/usr/src/cmd/mdb/sparc/v9/sdbc/Makefile
deleted file mode 100644
index c7d6108028..0000000000
--- a/usr/src/cmd/mdb/sparc/v9/sdbc/Makefile
+++ /dev/null
@@ -1,38 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-MODULE = sdbc.so
-MDBTGT = kvm
-
-AVSBASE = ../../../../../uts/common/avs
-
-MODSRCS = sdbc.c
-
-include ../../../../Makefile.cmd
-include ../../../../Makefile.cmd.64
-include ../../Makefile.sparcv9
-include ../../../Makefile.module
-include ../../../common/modules/sdbc/Makefile.com
-CPPFLAGS += -I$(AVSBASE)
diff --git a/usr/src/cmd/mdb/sparc/v9/sv/Makefile b/usr/src/cmd/mdb/sparc/v9/sv/Makefile
deleted file mode 100644
index 431b217cee..0000000000
--- a/usr/src/cmd/mdb/sparc/v9/sv/Makefile
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-MODULE = sv.so
-MDBTGT = kvm
-
-MODSRCS = sv.c
-
-include ../../../../Makefile.cmd
-include ../../../../Makefile.cmd.64
-include ../../Makefile.sparcv9
-include ../../../Makefile.module
-include ../../../common/modules/sv/Makefile.com
diff --git a/usr/src/head/Makefile b/usr/src/head/Makefile
index e5cd6e1ef0..e9beffdf71 100644
--- a/usr/src/head/Makefile
+++ b/usr/src/head/Makefile
@@ -128,7 +128,6 @@ HDRS= $($(MACH)_HDRS) \
nl_types.h \
nlist.h \
note.h \
- nsctl.h \
nsswitch.h \
nss_common.h \
nss_dbdefs.h \
diff --git a/usr/src/head/nsctl.h b/usr/src/head/nsctl.h
deleted file mode 100644
index ccfd6b71aa..0000000000
--- a/usr/src/head/nsctl.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2014 Garrett D'Amore <garrett@damore.org>
- *
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _NSCTL_H
-#define _NSCTL_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/nsctl/nsctl.h>
-
-
-/*
- * External file descriptor.
- */
-
-#ifndef _LIBNSCTL_H
-#ifndef _KMEMUSER
-typedef struct nsc_fd_s { int x; } nsc_fd_t;
-#endif
-#endif
-
-
-/*
- * Runtime Solaris release checking.
- *
- * nsc_check_release() is called with the string build release
- * (BUILD_REV_STR) and an optional array of nsc_release_t. The array
- * defines a map of build release to acceptable runtime release for the
- * component. The build release is always an acceptable runtime
- * release and need not be included in the map.
- *
- * build - the build release (e.g. "5.7")
- * runtime - comma &/or space separated list of acceptable runtime
- * releases (e.g. "5.7, 5.8")
- */
-
-typedef struct nsc_release {
- const char *build; /* build release */
- const char *runtime; /* runtime release(s) */
-} nsc_release_t;
-
-extern void _nsc_nocheck(void);
-extern nsc_fd_t *nsc_open(char *, int, int);
-extern nsc_fd_t *nsc_fdopen(int, char *, int);
-extern int nsc_close(nsc_fd_t *);
-extern int nsc_fileno(nsc_fd_t *);
-extern int nsc_reserve(nsc_fd_t *);
-extern int nsc_release(nsc_fd_t *);
-extern int nsc_partsize(nsc_fd_t *, nsc_size_t *);
-extern int nsc_freeze(char *path);
-extern int nsc_unfreeze(char *path);
-extern int nsc_isfrozen(char *path);
-extern int nsc_getsystemid(int *id);
-extern int nsc_name_to_id(char *name, int *id);
-extern int nsc_id_to_name(char **name, int id);
-extern int nsc_check_release(const char *, nsc_release_t *, char **);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _NSCTL_H */
diff --git a/usr/src/lib/Makefile b/usr/src/lib/Makefile
index 35b35800e8..90cffe62f7 100644
--- a/usr/src/lib/Makefile
+++ b/usr/src/lib/Makefile
@@ -117,7 +117,6 @@ SUBDIRS += \
libdlpi \
libdns_sd \
libdoor \
- libdscfg \
libdtrace \
libdtrace_jni \
libefi \
@@ -169,7 +168,6 @@ SUBDIRS += \
libndmp \
libnisdb \
libnls \
- libnsctl \
libnwam \
libofmt \
libpam \
@@ -185,7 +183,6 @@ SUBDIRS += \
libpthread \
libraidcfg \
librcm \
- librdc \
libreparse \
libresolv \
libresolv2 \
@@ -227,7 +224,6 @@ SUBDIRS += \
libtsnet \
libtsol \
libumem \
- libunistat \
libuuid \
libuutil \
libvolmgt \
@@ -392,7 +388,6 @@ HDRSUBDIRS= \
libdll \
libdlpi \
libdns_sd \
- libdscfg \
libdtrace \
libdtrace_jni \
libelfsign \
@@ -425,7 +420,6 @@ HDRSUBDIRS= \
libmlrpc \
libmtmalloc \
libndmp \
- libnsctl \
libnsl \
libnvpair \
libnwam \
@@ -440,7 +434,6 @@ HDRSUBDIRS= \
libproc \
libraidcfg \
librcm \
- librdc \
libreparse \
librestart \
librpcsvc \
@@ -473,7 +466,6 @@ HDRSUBDIRS= \
libtsnet \
libtsol \
libumem \
- libunistat \
libuutil \
libvolmgt \
libvrrpadm \
@@ -603,7 +595,6 @@ libdladm: libdevinfo libinetutil libscf librcm libexacct libkstat \
libdll: libast
libdlpi: libinetutil libdladm
libds: libsysevent
-libdscfg: libnsctl libunistat libadm
libdtrace: libproc libgen libctf libmapmalloc
libdtrace_jni: libuutil libdtrace
libefi: libuuid libsmbios
@@ -643,7 +634,6 @@ libproject: libpool libproc libsecdb
libprtdiag: libkstat
libprtdiag_psr: libprtdiag
libraidcfg: libdevinfo
-librdc: libnsctl libunistat libdscfg
librestart: libuutil libscf libpool libproject libsecdb libsysevent
libsasl: libgss pkcs11
libsaveargs: libdisasm
diff --git a/usr/src/lib/libdscfg/Makefile b/usr/src/lib/libdscfg/Makefile
deleted file mode 100644
index 8516e90e12..0000000000
--- a/usr/src/lib/libdscfg/Makefile
+++ /dev/null
@@ -1,64 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-include ../Makefile.lib
-
-HDRS= cfg.h\
- cfg_cluster.h\
- cfg_impl.h\
- cfg_lockd.h
-HDRDIR= common
-
-SUBDIRS= $(MACH)
-
-ROOTDIR= $(ROOT)/usr/include/sys/nsctl
-
-ROOTHDRS= $(HDRS:%=$(ROOTDIR)/%)
-
-all := TARGET= all
-clean := TARGET= clean
-clobber := TARGET= clobber
-install := TARGET= install
-lint := TARGET= lint
-_msg := TARGET= _msg
-
-.KEEP_STATE:
-
-all clean clobber install lint: $(SUBDIRS)
-
-$(MACH): FRC
- @cd $@; pwd; $(MAKE) $(TARGET)
-
-install_h: $(ROOTDIR) $(ROOTHDRS)
-
-check: $(CHECKHDRS)
-
-$(ROOTDIR)/%: common/%
- $(INS.file)
-
-$(ROOTDIR):
- $(INS.dir)
-
-
-FRC:
diff --git a/usr/src/lib/libdscfg/Makefile.com b/usr/src/lib/libdscfg/Makefile.com
deleted file mode 100644
index b12fb3a2b8..0000000000
--- a/usr/src/lib/libdscfg/Makefile.com
+++ /dev/null
@@ -1,74 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-LIBRARY= libdscfg.a
-VERS= .1
-
-OBJECTS= \
- cfg.o \
- cfg_cluster.o \
- cfg_local.o \
- cfg_lockdlck.o \
- cfg_lockdmsg.o \
- cfg_vols.o
-
-
-# include library definitions
-include ../../Makefile.lib
-
-SRCDIR= ../common
-SRCS= $(OBJECTS:%.o=../common/%.c)
-
-LIBS += $(DYNLIB) $(LINTLIB)
-
-# definitions for lint
-
-LINTFLAGS += -u
-LINTFLAGS += -erroff=E_FUNC_RET_ALWAYS_IGNOR2
-LINTFLAGS += -erroff=E_FUNC_RET_MAYBE_IGNORED2
-LINTFLAGS += -erroff=E_FUNC_SET_NOT_USED
-LINTFLAGS += -erroff=E_SEC_SCANF_UNBOUNDED_COPY
-LINTFLAGS += -erroff=E_BAD_FORMAT_ARG_TYPE2
-LINTOUT= lint.out
-LINTOUT_INTER= lintinter.out
-
-CERRWARN += -_gcc=-Wno-parentheses
-CERRWARN += -_gcc=-Wno-unused-function
-CERRWARN += -_gcc=-Wno-unused-variable
-CERRWARN += -_gcc=-Wno-uninitialized
-CERRWARN += -_gcc=-Wno-address
-
-ROOTLINTDIR= $(ROOTLIBDIR)
-ROOTLINT= $(LINTSRC:%=$(ROOTLINTDIR)/%)
-
-CLEANFILES += $(LINTOUT) $(LINTOUT_INTER) $(LINT_INTER)
-
-LDLIBS += -lnsctl -lunistat -ladm -lsocket -lnsl -lc
-
-.KEEP_STATE:
-
-lint: lintcheck
-
-# include library targets
-include ../../Makefile.targ
diff --git a/usr/src/lib/libdscfg/common/cfg.c b/usr/src/lib/libdscfg/common/cfg.c
deleted file mode 100644
index 17f668744a..0000000000
--- a/usr/src/lib/libdscfg/common/cfg.c
+++ /dev/null
@@ -1,3585 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <stdio.h>
-
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <stdio.h>
-#include <sys/mnttab.h>
-#include <sys/vtoc.h>
-#include <errno.h>
-#include <limits.h>
-#include <fcntl.h>
-#include <string.h>
-#include <stdarg.h>
-#include <strings.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-
-#include <locale.h>
-#include <langinfo.h>
-#include <libintl.h>
-#include <stdarg.h>
-#include <netdb.h>
-#include <ctype.h>
-#include <sys/stat.h>
-#include <sys/utsname.h>
-
-#include "cfg_impl.h"
-#include "cfg.h"
-#include "cfg_lockd.h"
-
-#if 0
-#define DEBUG_CFGLIST
-#define DEBUG_EXTRA
-#define DEBUG_LIB
-#define DEBUG_NOISY
-#define DEBUG_OUT
-#endif
-
-#define MAX_CFG 16 /* Max. number of lines in /etc/dscfg_format */
-#define MAX_SET 12 /* number of chars in a set name */
-
-
-/* parser tree for config section */
-static struct parser chead[MAX_CFG] = { NULL };
-static int chead_loaded = 0;
-static char config_file[CFG_MAX_BUF];
-static char dectohex[] = { '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
-#define CHARS_TO_ENCODE "=;\t "
-#define min(a, b) ((a) > (b) ? (b) : (a))
-
-/* field to be sorted on in sorting routines */
-static struct sortby_s {
- char section[CFG_MAX_KEY];
- char field[CFG_MAX_KEY];
- int offset;
- int comperror;
-} sortby;
-
-int cfg_severity = 0;
-char *cfg_perror_str;
-static int cfg_read(cfp_t *);
-static void cfg_read_parser_config(cfp_t *);
-static int cfg_rdlock(CFGFILE *);
-static int cfg_wrlock(CFGFILE *);
-static int cfg_lockd;
-void cfg_replace_lists(cfp_t *);
-void cfg_free_parser_tree();
-void cfg_invalidate_hsizes(int, const char *);
-int cfg_map_cfglists(cfp_t *);
-int cfg_hdrcmp(cfp_t *);
-void cfg_free_cfglist(cfp_t *);
-
-extern cfg_io_t *cfg_block_io_provider(void);
-extern cfg_io_t *cfg_raw_io_provider(void);
-extern int cl_initialized;
-
-#ifdef DEBUG_LIB
-static void
-dump_status(cfp_t *cfp, char *str)
-{
- printf("called from %s\n", str);
- printf(gettext("Header info:\n"
- "\tmagic: %x\tstate: %x\n"),
- cfp->cf_head->h_magic, cfp->cf_head->h_state);
- printf(gettext("Parser section:\n"
- "Start: %x\tsize: %d\toffset: %d\n"),
- cfp->cf_mapped, cfp->cf_head->h_parsesize,
- cfp->cf_head->h_parseoff);
- printf(gettext("Config section:\n"
- "Start: %x\tsize:%d\tacsize: %d\n"),
- cfp->cf_head->h_cparse, cfp->cf_head->h_csize,
- cfp->cf_head->h_acsize);
- printf("\n\tccopy1: %x\tccopy2: %x\n",
- cfp->cf_head->h_ccopy1, cfp->cf_head->h_ccopy2);
- printf(gettext("Sequence:\n"
- "\tseq1: %d\t\tseq2: %d\n"),
- cfp->cf_head->h_seq1, cfp->cf_head->h_seq2);
-}
-#endif /* DEBUG */
-
-/*
- * cfg_get_item
- * return position from parser config given tag and field
- */
-static int
-cfg_get_item(struct parser *tbl, const char *tag, const char *field)
-{
- int i;
- struct lookup *p;
-
- for (i = 0; i < MAX_CFG; i++) {
- /* only as many lists as defined */
- if (tbl[i].tag.l_word[0] == '\0') {
- i = MAX_CFG;
- break;
- }
- if (strcmp(tbl[i].tag.l_word, tag) == 0)
- break;
- }
-
- /* Handle table size */
- if (i < MAX_CFG) {
- p = tbl[i].fld;
- while (p) {
- if (strcmp(p->l_word, field) == 0)
- return (p->l_value);
- p = p->l_next;
- }
- }
-
- /* Handle failure */
- return (-1);
-}
-
-/*
- * cfg_get_num_flds
- * return number of fields for given parser tag
- */
-static int
-cfg_get_num_flds(struct parser *tbl, const char *tag, int *table_index)
-{
- int i;
- int pos = 0;
- struct lookup *p;
-
- for (i = 0; i < MAX_CFG; i++) {
- /* only as many lists as defined */
- if (tbl[i].tag.l_word[0] == '\0') {
- i = MAX_CFG;
- break;
- }
- if (strcmp(tbl[i].tag.l_word, tag) == 0) {
- *table_index = i;
- break;
- }
- }
-
- /* Handle table size */
- if (i < MAX_CFG) {
- p = tbl[i].fld;
- while (p) {
- pos++;
- p = p->l_next;
- }
- return (pos);
- }
-
- return (0);
-}
-
-/*
- * count white space fields
- */
-static int
-cfg_cnt_flds(char *value)
-{
- char *ptr;
- char buf[CFG_MAX_BUF];
- int flds = 0;
-
- if ((value == NULL) || (strlen(value) >= CFG_MAX_BUF))
- return (0);
-
- bzero(buf, CFG_MAX_BUF);
- strcpy(buf, value);
- ptr = strtok(buf, " ");
- while (ptr) {
- flds++;
- ptr = strtok(NULL, " ");
- }
- return (flds);
-}
-
-/*
- * cfg_get_parser_offset
- * returns the index for each
- * section of the parser..
- * ie. parser info for sndr is chead[3].tag.l_word
- * this will help us find sndr quicker, as the
- * the memory picture of the sets mimic this ordering
- */
-static int
-cfg_get_parser_offset(const char *section)
-{
- int i;
-
- for (i = 0; i < MAX_CFG; i++) {
- /* only as many lists as defined */
- if (chead[i].tag.l_word[0] == '\0') {
- i = MAX_CFG;
- break;
- }
- if (strcmp(chead[i].tag.l_word, section) == 0)
- break;
- }
-
- /* Handle table size */
- if (i < MAX_CFG)
- return (i);
-
- /* Handle failure */
- cfg_perror_str = dgettext("cfg",
- "cfg_get_parser_offset: section not found");
- cfg_severity = CFG_EFATAL;
- errno = ESRCH;
- return (-1);
-}
-
-/*
- * cfg_fld_mov
- * move fields from old buffer to new
- * moving only specified fields
- * concates newbuf
- * returns fields moved
- */
-static int
-cfg_fld_mov(char *newbuf, char *oldbuf, int start, int end)
-{
- char buf[CFG_MAX_BUF];
- char *ptr;
- int flds = 0;
-
- bzero(buf, CFG_MAX_BUF);
- if (oldbuf == NULL)
- return (0);
-
- if ((start > end) || (strlen(oldbuf) >= CFG_MAX_BUF)) {
- return (0);
- }
- if (!start || !end)
- return (-1);
- strcpy(buf, oldbuf);
- ptr = strtok(buf, " ");
- while (ptr) {
- flds++;
- if (flds >= start && flds <= end) {
- strcat(newbuf, ptr);
- strcat(newbuf, " ");
- }
- ptr = strtok(NULL, " ");
- }
-
- return (flds);
-}
-
-/*
- * cfg_filter_node
- * return indication if this raw buf should be returned
- * checks cfg->cf_node for filtering
- * We already know that this buf meets most of our criteria
- * find the cnode field in the buf and see if it matches
- * returns
- * TRUE Good entry
- * FALSE Don't use it
- */
-static int
-cfg_filter_node(CFGFILE *cfg, struct parser *tbl, char *buf, char *tag)
-{
- char tmpbuf[CFG_MAX_BUF];
- int i = 1;
- int fld;
- char *ptr;
-
- if (!cfg->cf_node) /* no filter always good */
- return (TRUE);
- bzero(tmpbuf, CFG_MAX_BUF);
- fld = cfg_get_item(tbl, tag, "cnode");
- if (fld < 0) /* no cnode field always good */
- return (TRUE);
- strncpy(tmpbuf, buf, CFG_MAX_BUF);
- if (tmpbuf[CFG_MAX_BUF - 1] != '\0')
- return (FALSE);
- ptr = strtok(tmpbuf, " ");
- while (ptr && (i < fld)) {
- ptr = strtok(NULL, " ");
- i++;
- }
- if (!ptr)
- return (FALSE);
-#ifdef DEBUG_EXTRA
- (void) fprintf(stderr, "cfg_filter_node: node=%s:%d cnode=%s:%d\n",
- cfg->cf_node, strlen(cfg->cf_node), ptr, strlen(ptr));
-#endif
- if (strcmp(ptr, cfg->cf_node) == 0)
- return (TRUE);
- return (FALSE);
-}
-/*
- * cfg_insert_node
- * insert resource in bufs which contain cnode parser field
- */
-static void
-cfg_insert_node(CFGFILE *cfg, struct parser *tbl, char *buf, char *tag)
-{
- char tmpbuf[CFG_MAX_BUF];
- int fld;
- int nflds;
- int table_index;
-
- bzero(tmpbuf, CFG_MAX_BUF);
- strcpy(tmpbuf, " ");
- fld = cfg_get_item(tbl, tag, "cnode");
- nflds = cfg_get_num_flds(tbl, tag, &table_index);
- if ((fld < 0) && !(cfg->cf_node)) /* no cnode field always good */
- return;
-
- cfg_fld_mov(tmpbuf, buf, 1, (fld - 1));
- if (cfg->cf_node)
- strcat(tmpbuf, cfg->cf_node);
- else
- strcat(tmpbuf, "-");
- strcat(tmpbuf, " ");
- cfg_fld_mov(tmpbuf, buf, (fld + 1), nflds);
- bcopy(tmpbuf, buf, strlen(tmpbuf) + 1);
-}
-
-/*
- * cfg_is_cnode
- * Parser current buffer to see if a non-empty " - " cnode exists
- */
-/*ARGSUSED*/
-static int
-cfg_is_cnode(CFGFILE *cfg, struct parser *tbl, char *buf, char *tag)
-{
- char tmpbuf[CFG_MAX_BUF];
- int fld = cfg_get_item(tbl, tag, "cnode");
-
- if (fld >= 0) {
- tmpbuf[0] = '\0';
- cfg_fld_mov(tmpbuf, buf, fld, fld);
- return (strcmp(tmpbuf, "- ") ? TRUE : FALSE);
- }
- return (FALSE);
-}
-/*
- * cfg_get_cstring
- * key determines section and value
- * special considerations:
- * AA.BB.CC...
- * AA = data service tag
- * BB = set number relative to first set (1..n)
- * CC = field of set or if absent, all
- */
-int
-cfg_get_cstring(CFGFILE *cfg, const char *key, void *value, int value_len)
-{
- cfp_t *cfp;
- char buf[CFG_MAX_BUF];
- char tmpkey[CFG_MAX_KEY];
- char *section;
- char set[MAX_SET];
- char *setp;
- char *itemp;
- char *p;
- int pos = 1;
- int setnum;
- int relnum;
- int secnum;
- int numfound;
- int needed;
- int table_offset;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
-
- if (!cfg_rdlock(cfg)) {
- cfg_perror_str = dgettext("cfg", CFG_NOTLOCKED);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
-
- bzero(buf, sizeof (buf));
- bzero(set, sizeof (set));
- bzero(tmpkey, sizeof (tmpkey));
- strcpy(tmpkey, key);
- section = strtok(tmpkey, ".");
- setp = strtok(NULL, ".");
- itemp = strtok(NULL, ".");
-
-#ifdef DEBUG_EXTRA
- if (!itemp)
- (void) fprintf(stderr, "cfg_get_cstring:section:%s setp=%s\n",
- section, setp);
- else
- (void) fprintf(stderr,
- "cfg_get_cstring:section:%s setp=%s fld=%s\n",
- section, setp, itemp);
-#endif
-
- table_offset = cfg_get_parser_offset(section);
- setnum = atoi(setp + 3);
- if ((setnum < 1) || (setnum > 0x7ffd)) {
- errno = EINVAL;
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_ENONFATAL;
- return (-1);
- }
-
- /*
- * we have to figure out where this set is
- * in relation to other sets
- */
- relnum = 1;
- secnum = 0;
- numfound = 0;
- for (cfp = &cfg->cf[0]; cfp <= &cfg->cf[1]; cfp++) {
- if (!cfp->cf_fd) continue;
- if (cfp->cf_head->h_state & CFG_HDR_INVALID) {
- if (!cfg_read(cfp)) {
- cfg_perror_str = dgettext("cfg", CFG_RDFAILED);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
- }
- while (numfound < setnum) {
- if ((*cfp->cf_pp->readcf)
- (cfp, buf, table_offset, relnum - secnum) == NULL) {
- secnum = relnum - 1;
- break;
- }
- if (cfg_filter_node(cfg, &chead[0], buf, section))
- numfound++;
-
- if (numfound == setnum)
- break;
-
- relnum++;
- }
- if (numfound == setnum)
- break;
- }
-
- /* Fail to find anything? */
- if (cfp >= &cfg->cf[2]) {
- errno = ESRCH;
- cfg_perror_str = dgettext("cfg", strerror(errno));
- cfg_severity = CFG_ENONFATAL;
- return (-1);
- }
-
- if (buf) {
- if (!itemp) {
- strncpy(value, buf, value_len);
- return (0);
- }
-
- if (itemp) {
- needed = cfg_get_item(&chead[0], section, itemp);
- p = strtok(buf, " ");
- while (p) {
- if (needed == pos) {
- errno = 0;
- if (*p == '-') {
- strcpy(value, "");
- return (0);
- } else {
- if (strlen(p) > value_len) {
- errno = E2BIG;
- cfg_perror_str =
- dgettext("cfg",
- strerror(errno));
- cfg_severity =
- CFG_ENONFATAL;
- return (-1);
- }
- }
- strncpy(value, p, value_len);
-
- return (pos);
- }
- p = strtok(NULL, " ");
- if (!p)
- break;
- pos++;
- }
- }
- }
- errno = ESRCH;
- cfg_perror_str = dgettext("cfg", strerror(errno));
- cfg_severity = CFG_ENONFATAL;
- return (-1);
-}
-
-/*
- * cfg_find_cstring()
- * search for a string in the specified section
- * in the specified field(s)
- * if nfld is 0, then the string is searched for in
- * every field of the entry
- * the set number of the first occurence of target is returned
- * ie. if /dev/vx/rdsk/vol10 is found in sndr.set9, 9 will be returned
- * that is, of course, if the correct field was searched on.
- * -1 on error
- *
- */
-int
-cfg_find_cstring(CFGFILE *cfg, const char *target,
- const char *section, int numflds, ...)
-{
-
- char **list = NULL;
- va_list ap;
- char buf[CFG_MAX_BUF];
- char *field, *p;
- char **fldbuf = NULL;
- int i, j, rc;
- int pos = 1;
- int fieldnum;
- int nflds;
- int tbl_off;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
-
- if (numflds == 0) {
- nflds = cfg_get_num_flds(&chead[0], section, &tbl_off);
-
- } else {
- nflds = numflds;
- }
- if ((fldbuf = calloc(nflds, CFG_MAX_KEY)) == NULL) {
- cfg_perror_str = dgettext("cfg", strerror(errno));
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
-
- if (numflds == 0) { /* search the whole string */
- if ((rc = cfg_get_section(cfg, &list, section)) <= 0) {
- for (i = 0; i < nflds; i++)
- free(fldbuf[i]);
- free(fldbuf);
- return (rc);
- }
- for (i = 0; i < rc; i++) {
- bzero(buf, sizeof (buf));
- strcpy(buf, list[i]);
- p = strtok(buf, " ");
- while (p) {
- if (strcmp(p, target) == 0) { /* we found it! */
- for (j = 0; j < rc; j++)
- free(list[j]);
- free(list);
- for (j = 0; j < nflds; j++)
- free(fldbuf[j]);
- free(fldbuf);
- return (i + 1);
- }
- p = strtok(NULL, " ");
- }
- }
- for (i = 0; i < nflds; i++)
- free(fldbuf[j]);
- for (i = 0; i < rc; i++)
- free(list[i]);
- free(fldbuf);
- free(list);
- return (0);
- }
-
- if ((rc = cfg_get_section(cfg, &list, section)) <= 0) {
- for (i = 0; i < nflds; i++)
- free(fldbuf[i]);
- free(fldbuf);
- return (rc);
- }
-
- va_start(ap, numflds);
- for (i = 0; i < numflds; i++) {
- fldbuf[i] = strdup(va_arg(ap, char *));
- }
-
- fldbuf[i] = NULL;
-
- for (j = 0; j < numflds; j++) {
- fieldnum = cfg_get_item(&chead[0], section, fldbuf[j]);
- for (i = 0; i < rc; i++) {
- bzero(buf, sizeof (buf));
- strcpy(buf, list[i]);
-
- field = strtok(buf, " ");
- pos = 1;
- while (pos < fieldnum) {
- field = strtok(NULL, " ");
- pos++;
- }
- if (field == NULL) {
- for (j = 0; j < numflds; j++)
- free(fldbuf[j]);
- for (j = 0; j < rc; j++)
- free(list[j]);
- free(fldbuf);
- free(list);
- return (-1);
- }
-
- if (strcmp(field, target) == 0) {
- for (j = 0; j < numflds; j++)
- free(fldbuf[j]);
- for (j = 0; j < rc; j++)
- free(list[j]);
- free(fldbuf);
- free(list);
-
- return (i + 1);
- }
-
- }
-
- }
- for (i = 0; i < nflds; i++)
- free(fldbuf[i]);
- for (i = 0; i < rc; i++)
- free(list[i]);
- free(fldbuf);
- free(list);
- return (0);
-}
-
-/*
- * cfg_put_cstring
- * modify entry or add an entry to configuration section
- * Key syntax supported
- * tag Add entry (in entirely) to config
- * tag.setn Add entry to setn If it exists overwrite old entry
- * tag.setn.field Change field in setn
- * value
- * string to change
- * NULL delete specified key
- *
- */
-
-int
-cfg_put_cstring(CFGFILE *cfg, const char *key, void *value, int val_len)
-{
- cfp_t *cfp;
- char buf[CFG_MAX_BUF];
- char newbuf[CFG_MAX_BUF];
- char *bufp;
- char tmpkey[CFG_MAX_KEY];
- char *section;
- char *setp;
- char *itemp;
- int nofield = 0;
- int noset = 0;
- int fldnum;
- int setnum = 0;
- int relnum;
- int secnum;
- int numfound;
- int addcnode = 1;
- int table_index;
- int table_offset;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
-
- bzero(buf, sizeof (buf));
- strcpy(tmpkey, key);
- section = strtok(tmpkey, ".");
- setp = strtok(NULL, ".");
- itemp = strtok(NULL, ".");
-
- if (!cfg_wrlock(cfg)) {
- cfg_perror_str = dgettext("cfg", CFG_RDFAILED);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
-
- if (!key) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_ENONFATAL;
- return (-1);
- }
- if (value && val_len == 0) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_ENONFATAL;
- return (-1);
- }
- if (!itemp)
- nofield++;
- if (!setp)
- noset++;
- else if (setp) {
- setnum = atoi(setp + 3);
- if (setnum < 1 || setnum > 0x7ffd) {
- errno = EINVAL;
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_ENONFATAL;
- return (-1);
- }
- }
-
- table_offset = cfg_get_parser_offset(section);
-
- /*
- * we have to figure out where this set is
- * in relation to other sets
- */
- relnum = 1;
- secnum = 0;
- numfound = 0;
-
- if (setp && nofield) {
- char tmpbuf[CFG_MAX_BUF];
- int rc;
- int nflds;
- int got;
-
- /*
- * Set specified but no field
- */
- for (cfp = &cfg->cf[0]; cfp <= &cfg->cf[1]; cfp++) {
- if (!cfp->cf_fd) continue;
- if (cfp->cf_head->h_state & CFG_HDR_INVALID) {
- if (!cfg_read(cfp)) {
- cfg_perror_str =
- dgettext("cfg", CFG_RDFAILED);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
- }
- while (numfound < setnum) {
- if ((*cfp->cf_pp->readcf)
- (cfp, tmpbuf, table_offset, relnum - secnum)
- == NULL) {
- secnum = relnum - 1;
- break;
- }
- if (cfg_filter_node(cfg, &chead[0], tmpbuf,
- section))
- numfound++;
-
- if (numfound == setnum)
- break;
-
- relnum++;
- }
- if (numfound == setnum)
- break;
- }
-
- /* Fail to find anything? */
- if (cfp >= &cfg->cf[2]) {
- errno = ESRCH;
- cfg_perror_str = dgettext("cfg", strerror(errno));
- cfg_severity = CFG_ENONFATAL;
- return (-1);
- }
-
- nflds = cfg_get_num_flds(&chead[0], section, &table_index);
-
- if (value == NULL) {
- /* Remove entry completely */
-
- rc = (*cfp->cf_pp->remcf)(cfp, table_index,
- relnum - secnum);
- if (rc < 0)
- return (rc);
- return (0);
- }
-
- got = cfg_cnt_flds(value);
- bzero(buf, sizeof (buf));
-
- strncpy(buf, " ", 1);
- if (strlen(value) > sizeof (buf) - 2) {
- errno = E2BIG;
- cfg_perror_str = dgettext("cfg", strerror(errno));
- cfg_severity = CFG_ENONFATAL;
- return (-1);
- }
- strncat(buf, value, val_len);
- if (got < nflds) {
- for (/* CSTYLED */; got < nflds; got++)
- strncat(buf, " - ", 3);
- } else if (got > nflds) {
- return (-1);
- } else {
- /* got == nflds, so cnode was included */
- addcnode = 0;
- }
-
- bufp = buf;
- if (addcnode) {
- cfg_insert_node(cfg, &chead[0], buf, section);
- }
-
- (*cfp->cf_pp->replacecf)(cfp, bufp, table_index,
- relnum - secnum);
-
- return (TRUE);
- }
-
- /*
- * Both Set and field are specified
- * needs to get current whole entry and old requested field
- * copy good fields to buf, replace new field in buf
- * move everything depending of new size
- * replace entry so set# does not change
- */
- if (setp && itemp) {
- int rc;
- int nflds;
- int cnodepos;
-
- for (cfp = &cfg->cf[0]; cfp <= &cfg->cf[1]; cfp++) {
- if (!cfp->cf_fd) continue;
- if (cfp->cf_head->h_state & CFG_HDR_INVALID) {
- if (!cfg_read(cfp)) {
- cfg_perror_str =
- dgettext("cfg", CFG_RDFAILED);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
- }
- while (numfound < setnum) {
- if ((*cfp->cf_pp->readcf)
- (cfp, buf, table_offset, relnum - secnum)
- == NULL) {
- secnum = relnum - 1;
- break;
- }
- if (cfg_filter_node(cfg, &chead[0], buf,
- section))
- numfound++;
-
- if (numfound == setnum)
- break;
-
- relnum++;
- }
- if (numfound == setnum)
- break;
- }
-
- /* Fail to find anything? */
- if (cfp >= &cfg->cf[2]) {
- errno = ESRCH;
- cfg_perror_str = dgettext("cfg", strerror(errno));
- cfg_severity = CFG_ENONFATAL;
- return (-1);
- }
-
- nflds = cfg_get_num_flds(&chead[0], section, &table_index);
- fldnum = cfg_get_item(&chead[0], section, itemp);
- bzero(newbuf, sizeof (newbuf));
- strncpy(newbuf, " ", 1);
-
- /* move good flds in */
- rc = cfg_fld_mov(newbuf, buf, 1, fldnum - 1);
- if (rc < 0)
- return (rc);
-
- /* move new fld in */
- strncat(newbuf, value, strlen(value));
- strcat(newbuf, " ");
-
- /* move remaining flds in */
- rc = cfg_fld_mov(newbuf, buf, fldnum + 1, nflds);
- if (rc < 0)
- return (rc);
-
- cnodepos = cfg_get_item(&chead[0], section, "cnode");
- if ((cnodepos >= 0) && strcmp(itemp, "cnode") != 0) {
- /* add cnode if user didn't specify it */
- cfg_insert_node(cfg, &chead[0],
- newbuf, section);
- }
-
- (*cfp->cf_pp->replacecf)(cfp, newbuf, table_index,
- relnum - secnum);
-
- return (TRUE);
- }
-
- if (noset) { /* blast entire thing in */
- int nflds;
- int got;
- int cnodepos;
-
- bufp = buf;
- if (!value) { /* we shouldn't be here */
- errno = EINVAL;
- return (-1);
- }
- strncat(buf, " ", 1);
- if (strlen(value) > sizeof (buf) - 2) {
- errno = E2BIG;
- return (-1);
- }
-
- strncat(buf, value, val_len);
- nflds = cfg_get_num_flds(&chead[0], section, &table_index);
- got = cfg_cnt_flds(value);
-
- cnodepos = cfg_get_item(&chead[0], section, "cnode");
- if (cnodepos < 0 || got >= cnodepos) {
- /* no cnode, or cnode was specified by caller */
- addcnode = 0;
- }
-
- if (got < nflds) {
- for (/* CSTYLED */; got < nflds; got++)
- strncat(buf, " - ", 3);
- } else if (got > nflds) {
- errno = EINVAL; /* specified too many fields */
- return (-1);
- } else {
- /* got == nflds, so cnode was included */
- addcnode = 0;
- }
-
- if (addcnode) {
- cfg_insert_node(cfg, &chead[0], buf, section);
- }
-
- /* Make sure we put this entry in the right database */
- if (cfg_is_cnode(cfg, &chead[0], buf, section) &&
- cfg->cf[1].cf_fd)
- cfp = &cfg->cf[1];
- else
- cfp = &cfg->cf[0];
-
- if (cfp->cf_head->h_state & CFG_HDR_INVALID) {
- if (!cfg_read(cfp)) {
- cfg_perror_str = dgettext("cfg", CFG_RDFAILED);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
- }
- if (cfp->cf_head->h_csize + strlen(buf) > CFG_DEFAULT_SSIZE) {
- errno = ENOSPC;
- return (-1);
- }
-
- (*cfp->cf_pp->addcf)(cfp, bufp, table_index);
-
- return (TRUE);
- }
-
- errno = EINVAL;
- cfg_perror_str = strerror(errno);
- cfg_severity = CFG_ENONFATAL;
- return (-1);
-}
-
-/*
- * cfg_encode_char
- *
- * Encode a single character into % + hex ascii value
- */
-static void
-cfg_encode_char(char *result, char ch)
-{
- *result++ = '%';
- *result++ = dectohex[ (ch >> 4) & 0xf ];
- *result++ = dectohex[ ch & 0xf ];
-}
-
-/*
- * cfg_decode_char
- *
- * Reverses cfg_encode_char
- */
-static char
-cfg_decode_char(char *code)
-{
- char retval;
- if (*code != '%') {
- return ('\0');
- }
- ++code;
- if (!isxdigit(*code))
- return ('\0');
- retval = (isdigit(*code)? *code - '0' : *code - 'a' + 10);
- retval <<= 4;
- ++code;
- if (!isxdigit(*code))
- return ('\0');
- retval |= (isdigit(*code)? *code - '0' : *code - 'a' + 10);
-
- return (retval);
-}
-
-/*
- * cfg_encode_option
- *
- * Transforms the key and value strings so that special characters
- * can be used within the options field.
- *
- * Returns:
- * Length of encoded string; -1 on failure
- */
-static int
-cfg_encode_string(char *str, char *output, int outlen)
-{
- char *mem, *p, *q;
- int curlen;
-
-
- /* first, scan through the tag string converting %-signs */
- p = str;
- q = output;
- curlen = 0;
- while (*p && curlen < outlen) {
- if (*p == '%') {
- if (curlen + 3 >= outlen) {
- return (-1);
- }
- cfg_encode_char(q, *p);
- curlen += 3;
- q += 3;
- } else {
- *q++ = *p;
- ++curlen;
- }
- ++p;
- }
- if (curlen < outlen)
- *q = '\0';
-
- /* now encode special characters */
- p = mem = strdup(output);
- q = output;
- curlen = 0;
- while (*p && curlen < outlen) {
- if (strchr(CHARS_TO_ENCODE, *p) != 0) {
- if (curlen + 3 >= outlen) {
- free(mem);
- return (-1);
- }
- cfg_encode_char(q, *p);
- curlen += 3;
- q += 3;
- } else {
- *q++ = *p;
- ++curlen;
- }
- ++p;
- }
- free(mem);
-
- if (curlen < outlen)
- *q = '\0';
- /* LINTED possible ptrdiff_t overflow */
- return (q - output);
-}
-
-/*
- * cfg_decode_option
- *
- * Given a string, decodes any %-encodes on it.
- */
-static void
-cfg_decode_string(char *str, char *output, int outlen)
-{
- char *p, *q;
- int curlen;
-
- p = str;
- q = output;
- curlen = 0;
- while (*p && curlen < outlen) {
- if (*p == '%') {
- char ch = cfg_decode_char(p);
- if (!ch) {
- *q++ = *p++;
- ++curlen;
- } else {
- *q++ = ch;
- p += 3;
- ++curlen;
- }
- } else {
- *q++ = *p++;
- ++curlen;
- }
- }
- if (curlen < outlen)
- *q = '\0';
-}
-
-/*
- * cfg_get_options
- * return first options set from basekey
- * Subsequent calls with basekey = NULL return next option if any
- * into tag and val
- * returns
- * true success and more options data
- * -1 no options data
- */
-
-int
-cfg_get_options(CFGFILE *cfg, int section, const char *basekey, char *tag,
- int tag_len, char *val, int val_len)
-{
- static char buf[CFG_MAX_BUF];
- char decode_buf[CFG_MAX_BUF];
- int rc;
- char *ttag, *tval;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
-
- errno = ENOSYS;
- if (basekey == 0) {
- ttag = strtok(NULL, "=");
- } else {
- bzero(buf, CFG_MAX_BUF);
- if (section == CFG_SEC_CONF) {
- rc = cfg_get_cstring(cfg, basekey, buf, CFG_MAX_BUF);
- } else
- return (-1);
- if (rc < 0)
- return (rc);
- /* buf now contains raw options data */
- ttag = strtok(buf, "=");
- }
- tval = strtok(NULL, ";");
- if (!(tval) || !(ttag))
- return (-1);
- if ((strlen(tval) > val_len) || (strlen(ttag) > tag_len)) {
- errno = E2BIG;
- return (-1);
- }
- cfg_decode_string(tval, decode_buf, CFG_MAX_BUF);
- strncpy(val, decode_buf, val_len);
- cfg_decode_string(ttag, decode_buf, CFG_MAX_BUF);
- strncpy(tag, decode_buf, tag_len);
- errno = 0;
- return (TRUE);
-}
-
-/*
- * cfg_put_options
- *
- * Replaces existing tag with new val. If tag doesn't exist,
- * then it adds a new tag with the specified val.
- *
- * Return:
- * true success
- * -1 incorrect section, or read error from cfg DB
- */
-int
-cfg_put_options(CFGFILE *cfg, int section, const char *basekey, char *tag,
- char *val)
-{
- char buf[CFG_MAX_BUF];
- char encode_buf[CFG_MAX_BUF];
- char *p;
- int enclen;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
-
- errno = ENOSYS;
- bzero(buf, CFG_MAX_BUF);
- if (section != CFG_SEC_CONF) {
- cfg_severity = CFG_ENONFATAL;
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- return (-1);
- }
- if (!tag || !*tag || !val || !*val)
- return (-1);
- if (cfg_get_cstring(cfg, basekey, buf, CFG_MAX_BUF) < 0) {
- /* cfg severity & perror_str set up cfg_get_cstring() */
- return (-1);
- }
- *encode_buf = ';';
- enclen = cfg_encode_string(tag, &encode_buf[1], CFG_MAX_BUF - 1) + 1;
- if (enclen < 1 || (enclen + 1) >= CFG_MAX_BUF) {
- cfg_severity = CFG_ENONFATAL;
- cfg_perror_str = dgettext("cfg", "Buffer too small");
- return (-1);
- }
- encode_buf[enclen] = '=';
- encode_buf[enclen + 1] = '\0';
-
- /* check the start of the string */
- if (strncmp(buf, &encode_buf[1], enclen) == 0) {
- /* locate the end of this option */
- p = strchr(buf, ';');
- if (p && *(p + 1) != '\0') {
- /* add the new tag to the end */
- ++p;
- strcat(p, &encode_buf[1]);
- } else {
- /* completely overwrite the existing tag */
- p = buf;
- strcpy(p, &encode_buf[1]);
- }
- if (cfg_encode_string(val, encode_buf, CFG_MAX_BUF) < 0) {
- cfg_severity = CFG_ENONFATAL;
- cfg_perror_str = dgettext("cfg", "Buffer too small");
- return (-1);
- }
- strcat(p, encode_buf);
- strcat(p, ";");
- if (cfg_put_cstring(cfg, basekey, p, strlen(p)) < 0) {
- /* severity & perror_str set by cfg_put_cstring */
- return (-1);
- }
- errno = 0;
- return (TRUE);
- }
-
- /* it's hiding somewhere inside... */
- p = strstr(buf, encode_buf);
- if (p) {
- /* delete the old value */
- char *q = strchr(p + 1, ';');
- if (q) {
- strcpy(p + 1, q + 1);
- } else {
- *p = '\0';
- }
- strcat(buf, &encode_buf[1]);
- } else if (*buf) {
- strcat(buf, &encode_buf[1]);
- } else {
- strcpy(buf, &encode_buf[1]);
- }
- enclen = cfg_encode_string(val, encode_buf, CFG_MAX_BUF);
- if (enclen < 0 || (strlen(buf) + enclen) >= CFG_MAX_BUF) {
- cfg_severity = CFG_ENONFATAL;
- cfg_perror_str = dgettext("cfg", "Buffer too small");
- return (-1);
- }
- strcat(buf, encode_buf);
- strcat(buf, ";");
- if (cfg_put_cstring(cfg, basekey, buf, CFG_MAX_BUF) < 0) {
- /* severity & perror_str set by cfg_put_cstring */
- return (-1);
- }
- errno = 0;
- return (TRUE);
-}
-
-/*
- * cfg_get_single_option
- *
- * Scans the options string for the specified option and returns
- * the decoded value
- *
- * Return:
- * true success
- * -1 incorrect section, or read error from cfg DB
- */
-int
-cfg_get_single_option(CFGFILE *cfg, int section, const char *basekey, char *tag,
- char *val, int val_len)
-{
- char buf[CFG_MAX_BUF];
- char encode_buf[CFG_MAX_BUF];
- char *p, *q;
- int enclen;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
-
- errno = ENOSYS;
- bzero(buf, CFG_MAX_BUF);
- if (section != CFG_SEC_CONF) {
- cfg_severity = CFG_ENONFATAL;
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- return (-1);
- }
- if (cfg_get_cstring(cfg, basekey, buf, CFG_MAX_BUF) < 0) {
- /* severity & perror_str set by cfg_get_cstring */
- return (-1);
- }
-
- *encode_buf = ';';
- enclen = cfg_encode_string(tag, &encode_buf[1], CFG_MAX_BUF - 1) + 1;
- if (enclen < 1 || (enclen + 1) >= CFG_MAX_BUF) {
- cfg_severity = CFG_ENONFATAL;
- cfg_perror_str = dgettext("cfg", "Buffer too small");
- return (-1);
- }
- encode_buf[enclen] = '=';
- encode_buf[enclen + 1] = '\0';
-
- /* check the start of the string */
- if (strncmp(buf, &encode_buf[1], enclen) == 0) {
- p = strchr(buf, '=');
- if (!p) {
- cfg_severity = CFG_ENONFATAL;
- cfg_perror_str = dgettext("cfg", "Option not found");
- return (-1);
- }
- ++p;
- q = strchr(p, ';');
- if (q) {
- *q = '\0';
- }
- cfg_decode_string(p, val, val_len);
- errno = 0;
- return (TRUE);
- }
-
- /* it's hiding somewhere inside... */
- p = strstr(buf, encode_buf);
- if (p) {
- p += enclen + 1;
- q = strchr(p, ';');
- if (q) {
- *q = '\0';
- }
- cfg_decode_string(p, val, val_len);
- errno = 0;
- return (TRUE);
- }
-
- /* key not found */
- return (-1);
-
-}
-
-/*
- * cfg_del_option
- *
- * Removes a single key=val pair from the specified option field
- *
- * Return:
- * true success
- * -1 unable to update config
- */
-int
-cfg_del_option(CFGFILE *cfg, int section, const char *basekey, char *tag)
-{
- char buf[CFG_MAX_BUF];
- char encode_buf[CFG_MAX_BUF];
- char *p, *q;
- int enclen, rc;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
-
- bzero(buf, CFG_MAX_BUF);
- if (section != CFG_SEC_CONF) {
- cfg_severity = CFG_ENONFATAL;
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- return (-1);
- }
- if (cfg_get_cstring(cfg, basekey, buf, CFG_MAX_BUF) < 0) {
- /* severity & perror_str are set by cfg_get_cstring */
- return (-1);
- }
-
- *encode_buf = ';';
- enclen = cfg_encode_string(tag, &encode_buf[1], CFG_MAX_BUF - 1) + 1;
- if (enclen < 1 || (enclen + 1) >= CFG_MAX_BUF) {
- cfg_severity = CFG_ENONFATAL;
- cfg_perror_str = dgettext("cfg", "Buffer too small");
- return (-1);
- }
- encode_buf[enclen] = '=';
- encode_buf[enclen + 1] = '\0';
-
- /* check the start of the string */
- if (strncmp(buf, &encode_buf[1], enclen) == 0) {
- p = strchr(buf, ';');
- if (p && (*(p + 1) != '\0')) {
- rc = cfg_put_cstring(cfg, basekey, p + 1,
- strlen(p + 1));
- } else {
- rc = cfg_put_cstring(cfg, basekey, "-", 1);
- }
- /* severity & perror_str are set by cfg_put_cstring */
- return (rc);
- }
-
- /* sigh */
- p = strstr(buf, encode_buf);
- if (!p) {
- /* already removed */
- return (TRUE);
- }
- q = strchr(p + 1, ';');
-
- /*
- * Now the string looks like:
- * | first few options | *p | option to remove | *q | rest | '\0'
- */
-
- if (!q) {
- /* hum... */
- *p = '\0';
- } else {
- strcpy(p, q);
- }
-
- return (cfg_put_cstring(cfg, basekey, buf, strlen(buf)));
-}
-
-static void
-cfg_set_memorymap(cfp_t *cfp)
-{
- cfgheader_t *hd = cfp->cf_head;
-
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr, "callocing %d for initial reads\n", hd->h_csize);
-#endif
-
- hd->h_ccopy1 = (char *)calloc(hd->h_csize, sizeof (char));
- hd->h_ccopy2 = (char *)calloc(hd->h_csize, sizeof (char));
- hd->h_sizes1 = (int *)calloc(CFG_DEFAULT_PSIZE, sizeof (int));
- hd->h_sizes2 = (int *)calloc(CFG_DEFAULT_PSIZE, sizeof (int));
-}
-
-/*
- * cfg_init_header
- * fill in default header info
- */
-static void
-cfg_init_header(cfp_t *cfp)
-{
- time_t tloc;
- cfgheader_t *hd = cfp->cf_head;
-
- hd->h_magic = (int32_t)CFG_NEW_MAGIC;
- hd->h_stamp = time(&tloc);
- hd->h_lock = 0;
- /* parser config */
- hd->h_parsesize = 0;
- hd->h_parseoff = 0;
- hd->h_csize = 0;
- hd->h_psize = 0;
- hd->h_cfgs = NULL;
- hd->h_ncfgs = 0;
- hd->h_seq1 = hd->h_seq2 = 1;
- bzero(hd->h_cfgsizes, MAX_CFG * sizeof (int));
-}
-/*
- * cfg_read
- * read header and all sections of configuration file
- * gets new data for incore copy
- * removes invalid header state
- * works even if config and persistent sections are empty
- *
- */
-static int
-cfg_read(cfp_t *cfp)
-{
- int rc;
- cfgheader_t *hd;
- int readsize = 0;
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr, "cfg_read\n");
-#endif
-
- if (!cfp->cf_head) {
- if ((hd = calloc(1, sizeof (*hd))) == NULL)
- return (FALSE);
-#ifdef DEBUG_HDR
- (void) fprintf(stderr, "initial cfg header read\n");
-#endif
- cfp->cf_head = hd;
- }
-
- if ((*cfp->cf_pp->seek)(cfp, 0, SEEK_SET) < 0) {
-#ifdef DEBUG_LIB
- (void) fprintf(stderr, "cfg: seek header failed\n");
-#endif
- return (FALSE);
- }
-
- rc = (*cfp->cf_pp->read)(cfp, (char *)cfp->cf_head, 4);
- if (rc < 4) {
-#ifdef DEBUG_LIB
- (void) fprintf(stderr, "cfg: read magic number failed\n");
-#endif
- return (FALSE);
- }
-
- if ((*cfp->cf_pp->seek)(cfp, 0, SEEK_SET) < 0) {
-#ifdef DEBUG_LIB
- (void) fprintf(stderr, "cfg: seek header failed\n");
-#endif
- return (FALSE);
- }
-
- rc = (*cfp->cf_pp->read)(cfp, (char *)cfp->cf_head, sizeof (*hd));
- if (rc < sizeof (*hd)) {
-#ifdef DEBUG_LIB
- (void) fprintf(stderr, "cfg: read header failed\n");
-#endif
- return (FALSE);
- }
-
- cfp->cf_head->h_cfgs = NULL;
- cfg_set_memorymap(cfp);
- if (cfp->cf_head->h_magic != CFG_NEW_MAGIC) {
-#ifdef DEBUG_LIB
- (void) fprintf(stderr, "cfg_read: wrong MAGIC number %x\n",
- cfp->cf_head->h_magic);
-#endif
- return (FALSE);
- }
-
- cfp->cf_head->h_state &= ~(CFG_HDR_INVALID);
-
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr, "reading parser\n");
-#endif
- rc = (*cfp->cf_pp->read)(cfp, (char *)cfp->cf_mapped,
- CFG_DEFAULT_PARSE_SIZE);
- if (rc < sizeof (*hd)) {
-#ifdef DEBUG
- (void) fprintf(stderr, "cfg: read parse config failed\n");
-#endif
- return (FALSE);
- }
-
- readsize = cfp->cf_head->h_csize;
-
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr, "reading copy1 readsize = %d\n", readsize);
-#endif
- rc = (*cfp->cf_pp->read)(cfp, (char *)cfp->cf_head->h_ccopy1,
- readsize);
- if (rc < 0) {
- /* don't fail just return */
-#ifdef DEBUG
- (void) fprintf(stderr, "cfg: read ccopy1 section failed\n");
-#endif
- return (FALSE);
- }
-
- if ((*cfp->cf_pp->seek)
- (cfp, CFG_DEFAULT_SSIZE - rc, SEEK_CUR) < 0) {
-#ifdef DEBUG
- (void) fprintf(stderr, "cfg: seek (SEEK_CUR) failed\n");
-#endif
- return (FALSE);
- }
-
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr, "reading copy2 readsize = %d\n", readsize);
-#endif
-
- rc = (*cfp->cf_pp->read)(cfp, (char *)cfp->cf_head->h_ccopy2,
- readsize);
- if (rc < 0) {
- /* don't fail just return */
-#ifdef DEBUG
- (void) fprintf(stderr, "cfg: read ccopy2 section failed\n");
-#endif
- return (FALSE);
- }
-
- /* read the sizes of the lists from disk */
- if ((*cfp->cf_pp->seek)
- (cfp, CFG_DEFAULT_SSIZE - rc, SEEK_CUR) < 0) {
-#ifdef DEBUG
- (void) fprintf(stderr, "cfg: seek (SEEK_CUR) failed\n");
-#endif
- return (FALSE);
- }
-
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr, "reading sizes\n");
-#endif
- rc = (*cfp->cf_pp->read)(cfp, (int *)cfp->cf_head->h_sizes1,
- CFG_DEFAULT_PSIZE);
- if (rc < 0) {
-#ifdef DEBUG
- (void) fprintf(stderr, "cfg: read h_sizes1 failed\n");
-#endif
- return (FALSE);
- }
-
- rc = (*cfp->cf_pp->read)(cfp, (int *)cfp->cf_head->h_sizes2,
- CFG_DEFAULT_PSIZE);
- if (rc < 0) {
-#ifdef DEBUG
- (void) fprintf(stderr, "cfg: read h_sizes2 failed\n");
-#endif
- return (FALSE);
- }
-
- /*
- * If initial or invalid sequence, use first section
- */
- if ((cfp->cf_head->h_seq1 <= 0) && (cfp->cf_head->h_seq2 <= 0)) {
- cfp->cf_head->h_cparse = cfp->cf_head->h_ccopy1;
- cfp->cf_head->h_sizes = cfp->cf_head->h_sizes1;
- }
-
- if (cfp->cf_head->h_seq1 >= cfp->cf_head->h_seq2) {
- cfp->cf_head->h_cparse = cfp->cf_head->h_ccopy1;
- cfp->cf_head->h_sizes = cfp->cf_head->h_sizes1;
- } else {
- cfp->cf_head->h_cparse = cfp->cf_head->h_ccopy2;
- cfp->cf_head->h_sizes = cfp->cf_head->h_sizes2;
- }
-
-#ifdef DEBUG_LIB
- dump_status(cfp, "cfg_read");
-#endif
-
- return (TRUE);
-}
-
-/*
- * cfg_lock
- * Read-write locking of the configuration
- * reads into core all sections
- * builds parser trees for each section
- * Returns: TRUE if the lock was acquired, FALSE otherwise.
- */
-int
-cfg_lock(CFGFILE *cfg, CFGLOCK mode)
-{
- cfp_t *cfp;
- int is_locked = 0;
- int rc;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (FALSE);
- }
-
- if (mode == CFG_UPGRADE) {
- mode = CFG_WRLOCK;
- }
-
- if (mode == CFG_WRLOCK && (cfg->cf[0].cf_flag & CFG_RDONLY)) {
- goto fail;
- }
-
- /*
- * if you don't even give me the right lock request,
- * why should I give you one?
- */
- if (mode != CFG_RDLOCK && mode != CFG_WRLOCK)
- goto fail;
-
- if (cfg_lockd) {
- if (mode == CFG_WRLOCK)
- cfg_lockd_wrlock();
- else
- cfg_lockd_rdlock();
- is_locked = 1;
- } else {
-
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr, "cfg_lock\n");
-#endif
- /* Lock is always based on local file pointer */
- cfg->cf[1].cf_lock = cfg->cf[0].cf_lock = cfg->cf[0].cf_fd;
-
- if (!((cfg->cf[0].cf_flag & CFG_RDONLY) &&
- (mode == CFG_RDLOCK))) {
-
- struct flock lk = {0};
- lk.l_type = (mode == CFG_RDLOCK ? F_RDLCK : F_WRLCK);
- lk.l_whence = SEEK_SET;
- lk.l_start = (off_t)0;
- lk.l_len = (off_t)0;
-
- if (fcntl(cfg->cf[0].cf_lock, F_SETLKW, &lk) < 0)
- goto fail;
- }
- }
-
- /* Determine number of files open */
- for (cfp = &cfg->cf[0]; cfp <= &cfg->cf[1]; cfp++) {
- if (!cfp->cf_fd) continue;
- if ((cfp->cf_head) &&
- (cfp->cf_head->h_state & CFG_HDR_INVALID)) {
- if ((rc = cfg_hdrcmp(cfp)) == 0) {
-#ifdef DEBUG_HDR
- (void) fprintf(stderr,
- "cfg header match, skipping re-read\n");
-#endif
- cfp->cf_head->h_state |= CFG_HDR_RDLOCK;
- if (mode == CFG_WRLOCK)
- cfp->cf_head->h_state |= CFG_HDR_WRLOCK;
-
- cfp->cf_head->h_state &= ~(CFG_HDR_INVALID);
- continue;
- }
-#ifdef DEBUG_HDR
- (void) fprintf(stderr, "re-reading cfg, header mismatch\n");
-#endif
- /*
- * dump what we have, info is stale
- */
- cfg_free_cfglist(cfp);
- cfg_free_parser_tree();
-
- if (cfp->cf_head->h_ccopy1) {
- free(cfp->cf_head->h_ccopy1);
- cfp->cf_head->h_ccopy1 = NULL;
- }
- if (cfp->cf_head->h_ccopy2) {
- free(cfp->cf_head->h_ccopy2);
- cfp->cf_head->h_ccopy2 = NULL;
- }
- if (cfp->cf_head->h_sizes1) {
- free(cfp->cf_head->h_sizes1);
- cfp->cf_head->h_sizes1 = NULL;
- }
- if (cfp->cf_head->h_sizes2) {
- free(cfp->cf_head->h_sizes2);
- cfp->cf_head->h_sizes2 = NULL;
- }
-
- if (cfp->cf_head)
- free(cfp->cf_head);
- cfp->cf_head = NULL;
- }
-
- if (cfp->cf_head == NULL) {
- if (!cfg_read(cfp)) {
- if (cfp->cf_head != NULL)
- cfg_init_header(cfp);
- else
- goto fail;
- } else {
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr,
- "reading parser config\n");
-#endif
- /* build parser trees */
- cfg_read_parser_config(cfp);
- }
-
- }
- cfp->cf_head->h_state |= CFG_HDR_RDLOCK;
- if (mode == CFG_WRLOCK) {
- if (cfp->cf_head->h_seq1 >= cfp->cf_head->h_seq2) {
-#ifdef DEBUG_LIB
- (void) fprintf(stderr,
- "cfg_lock: WRLOCK copying 1 to 2\n");
-#endif
- memcpy(cfp->cf_head->h_ccopy2,
- cfp->cf_head->h_ccopy1,
- cfp->cf_head->h_csize);
- memcpy(cfp->cf_head->h_sizes2,
- cfp->cf_head->h_sizes1,
- CFG_DEFAULT_PSIZE);
-
- cfp->cf_head->h_cparse = cfp->cf_head->h_ccopy2;
- cfp->cf_head->h_sizes = cfp->cf_head->h_sizes2;
- } else {
-#ifdef DEBUG_LIB
- (void) fprintf(stderr,
- "cfg_lock: WRLOCK copying 2 to 1\n");
-#endif
- memcpy(cfp->cf_head->h_ccopy1,
- cfp->cf_head->h_ccopy2,
- cfp->cf_head->h_csize);
- memcpy(cfp->cf_head->h_sizes1,
- cfp->cf_head->h_sizes2,
- CFG_DEFAULT_PSIZE);
-
- cfp->cf_head->h_cparse = cfp->cf_head->h_ccopy1;
- cfp->cf_head->h_sizes = cfp->cf_head->h_sizes1;
- }
-
- cfp->cf_head->h_state |= CFG_HDR_WRLOCK;
- }
-
- if (cfg_map_cfglists(cfp) < 0) {
-#ifdef DEBUG_LIB
- (void) fprintf(stderr, "cfg: map_cfglists failed\n");
-#endif
- goto fail;
- }
-
-#ifdef DEBUG_LIB
- dump_status(cfp, "cfg_lock");
-#endif
- }
-
- return (TRUE);
-
-fail:
- if (is_locked) {
- cfg_lockd_unlock();
- }
- cfg_perror_str = dgettext("cfg", CFG_EGENERIC);
- cfg_severity = CFG_ENONFATAL;
- return (FALSE);
-}
-
-/*
- * Unlock the database
- */
-void
-cfp_unlock(cfp_t *cfp)
-{
-
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr, "cfg_unlock\n");
-#endif
- if (cfg_lockd) {
- cfg_lockd_unlock();
- } else {
- struct flock lk = {0};
- lk.l_type = F_UNLCK;
- lk.l_whence = SEEK_SET;
- lk.l_start = (off_t)0;
- lk.l_len = (off_t)0;
- (void) fcntl(cfp->cf_lock, F_SETLKW, &lk);
- }
-
- if (cfp->cf_head != NULL) {
- cfp->cf_head->h_state &= ~(CFG_HDR_RDLOCK|CFG_HDR_WRLOCK);
- cfp->cf_head->h_state |= CFG_HDR_INVALID;
- }
-}
-void
-cfg_unlock(CFGFILE *cfg)
-{
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return;
- }
-
- cfp_unlock(&cfg->cf[0]);
- cfp_unlock(&cfg->cf[1]);
-}
-
-/*
- * Test for a read lock, set errno if failed.
- */
-static int
-cfg_rdlock(CFGFILE *cfg)
-{
- int rc;
- cfp_t *cfp;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (FALSE);
- }
-
- /* Determine number of files open */
- for (cfp = &cfg->cf[0]; cfp <= &cfg->cf[1]; cfp++) {
- if (!cfp->cf_fd)
- continue;
- if (cfp->cf_head == NULL) {
-#ifdef DEBUG_LIB
- (void) fprintf(stderr, "cfg_rdlock: cf_head == NULL\n");
-#endif
- /*
- * 6335583, if header == NULL,
- * we can't call cfg_read to fill the header again
- * since it will change the lock state to
- * CFG_HDR_WRLOCK and dscfg will be the processer
- * that hold the lock,
- * just returning a FALSE if the case,
- * then retrieve the lock state from flock structure.
- */
- rc = FALSE;
- break;
- } else {
-#ifdef DEBUG_LIB
- (void) fprintf(stderr, "cfg_rdlock: cf_head != NULL\n");
-#endif
- if ((cfp->cf_head->h_state & CFG_HDR_RDLOCK)
- == CFG_HDR_RDLOCK) {
- rc = TRUE;
- } else {
- rc = FALSE;
- break;
- }
- }
- }
-
- if (!rc)
- errno = EPERM;
-
- return (rc);
-}
-
-/*
- * Test for a write lock, set errno if failed.
- */
-static int
-cfg_wrlock(CFGFILE *cfg)
-{
- int rc;
- cfp_t *cfp;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (FALSE);
- }
-
- /* Determine number of files open */
- for (cfp = &cfg->cf[0]; cfp <= &cfg->cf[1]; cfp++) {
- if (!cfp->cf_fd)
- continue;
- if (cfp->cf_head == NULL) {
-#ifdef DEBUG_LIB
- (void) fprintf(stderr, "cfg wrlock: cf_head == NULL\n");
-#endif
- /*
- * 6335583, see comments on cfg_rdlock
- */
- rc = FALSE;
- break;
- } else {
-#ifdef DEBUG_LIB
- (void) fprintf(stderr, "cfg wrlock: cf_head != NULL\n");
-#endif
- if ((cfp->cf_head->h_state & CFG_HDR_WRLOCK)
- == CFG_HDR_WRLOCK) {
- rc = TRUE;
- } else {
- rc = FALSE;
- break;
- }
- }
- }
-
- if (!rc)
- errno = EPERM;
-
- return (rc);
-}
-
-/*
- * cfg_get_lock
- * Find lock status of CFG database.
- * Returns: TRUE and sets lock and pid if the lock is held, FALSE otherwise.
- */
-int
-cfg_get_lock(CFGFILE *cfg, CFGLOCK *lock, pid_t *pid)
-{
- struct flock lk;
- int rc;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (FALSE);
- }
-
- if (cfg_lockd) {
- switch (cfg_lockedby(pid)) {
- case LOCK_READ:
- *lock = CFG_RDLOCK;
- return (TRUE);
- case LOCK_WRITE:
- *lock = CFG_WRLOCK;
- return (TRUE);
- case LOCK_NOTLOCKED:
- default:
- return (FALSE);
- }
- } else {
- if (cfg_wrlock(cfg)) {
- *lock = CFG_WRLOCK;
- *pid = getpid();
- return (TRUE);
- }
-
- if (cfg_rdlock(cfg)) {
- *lock = CFG_RDLOCK;
- *pid = getpid();
- return (TRUE);
- }
- }
- /* Lock is always based on local file pointer */
- cfg->cf[1].cf_lock = cfg->cf[0].cf_lock = cfg->cf[0].cf_fd;
-
- bzero(&lk, sizeof (lk));
- lk.l_type = F_WRLCK;
- lk.l_whence = SEEK_SET;
- lk.l_start = (off_t)0;
- lk.l_len = (off_t)0;
-
- if (fcntl(cfg->cf[0].cf_lock, F_GETLK, &lk) < 0)
- rc = FALSE;
- else {
- if (lk.l_type == F_UNLCK)
- rc = FALSE;
- else {
- rc = TRUE;
- *pid = lk.l_pid;
- *lock = lk.l_type == F_WRLCK ? CFG_WRLOCK : CFG_RDLOCK;
- }
- }
-
- return (rc);
-}
-
-/*
- * cfg_commit
- * Write modified version of header, configuration and persistent
- * data using 2 stage commit.
- * If no valid data is found in header, it is assumed to be an initial
- * write and we will create the default header (could be dangerous)
- * another tricky part, if we are doing an upgrade we may be dealing
- * with an old database. we need to take care seeking and writing
- * until such time that it is upgraded.
- *
- * Mutual exclusion is checked using cfg_lock
- */
-
-int
-cfg_commit(CFGFILE *cfg)
-{
- cfp_t *cfp;
- int rc;
- time_t tloc;
- int section;
- int wrsize, *ip;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (FALSE);
- }
-
- if (!cfg_wrlock(cfg))
- return (FALSE);
-
- /* Determine number of files open */
- for (cfp = &cfg->cf[0]; cfp <= &cfg->cf[1]; cfp++) {
- if (!cfp->cf_fd)
- continue;
-
- /*
- * lets put everything back into one char *
- */
- cfg_replace_lists(cfp);
-
- if ((*cfp->cf_pp->seek)(cfp, 0, SEEK_SET) < 0) {
-#ifdef DEBUG_LIB
- (void) fprintf(stderr, "cfg: seek header failed\n");
-#endif
- return (FALSE);
- }
-
- cfp->cf_head->h_size = cfp->cf_head->h_parsesize
- + cfp->cf_head->h_csize + cfp->cf_head->h_psize;
- cfp->cf_head->h_stamp = time(&tloc);
-
- /* seeking into database */
- if ((*cfp->cf_pp->seek)(cfp, sizeof (cfgheader_t),
- SEEK_CUR) < 0)
- return (FALSE);
-
- if (cfp->cf_head->h_ccopy1 == cfp->cf_head->h_cparse) {
- if (cfp->cf_head->h_seq1 < 0)
- cfp->cf_head->h_seq1 = 1;
- else
- cfp->cf_head->h_seq1 = cfp->cf_head->h_seq2 + 1;
- section = 1;
- } else {
- if (cfp->cf_head->h_seq2 < 0)
- cfp->cf_head->h_seq2 = 1;
- else
- cfp->cf_head->h_seq2 = cfp->cf_head->h_seq1 + 1;
- section = 2;
- }
-#ifdef DEBUG_LIB
- dump_status(cfp, "cfg_commit");
-#endif
- rc = (*cfp->cf_pp->write)(cfp, cfp->cf_mapped,
- CFG_DEFAULT_PARSE_SIZE);
-#ifdef DEBUG
- if (rc < 0) {
- (void) fprintf(stderr,
- "parse commit: rc %d h_parsesize %d\n",
- rc, cfp->cf_head->h_parsesize);
- }
-#endif
- if (section == 1) {
- rc = (*cfp->cf_pp->write) (cfp, cfp->cf_head->h_ccopy1,
- cfp->cf_head->h_csize);
-#ifdef DEBUG
- if (rc < 0) {
- (void) fprintf(stderr,
- "csection commit 1: rc %d h_csize %d\n",
- rc, cfp->cf_head->h_csize);
- }
-#endif
- if ((*cfp->cf_pp->seek)
- (cfp, (2 * CFG_DEFAULT_SSIZE) - rc, SEEK_CUR) < 0)
- return (FALSE);
-
- /*
- * limit the write to only what we need
- */
- ip = cfp->cf_head->h_sizes1;
- for (wrsize = 0; *ip; ip += *ip + 1)
- wrsize += *ip + 1;
-
- rc = (*cfp->cf_pp->write)(cfp, cfp->cf_head->h_sizes1,
- wrsize * sizeof (int));
-#ifdef DEBUG
- if (rc < 0) {
- (void) fprintf(stderr,
- "cfg: write list sizes1 failed rc\n");
- }
-#endif
- } else {
- if ((*cfp->cf_pp->seek)(cfp, CFG_DEFAULT_SSIZE,
- SEEK_CUR) < 0)
- return (FALSE);
-
- rc = (*cfp->cf_pp->write)(cfp, cfp->cf_head->h_ccopy2,
- cfp->cf_head->h_csize);
-#ifdef DEBUG
- if (rc < 0) {
- (void) fprintf(stderr,
- "csection commit 2: rc %d h_csize %d\n",
- rc, cfp->cf_head->h_csize);
- }
-#endif
- if ((*cfp->cf_pp->seek)
- (cfp, (CFG_DEFAULT_SSIZE + CFG_DEFAULT_PSIZE) - rc,
- SEEK_CUR) < 0)
- return (FALSE);
-
- /*
- * limit the write to only what we need
- */
- ip = cfp->cf_head->h_sizes2;
- for (wrsize = 0; *ip; ip += *ip + 1)
- wrsize += *ip + 1;
-
- rc = (*cfp->cf_pp->write)(cfp, cfp->cf_head->h_sizes2,
- wrsize * sizeof (int));
-#ifdef DEBUG
- if (rc < 0) {
- (void) fprintf(stderr,
- "cfg: write list sizes2 failed\n");
- }
-#endif
-
- }
-
-
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr,
- "writing h_csize %d\n", cfp->cf_head->h_csize);
-#endif
- if ((*cfp->cf_pp->seek)(cfp, 0, SEEK_SET) < 0)
- return (FALSE);
-
- cfp->cf_head->h_size = cfp->cf_head->h_parsesize +
- cfp->cf_head->h_csize + cfp->cf_head->h_psize;
-
- rc = (*cfp->cf_pp->write)(cfp, cfp->cf_head,
- sizeof (cfgheader_t));
- if (rc < 0) {
- cfg_perror_str = dgettext("cfg",
- "cfg_commit: header write failed");
- cfg_severity = CFG_EFATAL;
- return (FALSE);
- }
- }
-
- return (TRUE);
-}
-
-/*
- * cfg_rewind
- * rewind internal file pointer for specified section
- * empty now, rewind not necessary. But don't break
- * old code.
- */
-/*ARGSUSED*/
-void
-cfg_rewind(CFGFILE *cfg, int section)
-{
- switch (section) {
- case CFG_SEC_CONF:
- break;
- case CFG_SEC_ALL:
- break;
- };
-}
-
-/*
- * cfg_location
- * set or return the default location file to
- * determine the partition name of the configuration partition
- * location is stored in well known file location
- */
-char *
-cfg_location(char *location, int mode, char *altroot)
-{
- int fd;
- int fmode;
- int rc;
- char wellknown[NSC_MAXPATH];
- char loc[NSC_MAXPATH];
-
- if (mode == CFG_LOC_GET_LOCAL) {
- return (CFG_LOCAL_LOCATION);
- } else if (mode == CFG_LOC_GET_CLUSTER) {
- fmode = O_RDONLY;
- } else {
- fmode = O_RDWR | O_CREAT;
- }
-
- if (altroot) {
- strcpy(wellknown, altroot);
- strcat(wellknown, CFG_CLUSTER_LOCATION);
- } else
- strcpy(wellknown, CFG_CLUSTER_LOCATION);
-
- fd = open(wellknown, fmode, 0644);
- if (fd < 0) {
- cfg_perror_str = dgettext("cfg", strerror(errno));
- cfg_severity = CFG_ENONFATAL;
- return (NULL);
- }
-
- if (mode == CFG_LOC_SET_CLUSTER) {
- if (location == NULL || (strlen(location) > NSC_MAXPATH)) {
- cfg_perror_str = dgettext("cfg",
- "cfg_location: filename too big or missing");
- cfg_severity = CFG_EFATAL;
- return (NULL);
- }
-
- /*
- * 5082142
- * If we're in a cluster, make sure that the config location
- * is a raw device. Using non-raw did devices in a cluster
- * can result in data corruption, since inconsistent data
- * may reside in the block cache on one node, but has not
- * been flushed to disk.
- */
- if (cfg_iscluster() > 0) {
- struct stat dscfg_stat;
- if (stat(location, &dscfg_stat) != 0) {
- cfg_perror_str = dgettext("cfg",
- "Unable to access dscfg location");
- cfg_severity = CFG_EFATAL;
- return (NULL);
- }
- if (!S_ISCHR(dscfg_stat.st_mode)) {
- cfg_perror_str = dgettext("cfg",
- "dscfg location must be a raw device");
- cfg_severity = CFG_EFATAL;
- return (NULL);
- }
- }
-
- if (ftruncate(fd, 0) < 0)
- return (NULL);
-
- rc = write(fd, location, strlen(location));
- if (rc < 0) {
- cfg_perror_str = dgettext("cfg",
- "cfg_location: write to well known failed");
- cfg_severity = CFG_EFATAL;
- return (NULL);
- }
- bzero(config_file, sizeof (config_file));
- }
- if (lseek(fd, 0, SEEK_SET) < 0)
- return (NULL);
-
- bzero(config_file, sizeof (config_file));
- rc = read(fd, config_file, sizeof (config_file));
- if (rc < 0) {
- cfg_perror_str = dgettext("cfg",
- "cfg_location: read from well known failed");
- cfg_severity = CFG_EFATAL;
- return (NULL);
- }
- close(fd);
- if (altroot) {
- strcpy(loc, altroot);
- strcat(loc, config_file);
- bzero(config_file, sizeof (config_file));
- strcpy(config_file, loc);
- }
-
- /*
- * scan string out of config_file, to strip whitespace
- */
- sscanf(config_file, "%s", loc);
- strcpy(config_file, loc);
-
- return (config_file);
-}
-
-/*
- * cfg_update_parser_config
- * If tag and key exist return -1
- *
- * XXX Currently does not append new field to existing parser rule
- */
-
-int
-cfg_update_parser_config(CFGFILE *cfg, const char *key, int section)
-{
- cfp_t *cfp;
- int size;
- char buf[CFG_MAX_BUF];
- struct parser *tbl;
- char tmpkey[CFG_MAX_KEY];
- char *ky, *fld;
- errno = 0;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
-
- cfp = FP_SUN_CLUSTER(cfg);
- if (!cfg_wrlock(cfg))
- return (-1);
-
- bzero(buf, CFG_MAX_BUF);
- bzero(tmpkey, sizeof (tmpkey));
- strcpy(tmpkey, key);
- if (section == CFG_PARSE_CONF) {
- strcat(buf, "C:");
- tbl = chead;
- } else {
- errno = EINVAL;
- return (-1);
- }
- ky = strtok(tmpkey, ".");
- fld = strtok(NULL, ".");
- while (fld) {
- size = cfg_get_item(tbl, ky, fld);
-
- /*
- * Assure we are loading a clean table, with do duplicates
- * based on our File Descriptor
- */
- if (chead_loaded && (chead_loaded != cfp->cf_fd)) {
- if (size <= 0)
- return (-1);
- } else {
- if (size > 0)
- return (-1);
- }
- fld = strtok(NULL, ".");
- }
- size = strlen(key) + 2;
- strncat(buf, key, size);
-#ifdef DEBUG_LIB
- (void) fprintf(stderr, "update parser config %s size %d\n", buf, size);
-#endif
- if ((size + cfp->cf_head->h_parseoff) > CFG_DEFAULT_PARSE_SIZE) {
- cfg_perror_str = dgettext("cfg",
- "cfg_update_parser_config: header overrun");
- cfg_severity = CFG_EFATAL;
-#ifdef DEBUG_LIB
- (void) fprintf(stderr, "update parser config: "
- "overrun siz %d poff %d parsesize %d\n",
- size, cfp->cf_head->h_parseoff, cfp->cf_head->h_parsesize);
-#endif
- errno = E2BIG;
- return (-1);
- }
- bcopy(buf, (cfp->cf_mapped + cfp->cf_head->h_parseoff), size);
- cfp->cf_head->h_parseoff += size;
- cfp->cf_head->h_state |= CFG_HDR_INVALID;
- if (cfp->cf_mapped[cfp->cf_head->h_parseoff - 1] != '\n') {
- cfp->cf_mapped[cfp->cf_head->h_parseoff] = '\n';
- cfp->cf_head->h_parseoff++;
- }
- cfp->cf_head->h_parsesize = cfp->cf_head->h_parseoff;
- cfg_read_parser_config(cfp);
- return (TRUE);
-}
-/*
- * cfg_read_parser_config
- * reads parser config from file
- * converts it to internal tree for parsing
- * chead for configuration parser entries
- *
- */
-static
-void
-cfg_read_parser_config(cfp_t *cfp)
-{
- struct lookup *p, *q;
- struct parser *thead;
- int off, foff;
- char *part;
- char *key;
- char *fld;
- int fldnum;
- char c;
- char buf[CFG_MAX_BUF];
- int i = 0;
- int n = 0;
-
- off = foff = 0;
- /*CONSTCOND*/
- while (TRUE) {
- off = 0;
- bzero(buf, CFG_MAX_BUF);
- /* LINTED it assigns value to c */
- while (c = cfp->cf_mapped[foff++]) {
- if (c == '\n')
- break;
- buf[off++] = c;
- }
- part = strtok(buf, ":");
- if (!part)
- break;
- if (*part == 'C') {
- thead = chead;
- n = i;
- }
- key = strtok(NULL, ".");
- if (!key)
- break;
- strcpy(thead[n].tag.l_word, key);
- thead[n].tag.l_value = 0;
- thead[n].fld = NULL;
- fldnum = 1;
- while ((fld = strtok(NULL, ".")) != NULL) {
- p = thead[n].fld;
- if (p == NULL) {
- q = thead[n].fld = calloc(1,
- sizeof (struct lookup));
- } else {
- for (q = thead[n].fld; q; q = q->l_next)
- p = q;
- q = calloc(1, sizeof (struct lookup));
- p->l_next = q;
- }
- strcpy(q->l_word, fld);
- q->l_value = fldnum;
- q->l_next = NULL;
-#ifdef DEBUG_EXTRA
- (void) fprintf(stderr,
- "read parser: q: word %s value %d\n",
- q->l_word, q->l_value);
-#endif
- fldnum++;
- }
- if (*part == 'C')
- i++;
- }
-
- /* All done, indicate parser table is loaded */
- if (i && (chead_loaded == 0))
- chead_loaded = cfp->cf_fd;
-
- /*
- * before I go and alloc, why am I here?
- * do I need a bunch of cfglists, or do I just
- * need to accommodate a just added parser entry
- * if the latter, we already have a base, just set
- * i to the index of the cfg which members need allocing
- */
- if ((cfp->cf_head->h_cfgs == NULL) ||
- (cfp->cf_head->h_cfgs[n-1].l_entry == NULL)) {
- cfp->cf_head->h_cfgs = (cfglist_t *)calloc(MAX_CFG,
- sizeof (cfglist_t));
- i = 0;
- }
- else
- i = n;
-
- if (cfp->cf_head->h_cfgs) {
-
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr, "alloced %d cfg lists \n", n + 1);
-#endif
- for (cfp->cf_head->h_ncfgs = n + 1;
- i < min(cfp->cf_head->h_ncfgs, MAX_CFG); i++) {
- cfp->cf_head->h_cfgs[i].l_name = '\0';
- cfp->cf_head->h_cfgs[i].l_name =
- strdup(chead[i].tag.l_word);
- cfp->cf_head->h_cfgs[i].l_index = i;
- cfp->cf_head->h_cfgs[i].l_entry =
- calloc(DEFAULT_ENTRY_SIZE, sizeof (char));
- cfp->cf_head->h_cfgs[i].l_nentry = 0;
- cfp->cf_head->h_cfgs[i].l_esiz =
- calloc(DEFAULT_NENTRIES, sizeof (int));
- cfp->cf_head->h_cfgs[i].l_size = 0;
- cfp->cf_head->h_cfgs[i].l_free = DEFAULT_ENTRY_SIZE;
- if ((cfp->cf_head->h_cfgs[i].l_entry == NULL) ||
- (cfp->cf_head->h_cfgs[i].l_esiz == NULL)) {
- cfg_perror_str = dgettext("cfg", "unable to"
- " allocate cfglist members");
- cfg_severity = CFG_EFATAL;
- }
- }
- } else {
- cfg_perror_str = dgettext("cfg", "unable to alloc cfglist");
- cfg_severity = CFG_EFATAL;
- }
-}
-
-/*
- * cfg_map_cfglists()
- * go through list of list sizes in header
- * and create separate lists
- */
-int
-cfg_map_cfglists(cfp_t *cfp)
-{
- int i;
- int offset = 0;
- int *ip;
- int list_size = 0;
- int slot_inc;
- char *p;
- cfgheader_t *ch;
-
- ch = cfp->cf_head;
- p = ch->h_cparse;
-
- /* get the first list size */
- ip = ch->h_sizes;
-
- for (i = 0; i < min(ch->h_ncfgs, MAX_CFG); i++) {
- if (ch->h_cfgsizes[i] > 0) {
- if (ch->h_cfgsizes[i] > DEFAULT_ENTRY_SIZE) {
-
- ch->h_cfgs[i].l_entry = (char *)
- realloc(ch->h_cfgs[i].l_entry,
- ch->h_cfgsizes[i] * sizeof (char));
- /* set free to 0, we'll get more when we add */
- ch->h_cfgs[i].l_free = 0;
-
- } else
- ch->h_cfgs[i].l_free -= ch->h_cfgsizes[i];
-
- /* get lists and marry up to each cfgs structure */
-
-
- list_size = *ip;
- ip++;
-
- if (list_size > DEFAULT_NENTRIES) {
- /*
- * we're gonna need more slots
- * we want to alloc on DEFAULT_NENTRIES
- * boundry. ie. always a multiple of it
- * later on, when we add to the list
- * we can see if we need to add by mod'ding
- * l_nentry and DEFAULT_NENTRIES and check for 0
- */
- slot_inc = DEFAULT_NENTRIES -
- (list_size % DEFAULT_NENTRIES);
- if (slot_inc == DEFAULT_NENTRIES)
- slot_inc = 0; /* addcfline reallocs */
-
- ch->h_cfgs[i].l_esiz = (int *)realloc(
- ch->h_cfgs[i].l_esiz,
- (list_size + slot_inc) * sizeof (int));
- }
- memcpy(ch->h_cfgs[i].l_esiz, ip,
- list_size * sizeof (int));
-
- ch->h_cfgs[i].l_nentry = list_size;
-
- ip += list_size;
-
- } else
-
- continue;
-
- if (ch->h_cfgs[i].l_entry != NULL) {
- p = ch->h_cparse + offset;
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr, "mapping list %d size %d offset %d, addr 0x%x\n",
- i, ch->h_cfgsizes[i], offset, p);
-#endif
- memcpy(ch->h_cfgs[i].l_entry,
- p, ch->h_cfgsizes[i]);
- ch->h_cfgs[i].l_size = ch->h_cfgsizes[i];
- offset += ch->h_cfgsizes[i];
- } else {
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr, "NULL l_entry\n");
-#endif
- return (-1);
- }
- }
-
-
- return (1);
-
-}
-
-void
-cfg_replace_lists(cfp_t *cfp)
-{
- int i;
- int offset = 0;
- int size_offset = 0;
-
- int section = 0;
- cfgheader_t *cf;
- cfglist_t *cfl;
-
- cf = cfp->cf_head;
-
- if ((cfl = cfp->cf_head->h_cfgs) == NULL)
- return;
-
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr, "cfg_replace_lists\n");
-#endif
-
- if (cf->h_cparse == cf->h_ccopy1)
- section = 1;
-
- /*
- * check to see if we are using copy1 or 2,
- * grow or shrink the size, fix h_cparse reference
- * in case realloc gave us a funky new address.
- * put stuff in it.
- */
- cf->h_ccopy1 = (char *)
- realloc(cf->h_ccopy1, cf->h_csize * sizeof (char));
- cf->h_ccopy2 = (char *)
- realloc(cf->h_ccopy2, cf->h_csize * sizeof (char));
- if (section == 1) {
- /* we used copy1 */
- cf->h_cparse = cf->h_ccopy1;
- } else
- cf->h_cparse = cf->h_ccopy2;
-
- /*
- * just because, we'll zero out h_csize and recalc
- * after all, this is the number the next guy gets
- */
- cf->h_csize = cf->h_sizes[0] = 0;
- for (i = 0; i < MAX_CFG; i++) {
- /* only as many lists as chead has */
- if (chead[i].tag.l_word[0] == '\0') {
- break;
- }
- if (cfl[i].l_entry && cfl[i].l_entry[0] != '\0') {
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr,
- "copying list %d at %x size %d\n",
- i, cf->h_cparse + offset,
- cfl[i].l_size);
-#endif
- memcpy((cf->h_cparse + offset),
- cfl[i].l_entry, cfl[i].l_size);
- offset += cfl[i].l_size;
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr,
- "cfl[%d].l_nentry %d cfl[%d].l_esiz[%d] %d"
- " size offset %d\n",
- i, cfl[i].l_nentry, i, cfl[i].l_nentry - 1,
- cfl[i].l_esiz[cfl[i].l_nentry - 1], size_offset);
-#endif
- /*
- * first write the number of entries
- * then copy over the array ie.
- * a list with 5 elements would be copied
- * as a 6 element array slot 0 being the
- * number of elements
- */
- cf->h_sizes[size_offset++] = cfl[i].l_nentry;
- memcpy((cf->h_sizes + size_offset), cfl[i].l_esiz,
- cfl[i].l_nentry * sizeof (int));
- size_offset += cfl[i].l_nentry;
- cf->h_sizes[size_offset] = 0;
- }
- cf->h_csize += cfl[i].l_size;
- }
-}
-
-void
-cfg_free_cfglist(cfp_t *cfp)
-{
- int i;
-
- if (!cfp->cf_head || !cfp->cf_head->h_cfgs)
- return;
-
- for (i = 0; cfp->cf_head && i < MAX_CFG; i++) {
- if (cfp->cf_head->h_cfgs[i].l_entry) {
- free(cfp->cf_head->h_cfgs[i].l_entry);
- cfp->cf_head->h_cfgs[i].l_entry = NULL;
- }
-
- if (cfp->cf_head->h_cfgs[i].l_name) {
- free(cfp->cf_head->h_cfgs[i].l_name);
- cfp->cf_head->h_cfgs[i].l_entry = NULL;
- }
-
- if (cfp->cf_head->h_cfgs[i].l_esiz) {
- free(cfp->cf_head->h_cfgs[i].l_esiz);
- cfp->cf_head->h_cfgs[i].l_esiz = NULL;
- }
- }
-
- if (cfp->cf_head) {
- free(cfp->cf_head->h_cfgs);
- cfp->cf_head->h_cfgs = NULL;
- }
-}
-
-void
-cfg_free_parser_tree()
-{
- struct lookup *p = NULL;
- struct lookup *q = NULL;
- int i;
-
- for (i = 0; i < MAX_CFG; i++) {
- if (chead)
- p = chead[i].fld;
- while (p) {
- q = p->l_next;
- if (p) {
- free(p);
- p = NULL;
- }
- p = q;
- }
- }
- bzero(chead, MAX_CFG * sizeof (struct parser));
-}
-
-void
-cfg_close(CFGFILE *cfg)
-{
- cfp_t *cfp;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return;
- }
-
- /* Determine number of files open */
- for (cfp = &cfg->cf[0]; cfp <= &cfg->cf[1]; cfp++) {
- if (!cfp->cf_fd) continue;
-
- (*cfp->cf_pp->close)(cfp);
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr, "freeing cfglists\n");
-#endif
- cfg_free_cfglist(cfp);
-
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr, "freeing cfp->cf_mapped\n");
-#endif
- free(cfp->cf_mapped);
- cfp->cf_mapped = NULL;
-
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr,
- "freeing copy1, copy2, h_sizes and cf\n");
-#endif
- if (cfp->cf_head) {
- if (cfp->cf_head->h_ccopy1) {
- free(cfp->cf_head->h_ccopy1);
- cfp->cf_head->h_ccopy1 = NULL;
- }
- if (cfp->cf_head->h_ccopy2) {
- free(cfp->cf_head->h_ccopy2);
- cfp->cf_head->h_ccopy2 = NULL;
- }
- if (cfp->cf_head->h_sizes1) {
- free(cfp->cf_head->h_sizes1);
- cfp->cf_head->h_sizes1 = NULL;
- }
- if (cfp->cf_head->h_sizes2) {
- free(cfp->cf_head->h_sizes2);
- cfp->cf_head->h_sizes2 = NULL;
- }
-
- }
- if (cfp->cf_head)
- free(cfp->cf_head);
- }
-
- free(cfg);
- cfg = NULL;
- cfg_free_parser_tree();
-
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr, "cfg_close\n");
-#endif
-}
-
-
-char *
-cfg_get_resource(CFGFILE *cfg)
-{
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (NULL);
- }
-
- return (cfg->cf_node);
-}
-
-/*
- * cfg_resource
- * set or clear the cluster node filter for get/put
- */
-
-void
-cfg_resource(CFGFILE *cfg, const char *node)
-{
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return;
- }
-
- if (cfg->cf_node) {
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr,
- "cfg_resource: changing node from %s to %s\n",
- cfg->cf_node, (node?node:"NULL"));
-#endif
- free(cfg->cf_node);
- cfg->cf_node = NULL;
- }
-
- /*
- * just in case someone passes in a non-NULL
- * node, but has no valid value
- */
- if ((node) && (node[0] != '\0')) {
- cfg->cf_node = strdup(node);
- }
-}
-
-/*
- * cfg_open
- * Open the current configuration file
- */
-CFGFILE *
-cfg_open(char *name)
-{
- CFGFILE *cfg;
- cfp_t *cfp;
- int32_t magic;
- long needed;
- int rc;
-
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr, "cfg_open\n");
-#endif
-
- cfg_severity = 0;
- if ((cfg = (CFGFILE *)calloc(1, sizeof (*cfg))) == NULL) {
- cfg_perror_str = dgettext("cfg",
- "cfg_open: malloc failed");
- cfg_severity = CFG_EFATAL;
- return (NULL);
- }
-
- cfp = &cfg->cf[0];
- if ((name) && strlen(name)) {
-#ifdef DEBUG
- (void) fprintf(stderr, "cfg_open: Using non-standard name\n");
-#endif
- cfp->cf_name = name;
- cfp->cf_pp = (strstr(cfp->cf_name, "/rdsk/") == NULL) ?
- cfg_block_io_provider() : cfg_raw_io_provider();
- } else {
- cfp->cf_name = cfg_location(NULL, CFG_LOC_GET_LOCAL, NULL);
- cfp->cf_pp = cfg_block_io_provider();
-
- /* Handle cfg_open(""), which is an open from boot tools */
- if (name)
- cl_initialized = 1;
- if (cfg_iscluster() > 0) {
- cfp = &cfg->cf[1];
- cfp->cf_name =
- cfg_location(NULL, CFG_LOC_GET_CLUSTER, NULL);
- if (cfp->cf_name) {
- cfp->cf_pp = cfg_raw_io_provider();
- }
- }
- }
-
- /*
- * Open one or two configuration files
- */
- for (cfp = &cfg->cf[0]; cfp->cf_name && (cfp <= &cfg->cf[1]); cfp++) {
- if ((*cfp->cf_pp->open)(cfp, cfp->cf_name) == NULL) {
- cfg_perror_str = dgettext("cfg",
- "cfg_open: unable to open configuration location");
- cfg_severity = CFG_EFATAL;
- break;
- }
-
- /* block device smaller than repository? */
- rc = (*cfp->cf_pp->read)(cfp, &magic, sizeof (magic));
- if (rc < sizeof (magic)) {
- cfg_perror_str = dgettext("cfg",
- "cfg_open: unable to read configuration header");
- cfg_severity = CFG_EFATAL;
- break;
- }
-
- if ((*cfp->cf_pp->seek)(cfp, 0, SEEK_SET) < 0) {
- cfg_perror_str = dgettext("cfg",
- "cfg_open: unable to seek configuration header");
- cfg_severity = CFG_EFATAL;
- break;
- }
-
- /*
- * we can't enforce size rules on an old database
- * so check the magic number before we test for size
- */
- if (magic == CFG_NEW_MAGIC) {
- needed = FBA_NUM(FBA_SIZE(1) - 1 +
- (sizeof (struct cfgheader) + CFG_CONFIG_SIZE));
- } else {
- needed = 0;
- }
-
- if (cfp->cf_size < needed) {
- cfg_perror_str = dgettext("cfg",
- "cfg_open: configuration file too small");
- cfg_severity = CFG_EFATAL;
- errno = ENOMEM;
- break;
- }
-
- cfp->cf_mapped = (char *)malloc(CFG_DEFAULT_PARSE_SIZE);
- if (cfp->cf_mapped == NULL) {
- cfg_perror_str = dgettext("cfg",
- "cfg_open: malloc failed");
- cfg_severity = CFG_EFATAL;
- break;
- }
-
- bzero(cfp->cf_mapped, CFG_DEFAULT_PARSE_SIZE);
- cfp->cf_lock = -1;
- }
-
- /* Processing errors, take care of one or more cfp pointers */
- if (cfg_severity && (cfp <= &cfg->cf[1])) {
- cfp = &cfg->cf[0];
- if (cfp->cf_fd)
- (*cfp->cf_pp->close)(cfp);
- cfp = &cfg->cf[1];
- if (cfp->cf_fd)
- (*cfp->cf_pp->close)(cfp);
- free(cfg);
- return (NULL);
- }
-
- cfg_lockd = cfg_lockd_init();
-
-
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr, "cfg_open ok\n");
-#endif
- return (cfg);
-}
-
-void
-cfg_invalidate_hsizes(int fd, const char *loc)
-{
- int offset;
- int rc = -1;
- int hdrsz;
-
- char buf[2 * CFG_DEFAULT_PSIZE];
-
- hdrsz = sizeof (cfgheader_t) + 512 -
- (sizeof (cfgheader_t) % 512);
-
- offset = hdrsz + CFG_DEFAULT_PARSE_SIZE +
- (CFG_DEFAULT_SSIZE * 2);
-
- if (cfg_shldskip_vtoc(fd, loc) > 0)
- offset += CFG_VTOC_SKIP;
-
- bzero(buf, sizeof (buf));
-
- if (lseek(fd, offset, SEEK_SET) > 0)
- rc = write(fd, buf, sizeof (buf));
- if (rc < 0)
- (void) fprintf(stderr, "cfg: invalidate hsizes failed\n");
-
-}
-
-char *
-cfg_error(int *severity)
-{
- if (severity != NULL)
- *severity = cfg_severity;
- return (cfg_perror_str ? cfg_perror_str : CFG_EGENERIC);
-}
-/*
- * cfg_cfg_isempty
- */
-int
-cfg_cfg_isempty(CFGFILE *cfg)
-{
- cfp_t *cfp;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (FALSE);
- }
-
- cfp = FP_SUN_CLUSTER(cfg);
- if (cfp->cf_head->h_csize == 0)
- return (TRUE);
- else
- return (FALSE);
-}
-
-/*
- * cfg_get_num_entries
- * return the number of entries in a given section of database
- * sndr, ii, ndr_ii...
- */
-int
-cfg_get_num_entries(CFGFILE *cfg, char *section)
-{
- int count = 0;
- int table_offset;
- cfp_t *cfp;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
-
- if ((table_offset = cfg_get_parser_offset(section)) < 0) {
- errno = ESRCH;
- return (-1);
- }
-
- /* Determine number of files open */
- for (cfp = &cfg->cf[0]; cfp->cf_fd && (cfp <= &cfg->cf[1]); cfp++)
- count += cfp->cf_head->h_cfgs[table_offset].l_nentry;
-
- return (count);
-}
-
-/*
- * cfg_get_section
- * all etries in a config file section is placed in
- * buf, allocation is done inside
- * freeing buf is responisbility of the caller
- * number of entries in section is returned
- * -1 on failure, errno is set
- */
-int
-cfg_get_section(CFGFILE *cfg, char ***list, const char *section)
-{
- int table_offset;
- int i, count;
- cfglist_t *cfl;
- char *p = NULL;
- char **buf;
- cfp_t *cfp;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (FALSE);
- }
-
- if ((table_offset = cfg_get_parser_offset(section)) < 0) {
- errno = ESRCH;
- return (-1);
- }
-
- /* Determine number of files open */
- count = 0;
- for (cfp = &cfg->cf[0]; cfp <= &cfg->cf[1]; cfp++) {
- if (!cfp->cf_fd) continue;
- if (cfp->cf_head->h_state & CFG_HDR_INVALID) {
- if (!cfg_read(cfp)) {
- cfg_perror_str = dgettext("cfg", CFG_RDFAILED);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
- }
-
- cfl = &cfp->cf_head->h_cfgs[table_offset];
- if (cfl->l_nentry == 0) /* empty list */
- continue;
-
- if (count == 0)
- buf = (char **)malloc(cfl->l_nentry * sizeof (char *));
- else
- buf = (char **)realloc(buf, (cfl->l_nentry + count) *
- sizeof (char *));
- if (buf == NULL) {
- errno = ENOMEM;
- return (-1);
- } else {
- bzero(&buf[count], cfl->l_nentry * sizeof (char *));
- }
-
- p = cfl->l_entry;
- for (i = 0; i < cfl->l_nentry; i++) {
- if ((buf[i + count] = strdup(p)) == NULL) {
- errno = ENOMEM;
- return (-1);
- }
- p += cfl->l_esiz[i];
- }
- count += cfl->l_nentry;
- }
-
- *list = buf;
- return (count);
-}
-
-/*
- * cluster upgrade helper functions. These support old database operations
- * while upgrading nodes on a cluster.
- */
-
-/*
- * returns the list of configured tags
- * return -1 on error, else the number
- * of tags returned in taglist
- * caller frees
- */
-int
-cfg_get_tags(CFGFILE *cfg, char ***taglist)
-{
- char **list;
- int i = 0;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
-
- if (!cfg_rdlock(cfg)) {
- return (-1);
- }
- list = calloc(1, MAX_CFG * sizeof (char *));
- if (list == NULL) {
- errno = ENOMEM;
- return (-1);
- }
-
- while ((i < MAX_CFG) && (chead[i].tag.l_word[0] != '\0')) {
- list[i] = strdup(chead[i].tag.l_word);
- if (list[i] == NULL) {
- for (/* CSTYLE */; i >= 0; i--) {
- if (list[i])
- free(list[i]);
- }
- free(list);
- errno = ENOMEM;
- return (-1);
- }
- i++;
- }
- *taglist = list;
- return (i);
-
-}
-
-/*
- * is this a database?
- * check the header for the magic number
- * 0 no match 1 match, -1 on error
- */
-int
-cfg_is_cfg(CFGFILE *cfg)
-{
- int32_t magic;
- int rc;
- cfp_t *cfp = FP_SUN_CLUSTER(cfg);
-
- rc = (cfp->cf_pp->read)(cfp, &magic, sizeof (magic));
- if (rc < sizeof (magic)) {
- cfg_perror_str = dgettext("cfg", "Fail to read configuration");
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
-
- if (magic == CFG_NEW_MAGIC)
- return (1);
-
- cfg_perror_str = dgettext("cfg",
- "configuration not initialized, bad magic");
- cfg_severity = CFG_EFATAL;
-
- return (0);
-}
-
-int
-compare(const void* a, const void *b)
-{
- char *p;
- char *pbuf;
- char *q;
- char *qbuf;
- int needed;
- int cmp;
- int pos;
-
- pbuf = strdup(a);
- qbuf = strdup(b);
-
- if (!qbuf || !pbuf)
- return (0);
-
- pos = 1;
- needed = sortby.offset;
-
- p = strtok(pbuf, " ");
- while (p) {
- if (needed == pos) {
- break;
- }
- p = strtok(NULL, " ");
- if (!p)
- break;
- pos++;
- }
-
- pos = 1;
- q = strtok(qbuf, " ");
- while (q) {
- if (needed == pos) {
- break;
- }
- q = strtok(NULL, " ");
- if (!q)
- break;
- pos++;
- }
- if (!p || !q) {
- sortby.comperror++;
- free(pbuf);
- free(qbuf);
- return (0);
- }
- cmp = strcmp(p, q);
- free(pbuf);
- free(qbuf);
- return (cmp);
-
-
-}
-/*
- * cfg_get_srtdsec
- * returns the section, sorted by supplied field
- * caller frees mem
- */
-int
-cfg_get_srtdsec(CFGFILE *cfg, char ***list, const char *section,
- const char *field)
-{
- cfglist_t *cfl;
- cfp_t *cfp;
- char **buf;
- char *tmplst;
- char *p, *q;
- int table_offset;
- int count, i;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (FALSE);
- }
-
- if ((table_offset = cfg_get_parser_offset(section)) < 0) {
- cfg_perror_str = dgettext("cfg", CFG_RDFAILED);
- errno = ESRCH;
- return (-1);
- }
-
- /*
- * do essentially what get_section does,
- * except stick entries in a static size
- * buf to make things easier to qsort
- */
- count = 0;
- for (cfp = &cfg->cf[0]; cfp <= &cfg->cf[1]; cfp++) {
- if (!cfp->cf_fd) continue;
- if (cfp->cf_head->h_state & CFG_HDR_INVALID) {
- if (!cfg_read(cfp)) {
- cfg_perror_str = dgettext("cfg", CFG_RDFAILED);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
- }
-
- cfl = &cfp->cf_head->h_cfgs[table_offset];
- if (cfl->l_nentry == 0) /* empty list */
- continue;
-
- if (count == 0)
- buf = (char **)malloc(cfl->l_nentry * sizeof (char *));
- else
- buf = (char **)realloc(buf, (cfl->l_nentry + count) *
- sizeof (char *));
- if (buf == NULL) {
- errno = ENOMEM;
- cfg_perror_str = dgettext("cfg", "cfg_get_srtdsec: "
- "malloc failed");
- cfg_severity = CFG_EFATAL;
- return (-1);
- } else {
- bzero(&buf[count], cfl->l_nentry * sizeof (char *));
- }
-
- /*
- * allocate each line
- */
- for (i = count; i < cfl->l_nentry + count; i++) {
- buf[i] = calloc(1, CFG_MAX_BUF);
- if (buf[i] == NULL) {
- free(buf);
- errno = ENOMEM;
- return (-1);
- }
- }
-
- if (count == 0)
- tmplst = (char *)malloc(cfl->l_nentry * CFG_MAX_BUF);
- else
- tmplst = (char *)realloc(tmplst,
- (cfl->l_nentry + count) * CFG_MAX_BUF);
- if (tmplst == NULL) {
- cfg_perror_str = dgettext("cfg", "cfg_get_srtdsec: "
- "malloc failed");
- cfg_severity = CFG_EFATAL;
- free(buf);
- return (-1);
- } else {
- bzero(&tmplst[count], cfl->l_nentry * CFG_MAX_BUF);
- }
-
- /*
- * put the section in tmplst and sort
- */
- p = &tmplst[count];
- q = cfl->l_entry;
- for (i = 0; i < cfl->l_nentry; i++) {
- bcopy(q, p, cfl->l_esiz[i]);
- p += CFG_MAX_BUF;
- q += cfl->l_esiz[i];
- }
- count += cfl->l_nentry;
- }
-
- bzero(sortby.section, CFG_MAX_KEY);
- bzero(sortby.field, CFG_MAX_KEY);
-
- strcpy(sortby.section, section);
- strcpy(sortby.field, field);
- sortby.comperror = 0;
- sortby.offset = cfg_get_item(&chead[0], section, field);
-
- qsort(tmplst, count, CFG_MAX_BUF, compare);
-
- if (sortby.comperror) {
- sortby.comperror = 0;
- cfg_perror_str = dgettext("cfg", "cfg_get_srtdsec: "
- "comparison error");
- cfg_severity = CFG_ENONFATAL;
- cfg_free_section(&buf, cfl->l_nentry);
- free(tmplst);
- *list = NULL;
- return (-1);
- }
-
- p = tmplst;
- for (i = 0; i < count; i++) {
- bcopy(p, buf[i], CFG_MAX_BUF);
- p += CFG_MAX_BUF;
- }
-
- free(tmplst);
- *list = buf;
- return (count);
-}
-
-/*
- * free an array alloc'd by get_*section
- * or some other array of size size
- */
-
-void
-cfg_free_section(char ***section, int size)
-{
- int i;
- char **secpp = *section;
-
- for (i = 0; i < size; i++) {
- if (secpp[i]) {
- free(secpp[i]);
- secpp[i] = NULL;
- }
- }
- if (secpp) {
- free(secpp);
- secpp = NULL;
- }
- section = NULL;
-}
-
-
-int
-cfg_shldskip_vtoc(int fd, const char *loc)
-{
- struct vtoc vtoc;
- struct stat sb;
- int slice;
- int rfd;
- char char_name[PATH_MAX];
- char *p;
-
- if (fstat(fd, &sb) == -1) {
- cfg_perror_str = dgettext("cfg", "unable to stat config");
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
- if (S_ISREG(sb.st_mode))
- return (0);
-
- if (S_ISCHR(sb.st_mode)) {
- if ((slice = read_vtoc(fd, &vtoc)) < 0)
- return (-1);
-
- if (vtoc.v_part[slice].p_start < CFG_VTOC_SIZE)
- return (1);
- else
- return (0);
- }
-
- if (S_ISBLK(sb.st_mode)) {
- p = strstr(loc, "/dsk/");
- if (p == NULL)
- return (-1);
- strcpy(char_name, loc);
- char_name[strlen(loc) - strlen(p)] = 0;
- strcat(char_name, "/rdsk/");
- strcat(char_name, p + 5);
-
- if ((rfd = open(char_name, O_RDONLY)) < 0) {
- return (-1);
- }
- if ((slice = read_vtoc(rfd, &vtoc)) < 0) {
- close(rfd);
- return (-1);
- }
- close(rfd);
- if (vtoc.v_part[slice].p_start < CFG_VTOC_SIZE)
- return (1);
- else
- return (0);
- }
-
- return (-1);
-}
-
-/*
- * comapares incore header with one on disk
- * returns 0 if equal, 1 if not, -1 error
- */
-int
-cfg_hdrcmp(cfp_t *cfp)
-{
- cfgheader_t *dskhdr, *memhdr;
- int rc;
-
- if ((dskhdr = calloc(1, sizeof (*dskhdr))) == NULL) {
- cfg_perror_str = dgettext("cfg", "cfg_hdrcmp: No memory");
- cfg_severity = CFG_ENONFATAL;
- }
-
- if ((*cfp->cf_pp->seek)(cfp, 0, SEEK_SET) < 0) {
- cfg_perror_str = dgettext("cfg", "cfg_hdrcmp: seek failed");
- cfg_severity = CFG_ENONFATAL;
- free(dskhdr);
- return (-1);
- }
-
- rc = (*cfp->cf_pp->read)(cfp, (char *)dskhdr, sizeof (*dskhdr));
- if (rc < 0) {
- cfg_perror_str = dgettext("cfg", "cfg_hdrcmp: read failed");
- cfg_severity = CFG_ENONFATAL;
- free(dskhdr);
- return (-1);
- }
-
- memhdr = cfp->cf_head;
-
- if ((memhdr->h_seq1 == dskhdr->h_seq1) &&
- (memhdr->h_seq2 == dskhdr->h_seq2))
- rc = 0;
- else
- rc = 1;
-
-
- free(dskhdr);
- return (rc);
-}
diff --git a/usr/src/lib/libdscfg/common/cfg.h b/usr/src/lib/libdscfg/common/cfg.h
deleted file mode 100644
index 84e64b8ebe..0000000000
--- a/usr/src/lib/libdscfg/common/cfg.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _CFG_H
-#define _CFG_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/nsctl/nsctl.h>
-
-#define CFG_MAX_BUF 1024 /* maximum buffer size for cfg_get_?string() */
-#define CFG_MAX_KEY 256 /* maximum key size for cfg_get_?string() */
-
-#ifndef _CFG_IMPL_H
-/*
- * These are really declared in cfg_impl.h, declare as dummy's here to
- * allow clients to compile without including cfg_impl.h.
- */
-typedef struct cfgfile CFGFILE;
-typedef struct cfp cfp_t;
-
-#endif /* _CFG_IMPL_H */
-
-int cfg_get_cstring(CFGFILE *cfg, const char *key, void *value, int value_len);
-int cfg_put_cstring(CFGFILE *cfg, const char *key, void *value, int value_len);
-int cfg_find_cstring(CFGFILE *cfg, const char *target, const char *section,
- int numflds, ...);
-int cfg_get_options(CFGFILE *cfg, int section, const char *basekey,
- char *tag, int tag_len, char *val, int val_len);
-int cfg_put_options(CFGFILE *cfg, int section, const char *basekey,
- char *tag, char *val);
-int cfg_get_single_option(CFGFILE *, int, const char *, char *, char *, int);
-int cfg_del_option(CFGFILE *, int, const char *, char *);
-
-int cfg_get_num_entries(CFGFILE *cfg, char *section);
-
-int cfg_get_tags(CFGFILE *cfg, char ***taglist);
-
-int cfg_cfg_isempty(CFGFILE *cfg);
-int cfg_get_section(CFGFILE *cfg, char ***buf, const char *section);
-CFGFILE *cfg_open(char *filename);
-void cfg_rewind(CFGFILE *cfg, int section);
-int cfg_is_cfg(CFGFILE *cfg);
-int cfg_shldskip_vtoc(int fd, const char *loc);
-int cfg_get_srtdsec(CFGFILE *cfg, char ***list,
- const char *sec, const char *field);
-void cfg_free_section(char ***, int);
-
-
-/*
- * Handle cluster configuration
- */
-#define FP_SUN_CLUSTER(x) \
- (((x->cf_node) && (x->cf[1].cf_fd)) ? &x->cf[1] : &x->cf[0])
-
-/*
- * rewind sections
- */
-#define CFG_SEC_CONF 0 /* configuration section */
-#define CFG_SEC_PERS 1 /* persistent section */
-#define CFG_SEC_ALL 2 /* rewind both sections */
-
-int cfg_update_parser_config(CFGFILE *, const char *key, int section);
-/*
- * parser sections
- */
-#define CFG_PARSE_CONF 0 /* config section key */
-#define CFG_PARSE_PERS 1 /* persistent section key */
-
-char *cfg_error(int *severity);
-/*
- * error codes
- */
-#define CFG_ENONFATAL 0 /* non fatal error */
-#define CFG_EFATAL 1 /* fatal error exit */
-
-/*
- * some error strings
- */
-#define CFG_NOTLOCKED "Configuration not locked"
-#define CFG_RDFAILED "Unable to read configuration"
-#define CFG_EINVAL "Invalid Argument"
-#define CFG_EGENERIC "Generic cfg failure"
-
-
-char *cfg_location(char *location, int mode, char *altroot);
-
-/*
- * location modes
- */
-#define CFG_LOC_SET_LOCAL 0
-#define CFG_LOC_GET_LOCAL 1
-#define CFG_LOC_SET_CLUSTER 2
-#define CFG_LOC_GET_CLUSTER 3
-
-/*
- * location strings
- */
-#define CFG_LOCAL_LOCATION "/etc/dscfg_local"
-#define CFG_CLUSTER_LOCATION "/etc/dscfg_cluster"
-
-void cfg_close(CFGFILE *);
-
-/*
- * lock mode
- */
-typedef enum {
- CFG_RDLOCK,
- CFG_WRLOCK,
- CFG_UPGRADE
-} CFGLOCK;
-
-int cfg_lock(CFGFILE *, CFGLOCK); /* lock the configuration */
-void cfp_unlock(cfp_t *); /* unlock the configuration */
-void cfg_unlock(CFGFILE *);
-int cfg_get_lock(CFGFILE *, CFGLOCK *, pid_t *); /* get config lock */
-
-int cfg_commit(CFGFILE *);
-void cfg_resource(CFGFILE *, const char *); /* Set/clear cluster node */
-char *cfg_get_resource(CFGFILE *); /* get current cluster node */
-char *cfg_dgname(const char *, char *, size_t); /* parse dg from pathname */
-char *cfg_l_dgname(const char *, char *, size_t); /* parse dg from pathname */
-int cfg_dgname_islocal(char *, char **); /* find locality of dg */
-int cfg_iscluster(void); /* running in a cluster? */
-int cfg_issuncluster(void); /* running in a Sun Cluster? */
-void cfg_invalidate_sizes(int);
-
-/*
- * add/rem result codes
- */
-#define CFG_USER_ERR 1
-#define CFG_USER_OK 2
-#define CFG_USER_FIRST 3
-#define CFG_USER_LAST 4
-#define CFG_USER_GONE 5
-#define CFG_USER_REPEAT 6
-
-int cfg_add_user(CFGFILE *, char *, char *, char *); /* add volume user */
-int cfg_rem_user(CFGFILE *, char *, char *, char *); /* remove vol user */
-int cfg_vol_enable(CFGFILE *, char *, char *, char *); /* enable volume */
-int cfg_vol_disable(CFGFILE *, char *, char *, char *); /* disable volume */
-
-int cfg_load_dsvols(CFGFILE *); /* load dsvol: section */
-void cfg_unload_dsvols(); /* unload dsvol: section */
-int cfg_load_svols(CFGFILE *); /* load sv: section */
-void cfg_unload_svols(); /* unload sv: section */
-int cfg_load_shadows(CFGFILE *); /* load shadows & bitmaps from ii: */
-void cfg_unload_shadows(); /* unload ii: */
-
-int cfg_get_canonical_name(CFGFILE *, const char *, char **);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _CFG_H */
diff --git a/usr/src/lib/libdscfg/common/cfg_cluster.c b/usr/src/lib/libdscfg/common/cfg_cluster.c
deleted file mode 100644
index c94b12c91e..0000000000
--- a/usr/src/lib/libdscfg/common/cfg_cluster.c
+++ /dev/null
@@ -1,582 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * This file contains the glue code that allows the NWS software to
- * determine whether a cluster disk service is local to this node or
- * not.
- *
- * See PSARC/1999/462 for more information on the interfaces from
- * suncluster that are used here.
- */
-
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/mkdev.h>
-#include <sys/stat.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <strings.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <dlfcn.h>
-
-#include <sys/ncall/ncall.h>
-#include <sys/nsctl/nsc_hash.h>
-
-#include "cfg_cluster.h"
-#include "cfg_impl.h"
-#include "cfg.h"
-
-/*
- * Static variables
- */
-
-static scconf_nodeid_t cl_nodeid = (uint_t)0xffff;
-static char *cl_nodename = NULL;
-
-static void *libscstat;
-static void *libscconf;
-
-static hash_node_t **schash;
-static int init_sc_entry();
-
-typedef struct hash_data_s {
- scstat_node_name_t scstat_node_name;
-} hash_data_t;
-
-/*
- * Global variables
- */
-int cl_initialized = 0;
-
-
-/*
- * Tell the linker to keep quiet.
- */
-
-#pragma weak scconf_get_nodename
-#pragma weak scconf_strerr
-#pragma weak scconf_get_ds_by_devt
-
-#pragma weak scstat_get_ds_status
-#pragma weak scstat_free_ds_status
-#pragma weak scstat_strerr
-
-
-/*
- * Initialise the library if we have not done so before.
- *
- * - IMPORTANT -
- *
- * This must -never- be called from any command that can be started
- * from /usr/cluster/lib/sc/run_reserve (and hence
- * /usr/cluster/sbin/reconfig) or the system will deadlock
- * during switchover. This includes:
- *
- * - svadm (no options, "print") -- called during sv switchover
- * - all boot commands
- *
- * - grab this node's cluster nodeid
- * - attempt to dlopen() the suncluster shared libraries we need
- * - grab this node's cluster nodename
- *
- * Returns:
- * 0 - success
- * -1 - error, errno is set
- */
-
-int
-cfg_cluster_init(void)
-{
- const char *scconf = "/usr/cluster/lib/libscconf.so.1";
- const char *scstat = "/usr/cluster/lib/libscstat.so.1";
-#ifdef DEBUG
- char errbuf[SCCONF_MAXSTRINGLEN];
-#endif
- scconf_nodeid_t id;
- scconf_errno_t err;
- char *name;
- FILE *pipe;
- int rc;
-
- /*
- * First check to see if we really are a cluster as clinfo -n can lie
- */
- if (cl_nodeid == 0xffff) {
- rc = system("/usr/sbin/clinfo");
- if (rc != -1 && WEXITSTATUS(rc) == 1) {
- /* not a cluster */
- cl_initialized = 1;
- cl_nodeid = 0;
- return (0);
- }
-
- pipe = popen("/usr/sbin/clinfo -n 2>/dev/null || echo 0", "r");
- if (pipe == NULL) {
-#ifdef DEBUG
- fprintf(stderr, "unable to get nodeid: %s\n",
- strerror(errno));
-#endif
- return (-1);
- }
-
- if ((rc = fscanf(pipe, "%d", &id)) != 1) {
-#ifdef DEBUG
- fprintf(stderr, "unable to get nodeid: %s\n",
- strerror(errno));
-#endif
- return (-1);
- }
-
- pclose(pipe);
-
- cl_nodeid = id;
- }
-
- /* Already loaded the Sun Cluster device tree */
- if (cl_initialized)
- return (0);
-
- /*
- * Try and dlopen the various libraries that we need
- */
-
- libscconf = dlopen(scconf, RTLD_LAZY | RTLD_GLOBAL);
- if (libscconf == NULL)
- goto error;
-
- libscstat = dlopen(scstat, RTLD_LAZY | RTLD_GLOBAL);
- if (libscstat == NULL)
- goto error;
-
- err = scconf_get_nodename(id, &name);
- if (err == SCCONF_EPERM) {
- cl_nodename = NULL;
- } else if (err != SCCONF_NOERR) {
-#ifdef DEBUG
- scconf_strerr(errbuf, err);
- fprintf(stderr, "scconf_get_nodename: %d: %s\n", err, errbuf);
-#endif
- goto error;
- } else
- cl_nodename = name;
-
- /* Load the Sun Cluster device tree */
- init_sc_entry();
- cl_initialized = 1;
- return (0);
-
-error: /* error cleanup */
- if (libscconf)
- dlclose(libscconf);
-
- if (libscstat)
- dlclose(libscstat);
-
- libscconf = NULL;
- libscstat = NULL;
-
- errno = ENOSYS;
- return (-1);
-}
-
-
-/*
- * cfg_issuncluster()
- *
- * Description:
- * Return the SunCluster nodeid of this node.
- *
- * Returns:
- * >0 - running in a SunCluster (value is nodeid of this node)
- * 0 - not running in a cluster
- * -1 - failure; errno is set
- */
-
-int
-cfg_issuncluster()
-{
- if (cfg_cluster_init() >= 0)
- return ((int)cl_nodeid);
- else
- return (-1);
-}
-int
-cfg_iscluster()
-{
- return (cfg_issuncluster());
-}
-
-/*
- * cfg_l_dgname_islocal()
- * Check if disk group is local on a non-SunCluster.
- *
- * Returns as cfg_dgname_islocal().
- */
-#ifndef lint
-static int
-cfg_l_dgname_islocal(char *dgname, char **othernode)
-{
- const char *metaset = "/usr/sbin/metaset -s %s -o > /dev/null 2>&1";
- char command[1024];
- int rc;
-
- if (snprintf(command, sizeof (command), metaset, dgname) >=
- sizeof (command)) {
- errno = ENOMEM;
- return (-1);
- }
-
- rc = system(command);
- if (rc < 0) {
- return (-1);
- }
-
- if (WEXITSTATUS(rc) != 0) {
- if (othernode) {
- /* metaset doesn't tell us */
- *othernode = "unknown";
- }
-
- return (0);
- }
-
- return (1);
-}
-#endif
-
-/*
- * cfg_dgname_islocal(char *dgname, char **othernode)
- * -- determine if the named disk service is mastered on this node
- *
- * If the disk service is mastered on another node, that nodename
- * will be returned in othernode (if not NULL). It is up to the
- * calling program to call free() on this value at a later time to
- * free the memory allocated.
- *
- * Returns:
- * 1 - disk service is mastered on this node
- * 0 - disk service is not mastered on this node (*othernode set)
- * -1 - error (errno will be set)
- */
-
-int
-cfg_dgname_islocal(char *dgname, char **othernode)
-{
- hash_data_t *data;
-
- if (dgname == NULL || *dgname == '\0' || othernode == NULL) {
- errno = EINVAL;
- return (-1);
- }
-
- /* Handle non-cluster configurations */
- if (cfg_cluster_init() < 0) {
- return (-1);
- } else if (cl_nodeid == 0) {
- /* it has to be local */
- return (1);
- }
-
- /*
- * lookup the current diskgroup name
- */
- if (data = (hash_data_t *)nsc_lookup(schash, dgname)) {
- if (strcmp(data->scstat_node_name, cl_nodename)) {
- if (othernode)
- *othernode = strdup(data->scstat_node_name);
- return (0);
- } else {
- return (1);
- }
- } else {
- errno = ENODEV;
- return (-1);
- }
-}
-
-/*
- * cfg_l_dgname()
- * parse the disk group name from the a device pathname on a non-SunCluster.
- *
- * Returns as cfg_dgname().
- */
-
-char *
-cfg_l_dgname(const char *pathname, char *buffer, size_t buflen)
-{
- const char *dev = "/dev/";
- const char *vx = "vx/";
- const char *md = "md/";
- const char *dsk = "dsk/";
- const char *start, *cp;
- int ll, len, chkdsk;
-
- bzero(buffer, buflen);
- chkdsk = 0;
-
- ll = strlen(dev);
- if (strncmp(pathname, dev, ll) != 0) {
- /* not a device pathname */
- errno = EINVAL;
- return ((char *)NULL);
- }
-
- start = pathname + ll;
-
- if (strncmp(start, vx, (ll = strlen(vx))) == 0) {
- /*
- * Veritas --
- * /dev/vx/{r}dsk/dgname/partition
- */
-
- start += ll;
-
- ll = strlen(dsk);
-
- if (*start == 'r' && strncmp((start + 1), dsk, ll) == 0)
- start += ll + 1;
- else if (strncmp(start, dsk, ll) == 0)
- start += ll;
- else {
- /* no dgname */
- return (buffer);
- }
- } else {
- /* no dgname */
- return (buffer);
- }
-
- for (cp = start, len = 0; *cp != '\0' && *cp != '/'; cp++)
- len++; /* count length of dgname */
-
- if (*cp == '\0') {
- /* no dgname */
- return (buffer);
- }
-
-#ifdef DEBUG
- if (*cp != '/') {
- fprintf(stderr,
- "cfg_dgname: parse error: *cp = '%c', expected '/'\n", *cp);
- errno = EPROTO;
- return ((char *)NULL);
- }
-#endif
-
- if (chkdsk) {
- cp++; /* skip the NULL */
-
- ll = strlen(dsk);
-
- if ((*cp != 'r' || strncmp((cp + 1), dsk, ll) != 0) &&
- strncmp(cp, dsk, ll) != 0) {
- /* no dgname */
- return (buffer);
- }
- }
-
- if (len >= buflen) {
- errno = E2BIG;
- return ((char *)NULL);
- }
-
- (void) strncpy(buffer, start, len);
- return (buffer);
-}
-
-
-/*
- * cfg_dgname()
- * determine which cluster resource group the pathname belongs to, if any
- *
- * Returns:
- * NULL - error (errno is set)
- * ptr to NULL-string - no dgname
- * pointer to string - dgname
- */
-
-char *
-cfg_dgname(const char *pathname, char *buffer, size_t buflen)
-{
- scconf_errno_t conferr;
- char *dsname = NULL;
- struct stat stb;
-#ifdef DEBUG
- char errbuf[SCCONF_MAXSTRINGLEN];
-#endif
-
- bzero(buffer, buflen);
-
- if (pathname == NULL || *pathname == '\0') {
- errno = EINVAL;
- return ((char *)NULL);
- }
-
- /* Handle non-cluster configurations */
- if (cfg_cluster_init() < 0) {
- errno = EINVAL;
- return ((char *)NULL);
- } else if (cl_nodeid == 0) {
- /* must be local - return NULL-string dgname */
- return (buffer);
- }
-
- if (stat(pathname, &stb) < 0) {
- errno = EINVAL;
- return ((char *)NULL);
- }
-
- conferr = scconf_get_ds_by_devt(major(stb.st_rdev),
- minor(stb.st_rdev), &dsname);
-
- if (conferr == SCCONF_ENOEXIST) {
- return (buffer);
- } else if (conferr != SCCONF_NOERR) {
-#ifdef DEBUG
- scconf_strerr(errbuf, conferr);
- fprintf(stderr,
- "scconf_get_ds_by_devt: %d: %s\n", conferr, errbuf);
-#endif
- errno = EINVAL;
- return ((char *)NULL);
- }
-
- strncpy(buffer, dsname, buflen);
- free(dsname);
-
- return (buffer);
-}
-
-
-/*
- * init_sc_entry
- *
- * Add an entry into the sclist and the schash for future lookups.
- *
- * - IMPORTANT -
- *
- * This must -never- be called from any command that can be started
- * from /usr/cluster/lib/sc/run_reserve (and hence
- * /usr/cluster/sbin/reconfig) or the system will deadlock
- * during switchover. This includes:
- *
- * - svadm (no options, "print") -- called during sv switchover
- * - all boot commands
- *
- * Return values:
- * -1 An error occurred.
- * 0 Entry added
- * 1 Entry already exists.
- */
-static int
-init_sc_entry()
-{
- scstat_ds_node_state_t *dsn;
- scstat_ds_name_t dsname;
- scstat_ds_t *dsstatus, *dsp;
- scstat_errno_t err;
-#ifdef DEBUG
- char errbuf[SCCONF_MAXSTRINGLEN];
-#endif
-
- hash_data_t *hdp;
-
- /*
- * Allocate a hash table
- */
- if ((schash = nsc_create_hash()) == NULL)
- return (-1);
-
- /*
- * the API is broken here - the function is written to expect
- * the first argument to be (scstat_ds_name_t), but the function
- * declaration in scstat.h requires (scstat_ds_name_t *).
- *
- * We just cast it to get rid of the compiler warnings.
- * If "dsname" is NULL, information for all device services is returned
- */
- dsstatus = NULL;
- dsname = NULL;
- /* LINTED pointer alignment */
- err = scstat_get_ds_status((scstat_ds_name_t *)dsname, &dsstatus);
- if (err != SCSTAT_ENOERR) {
-#ifdef DEBUG
- scstat_strerr(err, errbuf);
- fprintf(stderr, "scstat_get_ds_status(): %d: %s\n",
- err, errbuf);
-#endif
- errno = ENOSYS;
- return (-1);
- }
-
- if (dsstatus == NULL) {
- errno = ENODEV;
- return (-1);
- }
-
- /*
- * Traverse scstat_ds list, saving away resource in out hash table
- */
- for (dsp = dsstatus; dsp; dsp = dsp->scstat_ds_next) {
-
- /* Skip over NULL scstat_ds_name's */
- if ((dsp->scstat_ds_name == NULL) ||
- (dsp->scstat_ds_name[0] == '\0'))
- continue;
-
- /* See element exits already, error if so */
- if (nsc_lookup(schash, dsp->scstat_ds_name)) {
- fprintf(stderr, "scstat_get_ds_status: duplicate %s",
- dsp->scstat_ds_name);
- errno = EEXIST;
- return (-1);
- }
-
- /* Traverse the node status list */
- for (dsn = dsp->scstat_node_state_list; dsn;
- dsn = dsn->scstat_node_next) {
- /*
- * Only keep trace of primary nodes
- */
- if (dsn->scstat_node_state != SCSTAT_PRIMARY)
- continue;
-
- /* Create an element to insert */
- hdp = (hash_data_t *)malloc(sizeof (hash_data_t));
- hdp->scstat_node_name = strdup(dsn->scstat_node_name);
- nsc_insert_node(schash, hdp, dsp->scstat_ds_name);
- }
- }
-
- /*
- * Free up scstat resources
- */
- scstat_free_ds_status(dsstatus);
- return (0);
-}
diff --git a/usr/src/lib/libdscfg/common/cfg_cluster.h b/usr/src/lib/libdscfg/common/cfg_cluster.h
deleted file mode 100644
index 56f07219f7..0000000000
--- a/usr/src/lib/libdscfg/common/cfg_cluster.h
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _CFG_CLUSTER_H
-#define _CFG_CLUSTER_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * This file is a combination of interfaces culled from scstat.h,
- * scconf.h and the header files that they include.
- *
- * It exposes a subset of the interfaces defined in PSARC/2001/261
- * for use in NWS software.
- */
-
-#include <sys/errno.h>
-#include <sys/types.h>
-
-/*
- * From sc_syslog_msg.h
- */
-
-typedef enum sc_state_code_enum {
- ONLINE = 1, /* resource is running */
- OFFLINE, /* resource is stopped due to user action */
- FAULTED, /* resource is stopped due to a failure */
- DEGRADED, /* resource is running but has a minor problem */
- WAIT, /* resource is in transition from a state to another */
-
- /*
- * resource is monitored but state of the resource is
- * not known because either the monitor went down or
- * the monitor cannot report resource state temporarily.
- */
- UNKNOWN,
-
- NOT_MONITORED /* There is no monitor to check state of the resource */
-} sc_state_code_t;
-
-/*
- * End sc_syslog_msg.h
- */
-
-
-/*
- * From scstat.h
- */
-
-#define SCSTAT_MAX_STRING_LEN 1024
-
-/* Error codes returned by scstat functions. */
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-typedef enum scstat_errno {
- SCSTAT_ENOERR, /* normal return - no error */
- SCSTAT_EUSAGE, /* syntax error */
- SCSTAT_ENOMEM, /* not enough memory */
- SCSTAT_ENOTCLUSTER, /* not a cluster node */
- SCSTAT_ENOTCONFIGURED, /* not found in CCR */
- SCSTAT_ESERVICENAME, /* dcs: invalid service name */
- SCSTAT_EINVAL, /* scconf: invalid argument */
- SCSTAT_EPERM, /* not root */
- SCSTAT_ECLUSTERRECONFIG, /* cluster is reconfiguring */
- SCSTAT_ERGRECONFIG, /* RG is reconfiguring */
- SCSTAT_EOBSOLETE, /* Resource/RG has been updated */
- SCSTAT_EUNEXPECTED /* internal or unexpected error */
-} scstat_errno_t;
-
-/* States a resource can be in */
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-typedef enum scstat_state_code {
- SCSTAT_ONLINE = ONLINE, /* resource is running */
- SCSTAT_OFFLINE = OFFLINE, /* resource stopped due to user action */
- SCSTAT_FAULTED = FAULTED, /* resource stopped due to a failure */
- SCSTAT_DEGRADED = DEGRADED, /* resource running with a minor problem */
- SCSTAT_WAIT = WAIT, /* resource is in transition */
- SCSTAT_UNKNOWN = UNKNOWN, /* resource state is unknown */
- SCSTAT_NOTMONITORED = NOT_MONITORED /* resource is not monitored */
-} scstat_state_code_t;
-
-/* States a replica of a resource can be in */
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-typedef enum scstat_node_pref {
- SCSTAT_PRIMARY, /* replica is a primary */
- SCSTAT_SECONDARY, /* replica is a secondary */
- SCSTAT_SPARE, /* replica is a spare */
- SCSTAT_INACTIVE, /* replica is inactive */
- SCSTAT_TRANSITION, /* replica is changing state */
- SCSTAT_INVALID /* replica is in an invalid state */
-} scstat_node_pref_t;
-
-/* component name */
-typedef char *scstat_name_t;
-typedef scstat_name_t scstat_cluster_name_t; /* cluster name */
-typedef scstat_name_t scstat_node_name_t; /* node name */
-typedef scstat_name_t scstat_adapter_name_t; /* adapter name */
-typedef scstat_name_t scstat_path_name_t; /* path name */
-typedef scstat_name_t scstat_ds_name_t; /* device service name */
-typedef scstat_name_t scstat_quorumdev_name_t; /* quorum device name */
-typedef scstat_name_t scstat_rs_name_t; /* resource name */
-typedef scstat_name_t scstat_rg_name_t; /* rg name */
-
-/* status string */
-typedef char *scstat_statstr_t;
-typedef scstat_statstr_t scstat_node_statstr_t; /* node status */
-typedef scstat_statstr_t scstat_path_statstr_t; /* path status */
-typedef scstat_statstr_t scstat_ds_statstr_t; /* DS status */
-typedef scstat_statstr_t scstat_node_quorum_statstr_t; /* node quorum status */
-typedef scstat_statstr_t scstat_quorumdev_statstr_t; /* quorum device stat */
-
-/* ha device node status list */
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-typedef struct scstat_ds_node_state_struct {
- /* node name */
- scstat_node_name_t scstat_node_name;
- /* node status */
- scstat_node_pref_t scstat_node_state;
- /* next */
- struct scstat_ds_node_state_struct *scstat_node_next;
-} scstat_ds_node_state_t;
-
-/* Cluster node status */
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-typedef struct scstat_node_struct {
- scstat_node_name_t scstat_node_name; /* node name */
- scstat_state_code_t scstat_node_status; /* cluster membership */
- scstat_node_statstr_t scstat_node_statstr; /* node status string */
- void *pad; /* Padding for */
- /* PSARC/2001/261. */
- struct scstat_node_struct *scstat_node_next; /* next */
-} scstat_node_t;
-
-/* Cluster ha device status */
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-typedef struct scstat_ds_struct {
- /* ha device name */
- scstat_ds_name_t scstat_ds_name;
- /* ha device status */
- scstat_state_code_t scstat_ds_status;
- /* ha device statstr */
- scstat_ds_statstr_t scstat_ds_statstr;
- /* node preference list */
- scstat_ds_node_state_t *scstat_node_state_list;
- /* next */
- struct scstat_ds_struct *scstat_ds_next;
-} scstat_ds_t;
-
-/*
- * scstat_strerr
- *
- * Map scstat_errno_t to a string.
- *
- * The supplied "errbuffer" should be of at least SCSTAT_MAX_STRING_LEN
- * in length.
- */
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-void scstat_strerr(scstat_errno_t, char *);
-
-/*
- * Upon success, a list of objects of scstat_node_t are returned.
- * The caller is responsible for freeing the space.
- *
- * Possible return values:
- *
- * SCSTAT_NOERR - success
- * SCSTAT_ENOMEM - not enough memory
- * SCSTAT_EPERM - not root
- * SCSTAT_ENOTCLUSTER - there is no cluster
- * SCCONF_EINVAL - invalid argument
- * SCSTAT_EUNEXPECTED - internal or unexpected error
- */
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-scstat_errno_t scstat_get_nodes(scstat_node_t **pplnodes);
-
-/*
- * Free all memory associated with a scstat_node_t structure.
- */
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-void scstat_free_nodes(scstat_node_t *plnodes);
-
-/*
- * If the device service name passed in is NULL, then this function returns
- * the status of all device services, otherwise it returns the status of the
- * device service specified.
- * The caller is responsible for freeing the space.
- *
- * Possible return values:
- *
- * SCSTAT_ENOERR - success
- * SCSTAT_ENOMEM - not enough memory
- * SCSTAT_EPERM - not root
- * SCSTAT_ENOTCLUSTER - there is no cluster
- * SCCONF_EINVAL - invalid argument
- * SCSTAT_ESERVICENAME - invalid device group name
- * SCSTAT_EUNEXPECTED - internal or unexpected error
- */
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-scstat_errno_t scstat_get_ds_status(scstat_ds_name_t *dsname,
- scstat_ds_t **dsstatus);
-
-/*
- * Free memory associated with a scstat_ds_t structure.
- */
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-void scstat_free_ds_status(scstat_ds_t *dsstatus);
-
-/*
- * End scstat.h
- */
-
-/*
- * From scconf.h
- */
-
-/* Maximum message string length */
-#define SCCONF_MAXSTRINGLEN 1024
-
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-typedef enum scconf_errno {
- SCCONF_NOERR = 0, /* normal return - no error */
- SCCONF_EPERM = 1, /* permission denied */
- SCCONF_EEXIST = 2, /* object already exists */
- SCCONF_ENOEXIST = 3, /* object does not exist */
- SCCONF_ESTALE = 4, /* object or handle is stale */
- SCCONF_EUNKNOWN = 5, /* unkown type */
- SCCONF_ENOCLUSTER = 6, /* cluster does not exist */
- SCCONF_ENODEID = 7, /* ID used in place of node name */
- SCCONF_EINVAL = 8, /* invalid argument */
- SCCONF_EUSAGE = 9, /* command usage error */
- SCCONF_ETIMEDOUT = 10, /* call timed out */
- SCCONF_EINUSE = 11, /* already in use */
- SCCONF_EBUSY = 12, /* busy, try again later */
- SCCONF_EINSTALLMODE = 13, /* install mode */
- SCCONF_ENOMEM = 14, /* not enough memory */
- SCCONF_ESETUP = 15, /* setup attempt failed */
- SCCONF_EUNEXPECTED = 16, /* internal or unexpected error */
- SCCONF_EBADVALUE = 17, /* bad ccr table value */
- SCCONF_EOVERFLOW = 18, /* message buffer overflow */
- SCCONF_EQUORUM = 19, /* operation would compromise quorum */
- SCCONF_TM_EBADOPTS = 20, /* bad transport TM "options" */
- SCCONF_TM_EINVAL = 21, /* other transport TM error */
- SCCONF_DS_ESUSPENDED = 22, /* Device service in suspended state */
- SCCONF_DS_ENODEINVAL = 23, /* Node specified is not in cluster */
- SCCONF_EAUTH = 24, /* authentication error */
- SCCONF_DS_EINVAL = 25, /* Device service in an invalid state */
- SCCONF_EIO = 26 /* IO error */
-} scconf_errno_t;
-
-/* IDs */
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-typedef uint_t scconf_id_t;
-
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-typedef scconf_id_t scconf_nodeid_t; /* node ID */
-
-/* Cluster transport handle */
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-typedef void * scconf_cltr_handle_t;
-
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-extern scconf_errno_t scconf_get_nodeid(char *nodename,
- scconf_nodeid_t *nodeidp);
-
-/*
- * Get the name of a node from its "nodeid". Upon success,
- * a pointer to the nodename is left in "nodenamep".
- *
- * It is the caller's responsibility to free memory allocated
- * for "nodename" using free(3C).
- *
- * Possible return values:
- *
- * SCCONF_NOERR - success
- * SCCONF_EPERM - not root
- * SCCONF_ENOCLUSTER - there is no cluster
- * SCCONF_ENOMEM - not enough memory
- * SCCONF_EINVAL - invalid argument
- * SCCONF_EUNEXPECTED - internal or unexpected error
- */
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-extern scconf_errno_t scconf_get_nodename(scconf_nodeid_t nodeid,
- char **nodenamep);
-
-/*
- * Map scconf_errno_t to a string.
- *
- * The supplied "errbuffer" should be of at least SCCONF_MAXSTRINGLEN
- * in length.
- */
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-extern void scconf_strerr(char *errbuffer, scconf_errno_t err);
-
-/*
- * Given a dev_t value, return the name of device service that contains this
- * device.
- *
- * The caller is responsible for freeing the memory returned in "name".
- *
- * Possible return values:
- *
- * SCCONF_NOERR - success
- * SCCONF_EPERM - not root
- * SCCONF_ENOEXIST - the given device is not configured
- * SCCONF_ENOMEM - not enough memory
- * SCCONF_ENOCLUSTER - cluster config does not exist
- * SCCONF_EUNEXPECTED - internal or unexpected error
- */
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-extern scconf_errno_t scconf_get_ds_by_devt(major_t maj, minor_t min,
- char **dsname);
-
-/*
- * End scconf.h
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _CFG_CLUSTER_H */
diff --git a/usr/src/lib/libdscfg/common/cfg_impl.h b/usr/src/lib/libdscfg/common/cfg_impl.h
deleted file mode 100644
index a972b2525f..0000000000
--- a/usr/src/lib/libdscfg/common/cfg_impl.h
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _CFG_IMPL_H
-#define _CFG_IMPL_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define MAX_CFG 16 /* Max. number of lines in /etc/dscfg_format */
-
-#define CFG_MAX_KEY 256
-#define CFG_MAX_BUF 1024
-#define CFG_BLOCK_SIZE 512
-#define CFG_VTOC_SIZE 16
-#define CFG_VTOC_SKIP CFG_VTOC_SIZE * CFG_BLOCK_SIZE
-
-/*
- * Parser and file handling routines for Configuration parser.
- *
- * General layout on disk
- *
- * header cfgheader_t
- * parser configuration tag.field1.field2\n
- * configuration data copy1 freeform strings
- * configuration data copy2 freeform strings
- *
- * Strings in freeform fields are seperated by whitespace.
- * End of entry seperated by null.
- */
-
-struct lookup {
- char l_word[CFG_MAX_KEY];
- int l_value;
- struct lookup *l_next;
-};
-
-struct parser {
- struct lookup tag;
- struct lookup *fld;
- struct parser *next;
-};
-
-
-/*
- * cfglist description
- *
- * ________
- * | | the header has (with other things) an array
- * | header | of h_cfg[n].l_size entries. index 4
- * disk layout | | contains cfp->cf_head->h_cfg[4].l_size.
- * |________|
- * cfgfile-mapped->| |
- * CFG_DEFAULT_PARSE_SIZE | parser | cache_hint.device.wrthru.nordcache.cnode
- * | |
- * |________|
- * cfp->cf_head->h_ccopy1>| |
- * CFG_DEFAULT_SSIZE | data | null terminated strings grouped together
- * | copy 1 | in order of cfglist offset. ie data at
- * |________| offset 0 is from h_cfgs[0].l_entry
- * cfp->cf_head->h_ccopy2>| |
- * CFG_DEFAULT_SSIZE | data |
- * | copy 2 | same as above, used for two stage commit
- * |________|
- * cfp->cf_head->h_sizes1>| | here is where lists of sizes go for each
- * CFG_DEFAULT_PSIZE | sizes | cfglist. each array is preceded by the num
- * | copy 1 | of entries. |5|120|130|140|103|125|10|25 is
- * |________| a list with 5 entries 120,130,140,103,125
- * cfp->cf_head->h_sizes2>| | these numbers are used to rebuild l_nentry
- * CFG_DEFAULT_PSIZE | sizes | and l_esiz fields in h_cfg[n]
- * | copy 2 | this list is done as a two stage commit
- * |________|
- *
- *
- *
- * Data is read into cfp->cf_head->h_ccopy1 and cfp->cf_head->h_ccopy2
- * along with thier corresponding size metadata in cfp->cf_head->h_sizes1
- * and cfp->cf_head->h_sizes2. This infomation is used to rebuild the
- * cfglist structures seen below. The data in the cfglist structure is then
- * the ONLY valid data. Additions and/or deletions to the database is done
- * by moving around the cfglists and doing the right things with the size
- * arrays, the actual entries, total list sizes, the total of all the sizes of
- * all the cfglists and memory allocation. After addition/deletions are done,
- * and cfg_close is called, all of the lists are placed back into h_cparse
- * (which is really h_ccopy1 or h_ccopy2) the persistent lists are placed
- * into h_sizes (which is really h_sizes1 or h_sizes2).
- * A copy of each cfglist[n].l_size is kept in the header
- * (cfgheader->cfgsizes[n]).
- *
- *
- *
- *
- * h_cfgs h_cfgs[3]
- * head |-[0]- /|-l_name == sndr
- * |- /|-[1]- / |-l_entry == host dev bmap host..ip sync '\0' ...
- * file |- / |-[2]- / |-l_esiz[0..l_nentry - 1] == [130, 132, 135, 133,..]
- * |--|---------|-[3]---- |-l_enabled[0..l_nentry - 1] == [1,0,0,1,1]
- * |- \ |-[4]- \ |-l_nentry == 5
- * |- \|-[5]- \ |-l_index == 3
- * |-[n]- \|-l_free == 50537
- * |-l_size == 663 (130 + 132 + 135 + 133 + 133)
- *
- *
- *
- * l_name - is set when the parser is read.
- * It is the first tag of a line of parser text.
- * l_entry - is a pointer to the beginning of the null terminated string
- * list that belongs to the cfglist tagged with l_name.
- * l_esiz - is a list of sizes of the strings contained in l_entry.
- * l_esiz[0] tells the size of the string at l_entry[0].
- * l_esiz[n] is the size of the string that begins
- * at l_entry + l_esiz[0] + l_esiz[1]..+ l_esize[n - 1]
- * l_enabled - is a list of ones and zeros telling if this entry is alive
- * in the kernel. indexing is the same as l_esiz. (not implemented)
- * l_index - is the index of the parser tree that corresponds to l_name
- * and is set when the parser tree is built
- * l_free - is how memory is managed. Memory is allocated on a
- * DEFAULT_ENTRY_SIZE boundry.
- * the size of the balance of available memory at the end of l_entry
- * is kept here. when this number is lower than the string we need to add,
- * another block of memory is allocated for l_entry and the balance of
- * the size is added to l_free.
- * l_size - is size of this list. It is the summation of l_esiz[0..n]
- *
- */
-
-typedef struct cfglist {
- char *l_name; /* name of list sndr, ii.. */
- char *l_entry; /* start of list */
- int *l_esiz; /* array of sizes of entries */
- int l_nentry; /* number of entries */
- int l_index; /* index in relation to parser position */
- uint_t l_free; /* num of characters available */
- int l_size; /* size of list */
-} cfglist_t;
-
-/* note: this does not imply DEFAULT_NENTRIES * DEFAULT_ENTRY_SIZE */
-#define DEFAULT_NENTRIES 100 /* value for l_esiz sizes array */
-#define DEFAULT_ENTRY_SIZE (50 * CFG_MAX_BUF) /* 50K for each l_entry */
-
-
-typedef struct cfgheader {
- int32_t h_magic;
- int h_state; /* State flag see below */
- time_t h_stamp; /* time stamp of last update */
- long h_lock; /* lock for update */
- long h_size; /* total file size */
- int h_parseoff; /* parser config offset */
- int h_parsesize; /* parser config size */
- char *h_cparse; /* start of configuration */
- int h_csize; /* size of config section */
- int h_acsize; /* size of alternate config section */
- int *h_sizes; /* sizes of lists */
- int h_psize; /* size of persistent section */
- int h_apsize; /* size of alternate persistent section */
- char *h_ccopy1; /* base of config section 1 */
- char *h_ccopy2; /* base of config section 2 */
- int *h_sizes1; /* sizes of lists on disk 1 */
- int *h_sizes2; /* sizes of lists on disk 2 */
- int h_seq1; /* Sequenece number copy 1 both sections */
- int h_seq2; /* Sequenece number copy 2 both sections */
- char h_ncfgs; /* number of cfgs */
- cfglist_t *h_cfgs; /* start of cfg lists */
- int h_cfgsizes[MAX_CFG]; /* Sizes of configs */
-} cfgheader_t;
-
-#define CFG_HDR_GOOD 0x1
-#define CFG_HDR_INVALID 0x2
-#define CFG_HDR_RDLOCK 0x4
-#define CFG_HDR_WRLOCK 0x8
-
-struct cfg_io_s; /* forward reference */
-typedef struct cfp {
- int cf_fd; /* file descriptor */
- int cf_flag; /* flags - see below */
- long cf_size; /* size of file in fbas */
- int cf_lock; /* lock file descriptor */
- char *cf_mapped; /* mapped location via mmap */
- char *cf_name; /* file name */
- cfgheader_t *cf_head; /* header */
- struct cfg_io_s *cf_pp; /* i/o provider */
-} cfp_t;
-
-typedef struct cfgfile {
- void *cf_node; /* node filter */
- cfp_t cf[2]; /* local & optional cluster file */
-} CFGFILE;
-
-typedef struct cfg_io_s {
- struct cfg_io_s *next; /* Link to next module */
- char *name; /* name of provider */
- cfp_t *(*open)(cfp_t *, char *); /* Open device */
- void (*close)(cfp_t *); /* Close device */
- int (*seek)(cfp_t *, int, int); /* Seek */
- int (*read)(cfp_t *, void *, int); /* read */
- int (*write)(cfp_t *, void *, int); /* write */
- char *(*readcf)(cfp_t *, char *, int, int); /* Read mem config */
- int (*addcf)(cfp_t *, char *, int); /* add to mem config */
- int (*remcf)(cfp_t *, int, int); /* remove an entry */
- int (*replacecf)(cfp_t *, char *, int, int); /* replace entry */
-} cfg_io_t;
-
-#define CFG_FILE 0x1 /* database is in a regular file */
-#define CFG_NOREWIND 0x4 /* don't rewind for each get_string */
-#define CFG_NOWRVTOC 0x8 /* sector starts in vtoc land, skip it */
-#define CFG_RDONLY 0x10 /* database is read only */
-
-/*
- * constants
- */
-#define CFG_RDEV_LOCKFILE "/var/tmp/.dscfg.lck"
-#define CFG_NEW_MAGIC 0x4d414749 /* MAGI */
-#define CFG_DEFAULT_PARSE_SIZE (16 * 1024)
-#define CFG_DEFAULT_SSIZE (2 * 1024 * 1024)
-#define CFG_DEFAULT_PSIZE (512 * 1024)
-#define CFG_DEFAULT_OLDSIZE (96 * 1024)
-#define CFG_CONFIG_SIZE (CFG_DEFAULT_PARSE_SIZE + \
- (2 * CFG_DEFAULT_SSIZE) + \
- (2 * CFG_DEFAULT_PSIZE))
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _CFG_IMPL_H */
diff --git a/usr/src/lib/libdscfg/common/cfg_local.c b/usr/src/lib/libdscfg/common/cfg_local.c
deleted file mode 100644
index 1b243b1a6d..0000000000
--- a/usr/src/lib/libdscfg/common/cfg_local.c
+++ /dev/null
@@ -1,653 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <stdio.h>
-
-#include <sys/types.h>
-#include <sys/vtoc.h>
-#include <sys/wait.h>
-#include <stdio.h>
-#include <sys/mnttab.h>
-#include <errno.h>
-#include <limits.h>
-#include <fcntl.h>
-#include <string.h>
-#include <strings.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/mman.h>
-
-#include <locale.h>
-#include <langinfo.h>
-#include <libintl.h>
-#include <stdarg.h>
-#include <netdb.h>
-#include <ctype.h>
-#include <sys/stat.h>
-#include <sys/utsname.h>
-
-#include "cfg_impl.h"
-#include "cfg.h"
-#include "cfg_local.h"
-
-#if 0
-#define DEBUG_CFGLIST
-#define DEBUG_CFGLISTRM
-#endif
-
-extern int cfg_severity;
-extern char *cfg_perror_str;
-
-long
-get_bsize(cfp_t *cfp, char *name)
-{
- char char_name[PATH_MAX];
- char *rest;
- struct vtoc vtoc;
- int slice;
- int fd;
-
- if (strlen(name) >= PATH_MAX - 1)
- return (0);
-
- rest = strstr(name, "/dsk/");
- if (rest == NULL) {
- if ((rest = strstr(name, "/rdsk/")) == NULL)
- return (0);
- strcpy(char_name, name);
- goto do_open;
-
- }
- strcpy(char_name, name);
- char_name[strlen(name) - strlen(rest)] = 0;
- strcat(char_name, "/rdsk/");
- strcat(char_name, rest + 5);
-
-do_open:
- fd = open(char_name, O_RDONLY);
- if (fd < 0)
- return (0);
-
- slice = read_vtoc(fd, &vtoc);
- if (slice < 0) {
- (void) close(fd);
- return (0);
- }
-
- (void) close(fd);
- if (vtoc.v_part[slice].p_start < CFG_VTOC_SIZE)
- cfp->cf_flag |= CFG_NOWRVTOC;
-
- return (vtoc.v_part[slice].p_size);
-}
-
-/*
- * round up to the next block size
- */
-int
-get_block_size(int size)
-{
- int ret;
-
- if (size % CFG_BLOCK_SIZE != 0)
- ret = size + CFG_BLOCK_SIZE - (size % CFG_BLOCK_SIZE);
- else
- ret = size;
- return (ret);
-}
-
-/*
- * get a chunk of mem rounded up to next block size
- */
-char *
-get_block_buf(int size)
-{
- int blk_size;
- char *blk_buf;
-
- blk_size = get_block_size(size);
-
- if ((blk_buf = (char *)calloc(blk_size, sizeof (char))) == NULL) {
- cfg_severity = CFG_EFATAL;
- cfg_perror_str = dgettext("cfg", strerror(errno));
- return (NULL);
- }
- return (blk_buf);
-}
-
-void
-free_block_buf(char *buf)
-{
- if (buf)
- free(buf);
-}
-
-void
-localcf_close(cfp_t *cfp)
-{
- fsync(cfp->cf_fd);
- cfp_unlock(cfp);
- close(cfp->cf_fd);
-}
-
-
-/*
- * cfg_open
- * Open the current configuration file
- * Sets file descriptor in cfp->cf_fd for use by other routines
- */
-cfp_t *
-localcf_open(cfp_t *cfp, char *name)
-{
- struct stat sb;
- int rc;
-
-
- if (name == NULL) {
- cfg_perror_str = dgettext("cfg",
- "cfg_open: unable to open configuration location");
- cfg_severity = CFG_EFATAL;
- return (NULL);
- }
-
- cfp->cf_fd = open(name, O_RDWR|O_CREAT|O_DSYNC|O_RSYNC, 0640);
- if (cfp->cf_fd == -1) {
- if ((cfp->cf_fd = open(name, O_RDONLY, 0640)) == -1) {
- cfg_perror_str = dgettext("cfg",
- "cfg_open: unable to open configuration location");
- cfg_severity = CFG_EFATAL;
- return (NULL);
- }
- cfp->cf_flag |= CFG_RDONLY;
- }
-
- if (fstat(cfp->cf_fd, &sb) == -1) {
- close(cfp->cf_fd);
- cfg_perror_str = dgettext("cfg",
- "cfg_open: unable to stat configuration location");
- cfg_severity = CFG_EFATAL;
- return (NULL);
- }
-
-
- if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) {
- cfp->cf_size = get_bsize(cfp, name);
-
- /* skip the vtoc if necessary */
- if (cfp->cf_flag & CFG_NOWRVTOC) {
- do {
- rc = lseek(cfp->cf_fd, CFG_VTOC_SKIP, SEEK_SET);
- } while (rc == -1 && errno == EINTR);
-
- if (rc == -1) {
- cfg_perror_str = dgettext("cfg",
- strerror(errno));
- cfg_severity = CFG_EFATAL;
- close(cfp->cf_fd);
- return (NULL);
- }
- }
-
- } else if (S_ISREG(sb.st_mode)) {
- cfp->cf_flag |= CFG_FILE;
- cfp->cf_size = FBA_NUM(FBA_SIZE(1) - 1 + sb.st_size);
- } else {
- cfg_perror_str = dgettext("cfg", "cfg_open: unknown file type");
- cfg_severity = CFG_EFATAL;
- close(cfp->cf_fd);
- cfp->cf_fd = NULL;
- return (NULL);
- }
- return (cfp);
-}
-
-int
-localcf_seekblk(cfp_t *cfp, int off, int mode)
-{
- int rc;
-
- do {
- rc = lseek(cfp->cf_fd, off, mode);
- } while (rc == -1 && errno == EINTR);
-
- return (rc);
-}
-
-int
-localcf_readblk(cfp_t *cfp, void *buf, int size)
-{
- int rc;
-
- do {
- rc = read(cfp->cf_fd, buf, size);
- } while (rc == -1 && errno == EINTR);
-
- return (rc);
-}
-
-int
-localcf_writeblk(cfp_t *cfp, void *buf, int size)
-{
- int rc;
-
- do {
- rc = write(cfp->cf_fd, buf, size);
- } while (rc == -1 && errno == EINTR);
-
- return (rc);
-}
-
-int
-localcf_seek(cfp_t *cfp, int off, int mode)
-{
- int rc;
- int offset;
-
- offset = get_block_size(off);
-
- if ((mode == SEEK_SET) && (cfp->cf_flag & CFG_NOWRVTOC)) {
- offset += CFG_VTOC_SKIP;
- }
-
- do {
- rc = lseek(cfp->cf_fd, offset, mode);
- } while (rc == -1 && errno == EINTR);
-
- return (rc);
-}
-
-int
-localcf_read(cfp_t *cfp, void *buf, int size)
-{
- int rc;
- int blk_size;
- char *blk_buf;
-
- blk_size = get_block_size(size);
- if ((blk_buf = get_block_buf(size)) == NULL)
- return (-1);
-
- do {
- rc = read(cfp->cf_fd, blk_buf, blk_size);
- } while (rc == -1 && errno == EINTR);
-
- bcopy(blk_buf, buf, size);
- free_block_buf(blk_buf);
-
- return (rc);
-}
-
-int
-localcf_write(cfp_t *cfp, void *buf, int size)
-{
- int rc;
- int blk_size;
- char *blk_buf;
-
- blk_size = get_block_size(size);
- if ((blk_buf = get_block_buf(size)) == NULL)
- return (-1);
-
- bcopy(buf, blk_buf, size);
-
- do {
- rc = write(cfp->cf_fd, blk_buf, blk_size);
- } while (rc == -1 && errno == EINTR);
-
- free_block_buf(blk_buf);
-
- return (rc);
-}
-/*
- * Routines which operate on internal version of configuration
- */
-
-/*
- * Add entry to end of configuration section
- */
-
-int
-addcfline(cfp_t *cfp, char *line, int table_index)
-{
- int len = strlen(line)+1;
- int newsize = DEFAULT_ENTRY_SIZE / 2;
- cfgheader_t *hd;
- cfglist_t *cfl;
- char *q;
-
-#ifdef DEBUG_CFGLIST
- fprintf(stderr, "addcfline: pre l_size %d h_cfgsizes[%d]"
- " %d l_free %u adding len %d\n",
- cfp->cf_head->h_cfgs[table_index].l_size, table_index,
- cfp->cf_head->h_cfgsizes[table_index],
- cfp->cf_head->h_cfgs[table_index].l_free, len);
-#endif
-
- hd = cfp->cf_head;
- cfl = &cfp->cf_head->h_cfgs[table_index];
- if (cfl->l_free < len) {
-
-#ifdef DEBUG_CFGLIST
- fprintf(stderr, "resizing l_entry from %d to %d\n",
- cfl->l_size + cfl->l_free, cfl->l_size +
- cfl->l_free + newsize);
-#endif
- cfl->l_entry = (char *)realloc(cfl->l_entry, (cfl->l_size +
- cfl->l_free + newsize) * sizeof (char));
- if (cfl->l_entry == NULL) {
- errno = ENOMEM;
- return (-1);
- }
- cfl->l_free += newsize;
-
- }
- cfl->l_free -= len;
-
- /* out of list slots, get some more */
- if (cfl->l_nentry % DEFAULT_NENTRIES == 0) {
- /*
- * first, figure out how much bigger, than realloc
- */
-
-#ifdef DEBUG_CFGLIST
- fprintf(stderr,
- "list %d getting more nentries, I have %d\n",
- table_index, cfl->l_nentry);
-#endif
- cfl->l_esiz = (int *)
- realloc(cfl->l_esiz, (cfl->l_nentry + DEFAULT_NENTRIES) *
- sizeof (int));
- if (cfl->l_esiz == NULL) {
- errno = ENOMEM;
- return (-1);
- }
- }
-
-
- cfl->l_esiz[cfl->l_nentry] = len;
- cfl->l_nentry++;
-
- /* add line to end of list */
- q = cfl->l_entry + cfl->l_size;
-
- strcpy(q, line);
- q += len;
-
- /* set sizes */
- hd->h_cfgs[table_index].l_size += len;
- hd->h_cfgsizes[table_index] = cfl->l_size;
- cfp->cf_head->h_csize += len;
-
-#ifdef DEBUG_CFGLIST
- fprintf(stderr, "addcfline: post l_size %d h_cfgsizes[%d]"
- " %d l_free %u\n h_csize %d\n",
- cfp->cf_head->h_cfgs[table_index].l_size,
- table_index, cfp->cf_head->h_cfgsizes[table_index],
- cfp->cf_head->h_cfgs[table_index].l_free, cfp->cf_head->h_csize);
-#endif
-
- return (1);
-}
-
-/*
- * remove entry from configuration section
- */
-int
-remcfline(cfp_t *cfp, int table_offset, int setnum)
-{
- cfgheader_t *ch;
- char *p, *q;
- int len;
- int copylen;
- int i;
- cfglist_t *cfl;
- ch = cfp->cf_head;
-
- cfl = &cfp->cf_head->h_cfgs[table_offset];
-
- q = cfl->l_entry;
-
- if (cfl->l_size == 0) {
- /* list is empty */
- return (-1);
- }
-
- if (!q) { /* somethings wrong here */
- return (-1);
- }
-
-
- for (i = 1; i < setnum; i++) {
- q += cfl->l_esiz[i - 1];
- if (i >= cfl->l_nentry) { /* end of list */
- return (-1);
- }
- }
-
- if (q >= cfl->l_entry + cfl->l_size)
- return (-1);
-
- len = cfl->l_esiz[i - 1];
-
-
-#ifdef DEBUG_CFGLISTRM
- fprintf(stderr, "remcfline: pre: l_size %d h_cfgsizes[%d] %d free %d"
- " removing len %d\n",
- ch->h_cfgs[table_offset].l_size, table_offset,
- ch->h_cfgsizes[table_offset],
- ch->h_cfgs[table_offset].l_free, len);
-#endif
-
- p = q + len; /* next string */
-
- if (!(p >= cfl->l_entry + cfl->l_size)) {
- /* if we didn't delete the last string in list */
- /* LINTED possible overflow */
- copylen = cfl->l_entry + cfl->l_size - p;
- bcopy(p, q, copylen);
- copylen = (cfl->l_nentry - i) * sizeof (int);
- bcopy(&cfl->l_esiz[i], &cfl->l_esiz[i - 1], copylen);
- }
-
- /* decrement the number of sets in this list */
- cfl->l_nentry--;
- /* not really necessary, but.. */
- cfl->l_esiz[cfl->l_nentry] = 0;
-
- cfl->l_size -= len;
- cfl->l_free += len;
-
- p = cfl->l_entry + cfl->l_size;
- bzero(p, cfl->l_free);
-
- ch->h_cfgsizes[table_offset] = cfl->l_size;
- ch->h_csize -= len;
-
-
-#ifdef DEBUG_CFGLIST
- fprintf(stderr,
- "remcfline: post: l_size %d h_cfgsizes[%d] %d free %d\n ",
- ch->h_cfgs[table_offset].l_size, table_offset,
- ch->h_cfgsizes[table_offset], ch->h_cfgs[table_offset].l_free);
-#endif
-
- return (0);
-
-}
-/*
- * Read entry from configuration section
- */
-char *
-readcfline(cfp_t *cfp, char *buf, int table_offset, int num)
-{
-
- char *q;
- int i;
- cfgheader_t *ch;
- cfglist_t *cfl;
-
- /* this means they couldn't even find it in the parser tree */
- if (table_offset < 0)
- return (NULL);
-
- ch = cfp->cf_head;
- cfl = &ch->h_cfgs[table_offset];
-
- q = cfl->l_entry;
-
- for (i = 1; i < num; i++) {
- q += cfl->l_esiz[i - 1];
- if (i >= cfl->l_nentry) /* end of list */
- return (NULL);
- }
-
- if (q >= cfl->l_entry + cfl->l_size)
- return (NULL);
- strcpy(buf, q);
- return (q);
-}
-
-
-/*
- * overwrite from current position with new value
- */
-int
-replacecfline(cfp_t *cfp, char *line, int table_offset, int num)
-{
-/*
- * take a table offset and a num to replace
- * index in, bump the list up, leaving a hole big
- * enough for the new string, or bcopying the rest of the list
- * down only leaving a hole big enough.
- * make sure not to overflow the
- * allocated list size.
- */
- cfgheader_t *ch;
- cfglist_t *cfl;
- char *p, *q;
- int len = strlen(line) + 1;
- int diff = 0;
- int i;
- int newsize = DEFAULT_ENTRY_SIZE / 2;
-
-
- ch = cfp->cf_head;
- cfl = &ch->h_cfgs[table_offset];
-
- q = cfl->l_entry;
- for (i = 1; i < num; i++) {
- q += cfl->l_esiz[i - 1];
- if (i >= cfl->l_nentry) /* end of list */
- return (-1);
- }
- diff = len - cfl->l_esiz[i - 1];
- /* check for > 0, comparing uint to int */
- if ((diff > 0) && (diff > cfl->l_free)) {
- /*
- * we are going to overflow, get more mem, but only
- * 1/2 as much as initial calloc, we don't need to be greedy
- */
-#ifdef DEBUG_CFGLIST
- fprintf(stderr,
- "resizing at replacecfline from %d to %d \n",
- cfl->l_size + cfl->l_free, cfl->l_size +
- cfl->l_free + newsize);
-#endif
- cfl->l_entry = (char *)realloc(cfl->l_entry,
- (cfl->l_size + cfl->l_free + newsize) * sizeof (char));
- if (cfl->l_entry == NULL) {
- errno = ENOMEM;
- return (-1);
- }
- cfl->l_free += (DEFAULT_ENTRY_SIZE / 2);
-
- /* re-find q, we could have a whole new chunk of memory here */
- q = cfl->l_entry;
- for (i = 1; i < num; i++) {
- q += cfl->l_esiz[i - 1];
- if (i >= cfl->l_nentry) /* end of list */
- return (-1);
- }
- }
-
- p = q + cfl->l_esiz[i - 1]; /* next string */
- cfl->l_esiz[i - 1] += diff; /* the new entry size */
- if (diff != 0) { /* move stuff over/back for correct fit */
- /* LINTED possible overflow */
- bcopy(p, p + diff, (cfl->l_entry + cfl->l_size - p));
- cfl->l_free -= diff; /* 0 - (-1) = 1 */
- cfl->l_size += diff;
-
- /* total of all h_cfgs[n].l_entry */
- cfp->cf_head->h_csize += diff;
- cfp->cf_head->h_cfgsizes[table_offset] = cfl->l_size; /* disk */
- bzero((cfl->l_entry + cfl->l_size), cfl->l_free);
- }
-
- strcpy(q, line);
- return (1);
-
-}
-
-static cfg_io_t _cfg_raw_io_def = {
- NULL,
- "Local",
- localcf_open,
- localcf_close,
- localcf_seek,
- localcf_read,
- localcf_write,
- readcfline,
- addcfline,
- remcfline,
- replacecfline,
-
-};
-
-static cfg_io_t _cfg_block_io_def = {
- NULL,
- "Local",
- localcf_open,
- localcf_close,
- localcf_seekblk,
- localcf_readblk,
- localcf_writeblk,
- readcfline,
- addcfline,
- remcfline,
- replacecfline,
-};
-
-cfg_io_t *
-cfg_raw_io_provider(void)
-{
- return (&_cfg_raw_io_def);
-}
-
-cfg_io_t *
-cfg_block_io_provider(void)
-{
- return (&_cfg_block_io_def);
-}
diff --git a/usr/src/lib/libdscfg/common/cfg_local.h b/usr/src/lib/libdscfg/common/cfg_local.h
deleted file mode 100644
index 5dff884baf..0000000000
--- a/usr/src/lib/libdscfg/common/cfg_local.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _CFG_LOCAL_H
-#define _CFG_LOCAL_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-char *readcfline(cfp_t *cfp, char *buf, int table_index, int offset);
-int addcfline(cfp_t *cfp, char *line, int table_index);
-int replacecfline(cfp_t *cfp, char *line, int table_index, int offset);
-int remcfline(cfp_t *cfp, int table_index, int offset);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _CFG_LOCAL_H */
diff --git a/usr/src/lib/libdscfg/common/cfg_lockd.h b/usr/src/lib/libdscfg/common/cfg_lockd.h
deleted file mode 100644
index 42fbc6d676..0000000000
--- a/usr/src/lib/libdscfg/common/cfg_lockd.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _CFG_LOCKD_H
-#define _CFG_LOCKD_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef enum { LOCK_NOTLOCKED, /* Unlock message */
- LOCK_READ, /* ask for read lock */
- LOCK_WRITE, /* ask for write lock */
- LOCK_LOCKED, /* lock has been taken */
- LOCK_LOCKEDBY, /* who has lock? */
- LOCK_STAT, /* ask daemon to print its state */
- LOCK_ACK /* acknowledge a notlocked msg */
- } cfglockd_t;
-
-typedef struct sockaddr_in daemonaddr_t;
-
-struct lock_msg {
- int32_t message;
- pid_t pid;
- int32_t order;
- uint8_t seq;
-};
-
-#define CFG_PIDFILE "/var/tmp/.cfglockd.pid"
-#define CFG_SERVER_PORT 50121u
-#define CFG_LF_EOF -1
-#define CFG_LF_OKAY 1
-#define CFG_LF_AGAIN 0
-void cfg_lfinit();
-int cfg_filelock(int segment, int flag);
-int cfg_fileunlock(int segment);
-void cfg_readpid(int segment, pid_t *pidp);
-void cfg_writepid(int segment, pid_t pid);
-void cfg_enterpid();
-int cfg_lockd_init();
-cfglockd_t cfg_lockedby(pid_t *);
-void cfg_lockd_rdlock();
-void cfg_lockd_wrlock();
-void cfg_lockd_unlock();
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _CFG_LOCKD_H */
diff --git a/usr/src/lib/libdscfg/common/cfg_lockdlck.c b/usr/src/lib/libdscfg/common/cfg_lockdlck.c
deleted file mode 100644
index 14f7cb4b1d..0000000000
--- a/usr/src/lib/libdscfg/common/cfg_lockdlck.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <signal.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <strings.h>
-#include <errno.h>
-#include <assert.h>
-
-#include "cfg_impl.h"
-#include "cfg_lockd.h"
-
-
-#define segment_off(s) ((off_t)(s) * sizeof (pid_t))
-
-static int local_lockfd;
-static int local_lockfda;
-
-void
-cfg_lfinit()
-{
- local_lockfd = open(CFG_RDEV_LOCKFILE, O_RDWR|O_CREAT, 0644);
- local_lockfda = open(CFG_RDEV_LOCKFILE, O_RDWR|O_APPEND, 0644);
-}
-
-int
-cfg_filelock(int segment, int flag)
-{
- struct flock lk;
- struct stat sb;
- pid_t pid = 0;
- off_t off = segment_off(segment);
- int rc;
-
- while (fstat(local_lockfd, &sb) == -1 && errno == EINTR)
- ;
- if (sb.st_size < off + sizeof (pid_t)) {
- if ((flag&O_CREAT) == 0)
- return (CFG_LF_EOF);
- write(local_lockfda, &pid, sizeof (pid_t));
- }
- bzero(&lk, sizeof (lk));
- lk.l_type = F_WRLCK;
- lk.l_whence = SEEK_SET;
- lk.l_start = off;
- lk.l_len = (off_t)sizeof (pid_t);
-
- while ((rc = fcntl(local_lockfd, F_SETLK, &lk)) < 0 && errno == EINTR)
- ;
- if (rc == -1 && errno == EAGAIN)
- return (CFG_LF_AGAIN);
-
- return (CFG_LF_OKAY);
-}
-
-
-int
-cfg_fileunlock(int segment)
-{
- struct flock lk;
- off_t off = segment_off(segment);
-
- bzero(&lk, sizeof (lk));
- lk.l_type = F_UNLCK;
- lk.l_whence = SEEK_SET;
- lk.l_start = off;
- lk.l_len = (off_t)sizeof (pid_t);
-
- while (fcntl(local_lockfd, F_SETLK, &lk) < 0 && errno == EINTR)
- ;
- return (1);
-}
-
-void
-cfg_readpid(int segment, pid_t *pidp)
-{
- off_t off = segment_off(segment);
- lseek(local_lockfd, off, SEEK_SET);
- read(local_lockfd, pidp, sizeof (pid_t));
-}
-
-void
-cfg_writepid(int segment, pid_t pid)
-{
- off_t off = segment_off(segment);
- lseek(local_lockfd, off, SEEK_SET);
- write(local_lockfd, &pid, sizeof (pid_t));
-}
-
-void
-cfg_enterpid()
-{
- int i;
- pid_t pid;
-
- for (i = 0; ; i++) {
- if (cfg_filelock(i, O_CREAT) == CFG_LF_OKAY) {
- cfg_readpid(i, &pid);
- if (pid != (pid_t)0) {
- cfg_fileunlock(i);
- continue;
- }
- pid = getpid();
- cfg_writepid(i, pid);
- break;
- }
- }
-}
diff --git a/usr/src/lib/libdscfg/common/cfg_lockdmsg.c b/usr/src/lib/libdscfg/common/cfg_lockdmsg.c
deleted file mode 100644
index 238c75967e..0000000000
--- a/usr/src/lib/libdscfg/common/cfg_lockdmsg.c
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <signal.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <errno.h>
-
-#include "cfg_lockd.h"
-
-static daemonaddr_t clientaddr;
-static daemonaddr_t server;
-
-static unsigned short server_port = CFG_SERVER_PORT;
-static int lock_soc = 0;
-static int pf_inet = AF_INET;
-static int locked;
-static int initdone;
-static int initresult;
-static pid_t socket_pid;
-
-static void cfg_lockd_reinit();
-
-static int last_cmd = -1;
-static uint8_t seq = 0;
-
-static void
-send_cmd(int cmd)
-{
- struct lock_msg message_buf;
- int rc;
-
- if (last_cmd == cmd) {
- message_buf.seq = seq;
- } else {
- message_buf.seq = ++seq;
- last_cmd = cmd;
- }
- message_buf.message = cmd;
- if ((message_buf.pid = getpid()) != socket_pid)
- cfg_lockd_reinit();
-
- do {
- rc = sendto(lock_soc, &message_buf, sizeof (message_buf), 0,
- (struct sockaddr *)&server, sizeof (server));
- } while (rc == -1 && errno == EINTR);
-#ifdef CFG_LOCKD_DEBUG
- if (rc < 0) {
- perror("send");
- }
-#endif
-}
-
-static void
-read_msg(struct lock_msg *mp)
-{
- struct sockaddr from;
- int rc, len;
-
- /* wait for response */
- do {
- struct pollfd fds;
-
- fds.fd = lock_soc;
- fds.events = POLLIN;
- fds.revents = 0;
-
- rc = poll(&fds, 1, 500);
- if (!rc) {
-#ifdef CFG_LOCKD_DEBUG
- fprintf(stderr, "LOCKD: resending last command (%d)\n",
- last_cmd);
-#endif
- send_cmd(last_cmd);
- }
- } while (rc == 0 ||
- (rc == -1 && errno == EINTR));
-
- do {
- len = sizeof (from);
- rc = recvfrom(lock_soc, mp, sizeof (*mp), 0,
- &from, &len);
- } while (rc == -1 && errno == EINTR);
-#ifdef CFG_LOCKD_DEBUG
- if (rc < 0) {
- perror("revcfrom");
- }
-#endif
-}
-
-static void
-read_reply()
-{
- struct lock_msg message_buf;
-
- do {
- read_msg(&message_buf);
- } while (message_buf.seq != seq || message_buf.message != LOCK_LOCKED);
-}
-
-static void
-read_ack()
-{
- struct lock_msg message_buf;
-
- do {
- read_msg(&message_buf);
- } while (message_buf.seq != seq || message_buf.message != LOCK_ACK);
-}
-
-void
-cfg_lockd_rdlock()
-{
-#ifdef CFG_LOCKD_DEBUG
- FILE *fp;
-#endif
-
- send_cmd(LOCK_READ);
- locked = 1;
- read_reply();
-
-#ifdef CFG_LOCKD_DEBUG
- fp = fopen("/tmp/locktag", "a");
- if (fp) {
- time_t t = time(0);
- fprintf(fp, "%19.19s read lock acquired\n", ctime(&t));
- fclose(fp);
- }
- sleep(3);
-#endif
-}
-
-void
-cfg_lockd_wrlock()
-{
-#ifdef CFG_LOCKD_DEBUG
- FILE *fp;
-#endif
-
- send_cmd(LOCK_WRITE);
- locked = 1;
- read_reply();
-
-#ifdef CFG_LOCKD_DEBUG
- fp = fopen("/tmp/locktag", "a");
- if (fp) {
- time_t t = time(0);
- fprintf(fp, "%19.19s write lock acquired\n", ctime(&t));
- fclose(fp);
- }
- sleep(3);
-#endif
-}
-
-void
-cfg_lockd_unlock()
-{
-#ifdef CFG_LOCKD_DEBUG
- FILE *fp;
-#endif
-
- send_cmd(LOCK_NOTLOCKED);
- read_ack();
- locked = 0;
-
-#ifdef CFG_LOCKD_DEBUG
- fp = fopen("/tmp/locktag", "a");
- if (fp) {
- time_t t = time(0);
- fprintf(fp, "%19.19s ----- lock released\n", ctime(&t));
- fclose(fp);
- }
- sleep(3);
-#endif
-}
-
-void
-cfg_lockd_stat()
-{
- send_cmd(LOCK_STAT);
-}
-
-cfglockd_t
-cfg_lockedby(pid_t *pidp)
-{
- struct lock_msg message_buf;
- send_cmd(LOCK_LOCKEDBY);
- read_msg(&message_buf);
- *pidp = message_buf.pid;
- return ((cfglockd_t)message_buf.message);
-}
-
-static void
-cfg_atexit()
-{
- if (locked)
- cfg_lockd_unlock();
-}
-
-static int
-cfg_lockd_socket()
-{
- if ((lock_soc = socket(pf_inet, SOCK_DGRAM, 0)) < 0) {
-#ifdef CFG_LOCKD_DEBUG
- fprintf(stderr, "libcfg: failed to create socket\n");
- perror("socket");
-#endif
- return (-1);
- }
- clientaddr.sin_family = AF_INET;
- clientaddr.sin_addr.s_addr = INADDR_ANY;
- clientaddr.sin_port = htons(0);
- if (bind(lock_soc, (struct sockaddr *)&clientaddr,
- sizeof (clientaddr)) < 0) {
-#ifdef CFG_LOCKD_DEBUG
- perror("bind");
-#endif
- return (-1);
- }
- socket_pid = getpid();
- return (0);
-}
-
-/*
- * Re-initialise after a fork has been detected.
- *
- * Needs to create a new socket for new process to receive messages
- * from the lock daemon and enter pid into lock file so that the daemon
- * can detect new processes exit if it doesn't call unlock first.
- */
-
-static void
-cfg_lockd_reinit()
-{
- if (lock_soc)
- close(lock_soc);
- lock_soc = 0;
- if (cfg_lockd_socket()) {
- initresult = 0;
- return;
- }
- cfg_enterpid();
- initresult = 1;
-}
-
-int
-cfg_lockd_init()
-{
- struct hostent *hp;
- FILE *fp;
- int pid = 0x12345678;
-
- if (initdone) {
- /* only perform reinit if init worked first time */
- if (getpid() != socket_pid && initresult != 0)
- cfg_lockd_reinit();
- return (initresult);
- }
-
- initdone = 1;
- initresult = 0;
-
- /* check if there's a lock daemon out there */
- if ((fp = fopen(CFG_PIDFILE, "r")) == NULL)
- return (0);
- if (fscanf(fp, "%d\n", &pid) != 1) {
- fclose(fp);
- return (0);
- }
- fclose(fp);
- if (kill((pid_t)pid, 0) != 0)
- return (0);
-
- /* there is a lock daemon */
- cfg_lfinit();
- cfg_enterpid();
- if (cfg_lockd_socket())
- return (0);
-
- if ((hp = gethostbyname("localhost")) == NULL) {
-#ifdef CFG_LOCKD_DEBUG
- fprintf(stderr, "Can't find hostent for %s\n", "localhost");
-#endif
- return (0);
- }
- (void) memcpy(&(server.sin_addr.s_addr), *(hp->h_addr_list),
- sizeof (server.sin_addr));
- server.sin_port = htons(server_port);
- server.sin_family = hp->h_addrtype;
- endhostent();
- atexit(cfg_atexit);
- initresult = 1;
- return (1);
-}
diff --git a/usr/src/lib/libdscfg/common/cfg_vols.c b/usr/src/lib/libdscfg/common/cfg_vols.c
deleted file mode 100644
index 6f0f8bb447..0000000000
--- a/usr/src/lib/libdscfg/common/cfg_vols.c
+++ /dev/null
@@ -1,1286 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <sys/mkdev.h>
-#include <strings.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <locale.h>
-#include <errno.h>
-
-#include <sys/nsctl/cfg.h>
-
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_u.h>
-#include <sys/unistat/spcs_errors.h>
-#include <sys/unistat/spcs_s_impl.h>
-
-#include <sys/nsctl/sv.h>
-#include <sys/nsctl/nsc_hash.h>
-
-#define DEV_EXPAND 32
-
-#define DO_DISABLE 0
-#define DO_ENABLE 1
-
-/*
- * Utility functions for iiadm and rdcadm/sndradm.
- */
-
-typedef struct hash_data_s {
- union {
- char *users;
- char *mode;
- } u;
- char *path;
- char *node;
- int setno;
-} hash_data_t;
-
-typedef struct {
- dev_t rdev;
- mode_t mode;
- char *path;
-} device_t;
-
-static hash_data_t *make_svol_data(char *, char *, char *, int);
-static hash_data_t *make_dsvol_data(char *, char *, char *, int);
-static void delete_svol_data(void *);
-static void delete_dsvol_data(void *);
-static int sv_action(char *, CFGFILE *, char *, int);
-
-static int add_dev_entry(const char *);
-static int compare(const void *, const void *);
-static char *find_devid(const char *);
-static void free_dev_entries();
-static void rebuild_devhash();
-
-static hash_node_t **dsvol;
-static int dsvol_loaded = 0;
-
-static hash_node_t **svol;
-static int svol_loaded = 0;
-
-static hash_node_t **shadowvol;
-
-static hash_node_t **devhash;
-static device_t *devlist;
-static int devcount = 0;
-static int devalloc = 0;
-
-/*
- * cfg_add_user
- *
- * Description:
- * Adds the calling tool as a user of the volume.
- *
- * Inputs:
- * char *path: The pathname of the volume to be enabled.
- * char *cnode: The device group name, or NULL if -C local or not cluster
- * CFGFILE *cfg: A pointer to the current config file, or NULL if this
- * function is to open/write/commit/close the change itself.
- *
- * Return values:
- * CFG_USER_FIRST: Indicates that this is the first user of this
- * particular volume.
- * CFG_USER_OK: Indicates that the volume has already been entered into
- * the config file.
- * CFG_USER_ERR: Indicates that some failure has occurred and no changes
- * to the config file have been made.
- * CFG_USER_REPEAT: Indicates that this user has already registered for
- * the volume.
- */
-int
-cfg_add_user(CFGFILE* cfg, char *path, char *cnode, char *user)
-{
- int self_open, self_loaded, change_made;
- char *ctag, search_key[ CFG_MAX_KEY ], buf[ CFG_MAX_BUF ];
- int retval, rc;
- hash_data_t *data;
-
- self_open = (cfg == NULL);
- self_loaded = 0;
- change_made = 0;
-
- if (self_open) {
- cfg = cfg_open(NULL);
- if (cfg == NULL) {
- return (CFG_USER_ERR);
- }
-
- if (!cfg_lock(cfg, CFG_WRLOCK)) {
- /* oops */
- cfg_close(cfg);
- return (CFG_USER_ERR);
- }
- }
-
- /* Check cnode */
- ctag = cfg_get_resource(cfg);
- if (cnode) {
- if (ctag) {
- if (strcmp(cnode, ctag))
- return (CFG_USER_ERR);
- } else
- cfg_resource(cfg, cnode);
- } else
- cnode = ctag;
-
- if (!dsvol_loaded) {
- if (cfg_load_dsvols(cfg) < 0) {
- if (self_open) {
- cfg_close(cfg);
- }
- return (CFG_USER_ERR);
- }
- self_loaded = 1;
- }
-
- /* find the volume */
- (void) snprintf(search_key, CFG_MAX_KEY, "%s:%s", path, cnode);
- data = nsc_lookup(dsvol, search_key);
-
- if (!data) {
- /* whoops, not found. Add as new user */
- cfg_rewind(cfg, CFG_SEC_CONF);
- (void) snprintf(buf, CFG_MAX_BUF, "%s %s %s", path, cnode,
- user);
- rc = cfg_put_cstring(cfg, "dsvol", buf, strlen(buf));
- if (rc < 0) {
- if (self_loaded) {
- cfg_unload_dsvols();
- }
- if (self_open) {
- cfg_close(cfg);
- }
- return (CFG_USER_ERR);
- }
- /* reload hash, if we need to */
- if (!self_loaded) {
- cfg_unload_dsvols();
- if (cfg_load_dsvols(cfg) < 0) {
- if (self_open) {
- cfg_close(cfg);
- }
- return (CFG_USER_ERR);
- }
- }
- retval = CFG_USER_FIRST;
- change_made = 1;
- } else {
- /* Check to ensure we're not already listed */
- char *p = strdup(data->u.users);
- char *q = strtok(p, ",");
- while (q && (strcmp(q, user) != 0)) {
- q = strtok(0, ",");
- }
- free(p); /* not using data; only testing 'q' ptr */
-
- if (!q) {
- /* not listed as a user */
- cfg_rewind(cfg, CFG_SEC_CONF);
- (void) snprintf(buf, CFG_MAX_BUF, "%s %s %s,%s",
- data->path, data->node, data->u.users, user);
- (void) snprintf(search_key, CFG_MAX_KEY, "dsvol.set%d",
- data->setno);
- if (cfg_put_cstring(cfg, search_key, buf,
- strlen(buf)) < 0) {
- if (self_loaded) {
- cfg_unload_dsvols();
- }
- if (self_open) {
- cfg_close(cfg);
- }
- return (CFG_USER_ERR);
- }
-
- /*
- * Since we deleted an entry from the config
- * file, we don't know what all the new
- * set numbers are. We need to reload
- * everything
- */
- if (!self_loaded) {
- cfg_unload_dsvols();
- if (cfg_load_dsvols(cfg) < 0) {
- if (self_open) {
- cfg_close(cfg);
- }
- return (CFG_USER_ERR);
- }
- }
- change_made = 1;
- retval = CFG_USER_OK;
- } else {
- retval = CFG_USER_REPEAT;
- }
- }
-
- if (self_loaded) {
- cfg_unload_dsvols();
- }
-
- if (self_open) {
- if (change_made)
- (void) cfg_commit(cfg);
- cfg_close(cfg);
- }
-
- return (retval);
-}
-
-/*
- * cfg_rem_user
- *
- * Description:
- * Removes a user from the config file.
- *
- * Inputs:
- * char *path: The pathname of the volume to be enabled.
- * char *cnode: The device group name, or NULL if -C local or not cluster
- * char *user: The subsystem that is adding this tag (sv, ii, sndr)
- * CFGFILE *cfg: A pointer to the current config file, or NULL if this
- * function is to open/write/commit/close the change itself.
- * Return values:
- * CFG_USER_ERR: An error occurred during the processing of this
- * directive.
- * CFG_USER_OK: User successfully removed; volume in use by other(s).
- * CFG_USER_LAST: User successfuly removed; no other users registered
- * CFG_USER_GONE: The volume is no longer listed in the dsvol section,
- * indicating some sort of application-level error.
- *
- */
-int
-cfg_rem_user(CFGFILE *cfg, char *path, char *cnode, char *user)
-{
- int self_open, self_loaded, change_made;
- char *ctag, search_key[ CFG_MAX_KEY ], buf[ CFG_MAX_BUF ];
- char cfg_key[ CFG_MAX_KEY ];
- hash_data_t *data;
- int retval;
- int force_remove;
-
- self_open = (cfg == NULL);
- self_loaded = 0;
- change_made = 0;
- force_remove = (strcmp(user, "sv") == 0);
-
- if ('-' == *user) {
- ++user;
- }
-
- /* Check cnode */
- ctag = cfg_get_resource(cfg);
- if (cnode) {
- if (ctag) {
- if (strcmp(cnode, ctag))
- return (CFG_USER_ERR);
- } else
- cfg_resource(cfg, cnode);
- } else
- cnode = ctag;
-
- if (self_open) {
- cfg = cfg_open(NULL);
- if (cfg == NULL) {
- return (CFG_USER_ERR);
- }
-
- if (!cfg_lock(cfg, CFG_WRLOCK)) {
- /* oops */
- cfg_close(cfg);
- return (CFG_USER_ERR);
- }
- }
-
-
- change_made = 0;
- if (!dsvol_loaded) {
- if (cfg_load_dsvols(cfg) < 0) {
- if (self_open) {
- cfg_close(cfg);
- }
- return (CFG_USER_ERR);
- }
- self_loaded = 1;
- }
-
- /* find the volume */
- (void) snprintf(search_key, CFG_MAX_KEY, "%s:%s", path, cnode);
- data = nsc_lookup(dsvol, search_key);
-
- if (!data) {
- /* yipes */
- retval = CFG_USER_GONE;
- } else if (force_remove) {
- retval = CFG_USER_LAST;
- cfg_rewind(cfg, CFG_SEC_CONF);
- (void) snprintf(cfg_key, CFG_MAX_KEY, "dsvol.set%d",
- data->setno);
- if (cfg_put_cstring(cfg, cfg_key, NULL, 0) < 0) {
- if (self_loaded) {
- cfg_unload_dsvols();
- }
- if (self_open) {
- cfg_close(cfg);
- }
- return (CFG_USER_ERR);
- }
- if (!self_loaded) {
- cfg_unload_dsvols();
- if (cfg_load_dsvols(cfg) < 0) {
- if (self_open) {
- cfg_close(cfg);
- }
- return (CFG_USER_ERR);
- }
- }
- } else {
- char *p = strdup(data->u.users);
- char *q = strtok(p, ",");
- int appended = 0;
-
- (void) snprintf(buf, CFG_MAX_BUF, "%s %s ", data->path,
- data->node);
- while (q && (strcmp(q, user) != 0)) {
- if (appended) {
- strcat(buf, ",");
- strcat(buf, q);
- } else {
- strcat(buf, q);
- appended = 1;
- }
- q = strtok(0, ",");
- }
-
- if (!q) {
- /* uh-oh */
- retval = CFG_USER_GONE;
- } else {
- /* old user skipped; add in remaining users */
- while (q = strtok(0, ", ")) {
- if (appended) {
- strcat(buf, ",");
- strcat(buf, q);
- } else {
- strcat(buf, q);
- appended = 1;
- }
- }
-
- if (appended) {
- retval = CFG_USER_OK;
- cfg_rewind(cfg, CFG_SEC_CONF);
- (void) snprintf(cfg_key, CFG_MAX_KEY,
- "dsvol.set%d", data->setno);
- if (cfg_put_cstring(cfg, cfg_key, buf,
- strlen(buf)) < 0) {
- if (self_loaded) {
- cfg_unload_dsvols();
- }
- if (self_open) {
- cfg_close(cfg);
- }
- return (CFG_USER_ERR);
- }
- if (!self_loaded) {
- cfg_unload_dsvols();
- if (cfg_load_dsvols(cfg) < 0) {
- if (self_open) {
- cfg_close(cfg);
- }
- return (CFG_USER_ERR);
- }
- }
- } else {
- retval = CFG_USER_LAST;
- cfg_rewind(cfg, CFG_SEC_CONF);
- (void) snprintf(cfg_key, CFG_MAX_KEY,
- "dsvol.set%d", data->setno);
- if (cfg_put_cstring(cfg, cfg_key, NULL,
- 0) < 0) {
- if (self_loaded) {
- cfg_unload_dsvols();
- }
- if (self_open) {
- cfg_close(cfg);
- }
- return (CFG_USER_ERR);
- }
- /*
- * Since we deleted an entry from the config
- * file, we don't know what all the new
- * set numbers are. We need to reload
- * everything
- */
- if (!self_loaded) {
- cfg_unload_dsvols();
- if (cfg_load_dsvols(cfg) < 0) {
- if (self_open) {
- cfg_close(cfg);
- }
- return (CFG_USER_ERR);
- }
- }
- }
- change_made = 1;
- }
- }
-
- if (self_loaded) {
- cfg_unload_dsvols();
- }
-
- if (self_open) {
- if (change_made)
- (void) cfg_commit(cfg);
- cfg_close(cfg);
- }
-
- return (retval);
-}
-
-/*
- * Enable a volume under SV control (or add this char *user to the list
- * of users of that volume).
- *
- * Parameters:
- * cfg - The config file to use.
- * path - The pathname of the volume
- * ctag - The cluster tag for this volume (if any)
- * user - The user (sv, ii, sndr) of the volume.
- */
-int
-cfg_vol_enable(CFGFILE *cfg, char *path, char *ctag, char *user)
-{
- int rc;
- int retval;
-
- if (!ctag || *ctag == '\0') {
- ctag = "-";
- }
-
- retval = -1;
- rc = cfg_add_user(cfg, path, ctag, user);
- switch (rc) {
- case CFG_USER_ERR:
- spcs_log("dsvol", NULL,
- gettext("unable to set up dsvol section of config for %s"),
- path);
- break;
- case CFG_USER_OK:
- retval = 0;
- break;
- case CFG_USER_FIRST:
- /* enable sv! */
- retval = sv_action(path, cfg, ctag, DO_ENABLE);
- if (retval < 0) {
- (void) cfg_rem_user(cfg, path, ctag, user);
- }
- break;
- default:
- spcs_log("dsvol", NULL,
- gettext("unexpected return from cfg_add_user(%d)"), rc);
- break;
- }
-
- return (retval);
-}
-
-/*
- * Disable a volume from SV control (or remove this char *user from the list
- * of users of that volume).
- *
- * Parameters:
- * cfg - The config file to use.
- * path - The pathname of the volume
- * ctag - The cluster tag for this volume (if any)
- * user - The user (sv, ii, sndr) of the volume.
- */
-int
-cfg_vol_disable(CFGFILE *cfg, char *path, char *ctag, char *user)
-{
- int rc;
- int retval;
-
- if (!ctag || *ctag == '\0') {
- ctag = "-";
- }
-
- retval = -1;
- rc = cfg_rem_user(cfg, path, ctag, user);
- switch (rc) {
- case CFG_USER_ERR:
- spcs_log("dsvol", NULL,
- gettext("unable to set up dsvol section of config for %s"),
- path);
- break;
- case CFG_USER_OK:
- retval = 0;
- break;
- case CFG_USER_GONE:
- spcs_log("dsvol", NULL,
- gettext("%s tried to remove non-existent tag for %s"),
- user, path);
- break;
- case CFG_USER_LAST:
- /* diable sv! */
- retval = sv_action(path, cfg, ctag, DO_DISABLE);
- break;
- default:
- spcs_log("dsvol", NULL,
- gettext("unexpected return from cfg_rem_user(%d)"), rc);
- break;
- }
-
- return (retval);
-}
-
-/*
- * cfg_load_dsvols
- *
- * Description:
- * Loads the dsvol section of the config file into a giant hash, to
- * make searching faster. The important bit to remember is to not
- * release the write lock between calling cfg_load_dsvols() and the
- * cfg_*_user() functions.
- *
- * Assumptions:
- * 1/ cfg file is open
- * 2/ cfg file has been write-locked
- * 3/ user of this routine may already be using hcreate/hsearch
- *
- * Return value:
- * -1 if error, or total number of sets found
- */
-int
-cfg_load_dsvols(CFGFILE *cfg)
-{
- int set, rc, entries;
- char search_key[ CFG_MAX_KEY ];
- char *buf;
- char **entry, *path, *cnode, *users;
- hash_data_t *data;
- int devs_added = 0;
- int offset = 0;
- char *ctag = cfg_get_resource(cfg);
- if (!ctag || *ctag == '\0') {
- ctag = "-";
- }
-
- dsvol = nsc_create_hash();
- if (!dsvol) {
- return (-1);
- }
-
- rc = 0;
- cfg_rewind(cfg, CFG_SEC_CONF);
- entries = cfg_get_section(cfg, &entry, "dsvol");
- for (set = 1; set <= entries; set++) {
- buf = entry[set - 1];
-
- /* split up the line */
- if (!(path = strtok(buf, " "))) {
- /* oops, now what? */
- free(buf);
- break;
- }
- if (!(cnode = strtok(0, " "))) {
- free(buf);
- break;
- }
- if (ctag && (strcmp(cnode, ctag) != 0)) {
- ++offset;
- free(buf);
- continue;
- }
-
- if (!(users = strtok(0, " "))) {
- free(buf);
- break;
- }
-
- data = make_dsvol_data(path, cnode, users, set - offset);
- if (!data) {
- free(buf);
- break;
- }
- (void) snprintf(search_key, CFG_MAX_KEY, "%s:%s", path, cnode);
- rc = nsc_insert_node(dsvol, data, search_key);
- if (rc < 0) {
- free(buf);
- break;
- }
-
- /* we also need to keep track of node information */
- rc = add_dev_entry(path);
- if (rc < 0) {
- free(buf);
- break;
- } else if (rc)
- ++devs_added;
-
- free(buf);
- rc = 0;
- }
-
- while (set < entries)
- free(entry[set++]);
- if (entries)
- free(entry);
-
- if (devs_added) {
- qsort(devlist, devcount, sizeof (device_t), compare);
- rebuild_devhash();
- }
-
- dsvol_loaded = 1;
- return (rc < 0? rc : entries);
-}
-
-/*
- * cfg_unload_dsvols
- *
- * Description:
- * Free all memory allocated with cfg_load_dsvols.
- */
-void
-cfg_unload_dsvols()
-{
- if (dsvol) {
- nsc_remove_all(dsvol, delete_dsvol_data);
- dsvol = 0;
- dsvol_loaded = 0;
- }
-}
-
-/*
- * cfg_load_svols
- *
- * Description:
- * Loads the sv section of the config file into a giant hash, to make
- * searching faster. The important bit to remember is to not release
- * the write lock between calling cfg_load_svols() and the cfg_*_user()
- * functions.
- *
- * Assumptions:
- * 1/ cfg file is open
- * 2/ cfg file has been write-locked
- * 3/ user of this routine may already be using builtin hcreate/hsearch
- */
-int
-cfg_load_svols(CFGFILE *cfg)
-{
- int set, entries, offset = 0;
- char *buf, **entry;
- char *path, *mode, *cnode;
- hash_data_t *data;
- char *ctag = cfg_get_resource(cfg);
- if (!ctag || *ctag == '\0') {
- ctag = "-";
- }
-
- svol = nsc_create_hash();
- if (!svol) {
- return (-1);
- }
-
- cfg_rewind(cfg, CFG_SEC_CONF);
- entries = cfg_get_section(cfg, &entry, "sv");
- for (set = 1; set <= entries; set++) {
- buf = entry[set - 1];
-
- /* split up the line */
- if (!(path = strtok(buf, " "))) {
- free(buf);
- break;
- }
- if (!(mode = strtok(0, " "))) {
- free(buf);
- break;
- }
- if (!(cnode = strtok(0, " "))) {
- cnode = "";
- }
-
- if (ctag && (strcmp(cnode, ctag) != 0)) {
- ++offset;
- free(buf);
- continue;
- }
-
- data = make_svol_data(path, mode, cnode, set - offset);
- if (!data) {
- free(buf);
- break;
- }
- if (nsc_insert_node(svol, data, path) < 0) {
- free(buf);
- break;
- }
- free(buf);
- }
- while (set < entries)
- free(entry[set++]);
- if (entries)
- free(entry);
-
- svol_loaded = 1;
- return (0);
-}
-
-/*
- * cfg_unload_svols
- *
- * Description:
- * Frees all memory allocated with cfg_load_dsvols
- */
-void
-cfg_unload_svols()
-{
- if (svol) {
- nsc_remove_all(svol, delete_svol_data);
- svol = 0;
- svol_loaded = 0;
- }
-}
-
-/*
- * cfg_get_canonical_name
- *
- * Description:
- * Find out whether a device is already known by another name in
- * the config file.
- *
- * Parameters:
- * cfg - The config file to use
- * path - The pathname of the device
- * result - (output) The name it is otherwise known as. This parameter
- * must be freed by the caller.
- *
- * Return values:
- * -1: error
- * 0: name is as expected, or is not known
- * 1: Name is known by different name (stored in 'result')
- */
-int
-cfg_get_canonical_name(CFGFILE *cfg, const char *path, char **result)
-{
- int self_loaded;
- char *alt_path;
- int retval;
-
- if (devlist) {
- self_loaded = 0;
- } else {
- if (cfg_load_shadows(cfg) < 0) {
- return (-1);
- }
- self_loaded = 1;
- }
-
- /* see if it exists under a different name */
- alt_path = find_devid(path);
- if (!alt_path || strcmp(path, alt_path) == 0) {
- *result = NULL;
- retval = 0;
- } else {
- /* a-ha */
- *result = strdup(alt_path);
- retval = 1;
- }
-
- if (self_loaded) {
- free_dev_entries();
- }
-
- return (retval);
-}
-
-/*
- * cfg_load_shadows
- *
- * Description:
- * Load in shadow and bitmap volumes from the II section of the
- * config file. SNDR's volumes are handled already by cfg_load_dsvols.
- * Not all shadow volumes are listed under dsvol: they can be exported.
- *
- * Parameters:
- * cfg - The config file to use
- *
- * Return values:
- * -1: error
- * 0: success
- */
-int
-cfg_load_shadows(CFGFILE *cfg)
-{
- int set, self_loaded, rc, entries;
- char *buf, **entry, *ptr;
- int devs_added = 0;
-
- if (dsvol_loaded) {
- self_loaded = 0;
- } else {
- if (cfg_load_dsvols(cfg) < 0) {
- return (-1);
- }
- self_loaded = 1;
- }
-
- shadowvol = nsc_create_hash();
- if (!shadowvol) {
- return (-1);
- }
-
- rc = 0;
- cfg_rewind(cfg, CFG_SEC_CONF);
- entries = cfg_get_section(cfg, &entry, "ii");
- for (set = 1; set <= entries; set++) {
- buf = entry[set - 1];
-
- /* skip the master vol */
- ptr = strtok(buf, " ");
-
- /* shadow is next */
- ptr = strtok(NULL, " ");
-
- rc = add_dev_entry(ptr);
- if (rc < 0) {
- free(buf);
- break;
- } else if (rc)
- ++devs_added;
-
- /* and next is bitmap */
- ptr = strtok(NULL, " ");
-
- rc = add_dev_entry(ptr);
- if (rc < 0) {
- free(buf);
- break;
- } else if (rc)
- ++devs_added;
- rc = 0;
- free(buf);
- }
- while (set < entries)
- free(entry[set++]);
- if (entries)
- free(entry);
-
- if (self_loaded) {
- cfg_unload_dsvols();
- }
-
- if (devs_added) {
- /* sort it, in preparation for lookups */
- qsort(devlist, devcount, sizeof (device_t), compare);
- rebuild_devhash();
- }
-
- return (rc);
-}
-
-void
-cfg_unload_shadows()
-{
- /* do nothing */
-}
-
-/* ---------------------------------------------------------------------- */
-
-static hash_data_t *
-make_dsvol_data(char *path, char *cnode, char *users, int set)
-{
- hash_data_t *data;
-
- data = (hash_data_t *)malloc(sizeof (hash_data_t));
- if (!data) {
- return (0);
- }
-
- data->u.users = strdup(users);
- data->path = strdup(path);
- data->node = strdup(cnode);
- data->setno = set;
-
- return (data);
-}
-
-static void
-delete_dsvol_data(void *data)
-{
- hash_data_t *p = (hash_data_t *)data;
-
- free(p->u.users);
- free(p->path);
- free(p->node);
- free(p);
-}
-
-static hash_data_t *
-make_svol_data(char *path, char *mode, char *cnode, int set)
-{
- hash_data_t *data;
-
- data = (hash_data_t *)malloc(sizeof (hash_data_t));
- if (!data) {
- return (0);
- }
-
- data->u.mode = strdup(mode);
- data->path = strdup(path);
- data->node = strdup(cnode);
- data->setno = set;
-
- return (data);
-}
-
-
-static void
-delete_svol_data(void *data)
-{
- hash_data_t *p = (hash_data_t *)data;
-
- free(p->u.mode);
- free(p->path);
- free(p->node);
- free(p);
-}
-
-static int
-sv_action(char *path, CFGFILE *caller_cfg, char *ctag, int enable)
-{
- struct stat stb;
- sv_conf_t svc;
- int fd = -1;
- int cfg_changed = 0;
- CFGFILE *cfg;
- int print_log = 0;
- int err = 0, rc;
- int sv_ioctl, spcs_err, self_loaded;
- char *log_str1, *log_str2;
- char key[ CFG_MAX_KEY ];
- char buf[ CFG_MAX_BUF ];
- hash_data_t *node;
- device_t *statinfo = 0;
-
- if (caller_cfg == NULL) {
- cfg = cfg_open(NULL);
- if (cfg == NULL)
- return (-1);
-
- if (ctag)
- cfg_resource(cfg, ctag);
- } else
- cfg = caller_cfg;
-
-
- self_loaded = 0;
- sv_ioctl = (enable? SVIOC_ENABLE : SVIOC_DISABLE);
- log_str1 = (enable? gettext("enabled %s") : gettext("disabled %s"));
- log_str2 = (enable? gettext("unable to enable %s") :
- gettext("unable to disable %s"));
- spcs_err = (enable? SV_EENABLED : SV_EDISABLED);
- bzero(&svc, sizeof (svc));
-
- if (devhash)
- statinfo = nsc_lookup(devhash, path);
-
- if (statinfo) {
- if (!S_ISCHR(statinfo->mode))
- goto error;
- svc.svc_major = major(statinfo->rdev);
- svc.svc_minor = minor(statinfo->rdev);
- } else {
- if (stat(path, &stb) != 0)
- goto error;
-
- if (!S_ISCHR(stb.st_mode))
- goto error;
- svc.svc_major = major(stb.st_rdev);
- svc.svc_minor = minor(stb.st_rdev);
- }
-
- strncpy(svc.svc_path, path, sizeof (svc.svc_path));
-
- fd = open(SV_DEVICE, O_RDONLY);
- if (fd < 0)
- goto error;
-
- svc.svc_flag = (NSC_DEVICE | NSC_CACHE);
- svc.svc_error = spcs_s_ucreate();
-
- do {
- rc = ioctl(fd, sv_ioctl, &svc);
- } while (rc < 0 && errno == EINTR);
-
- if (rc < 0) {
- if (errno != spcs_err) {
- spcs_log("sv", &svc.svc_error, log_str2, svc.svc_path);
- if (enable)
- goto error;
- else
- err = errno;
- } else
- err = spcs_err;
- }
-
- spcs_log("sv", NULL, log_str1, svc.svc_path);
-
- /* SV enable succeeded */
- if (caller_cfg == NULL) /* was not previously locked */
- if (!cfg_lock(cfg, CFG_WRLOCK))
- goto error;
-
- if (err != spcs_err) { /* already enabled, already in config */
- if (enable) {
- cfg_rewind(cfg, CFG_SEC_CONF);
- (void) snprintf(buf, CFG_MAX_BUF, "%s - %s", path,
- ctag? ctag : "-");
- if (cfg_put_cstring(cfg, "sv", buf, CFG_MAX_BUF) < 0) {
- /* SV config not updated, so SV disable again */
- (void) ioctl(fd, SVIOC_DISABLE, &svc);
- print_log++;
- } else
- cfg_changed = 1;
- } else {
- /* pull it out of the config */
- if (!svol_loaded) {
- if (cfg_load_svols(cfg) < 0) {
- if (NULL == caller_cfg) {
- cfg_close(cfg);
- }
- return (-1);
- }
- self_loaded = 1;
- }
- node = nsc_lookup(svol, svc.svc_path);
- if (node) {
- cfg_rewind(cfg, CFG_SEC_CONF);
- (void) snprintf(key, CFG_MAX_KEY, "sv.set%d",
- node->setno);
- if (cfg_put_cstring(cfg, key, NULL, NULL) < 0) {
- spcs_log("sv", NULL,
- gettext("failed to remove %s from "
- "sv config"), svc.svc_path);
- }
- /*
- * Since we deleted an entry from the config
- * file, we don't know what all the new
- * set numbers are. We need to reload
- * everything
- */
- if (!self_loaded) {
- cfg_unload_svols();
- if (cfg_load_svols(cfg) < 0) {
- if (NULL == caller_cfg) {
- cfg_close(cfg);
- }
- return (-1);
- }
- }
- cfg_changed = 1;
- }
- if (self_loaded) {
- cfg_unload_svols();
- self_loaded = 0;
- }
- }
- }
-
-#ifdef lint
- (void) printf("extra line to shut lint up %s\n", module_names[0]);
-#endif
-
-error:
- if (fd >= 0)
- (void) close(fd);
-
- if (cfg == NULL)
- return (-1);
-
- if (cfg_changed)
- if (caller_cfg == NULL) /* we opened config */
- (void) cfg_commit(cfg);
-
- if (caller_cfg == NULL)
- cfg_close(cfg);
- if ((cfg_changed) || (err == spcs_err))
- return (1);
- if (print_log)
- spcs_log("sv", NULL,
- gettext("unable to add to configuration, disabled %s"),
- svc.svc_path);
- spcs_s_ufree(&svc.svc_error);
-
- return (-1);
-}
-
-/*
- * add_dev_entry
- *
- * Add an entry into the devlist and the devhash for future lookups.
- *
- * Return values:
- * -1 An error occurred.
- * 0 Entry added
- * 1 Entry already exists.
- */
-static int
-add_dev_entry(const char *path)
-{
- struct stat buf;
- device_t *newmem;
- hash_data_t *data;
-
- if (!devhash) {
- devhash = nsc_create_hash();
- if (!devhash) {
- return (-1);
- }
- } else {
- data = nsc_lookup(devhash, path);
- if (data) {
- return (1);
- }
- }
-
- if (stat(path, &buf) < 0) {
- /* ignore error, we are most likely deleting entry anyway */
- buf.st_rdev = 0;
- }
-
- if (devcount >= devalloc) {
- /* make some room */
- devalloc += DEV_EXPAND;
- newmem = (device_t *)realloc(devlist, devalloc *
- sizeof (device_t));
- if (!newmem) {
- free_dev_entries();
- return (-1);
- } else {
- devlist = newmem;
- }
- }
-
- devlist[ devcount ].path = strdup(path);
- devlist[ devcount ].rdev = buf.st_rdev;
- devlist[ devcount ].mode = buf.st_mode;
-
- if (nsc_insert_node(devhash, &devlist[devcount], path) < 0) {
- return (-1);
- }
-
- ++devcount;
- return (0);
-}
-
-static void
-rebuild_devhash()
-{
- int i;
-
- if (!devhash)
- nsc_remove_all(devhash, 0);
-
- devhash = nsc_create_hash();
- if (!devhash)
- return;
-
- for (i = 0; i < devcount; i++) {
- nsc_insert_node(devhash, &devlist[i], devlist[i].path);
- }
-}
-
-static int
-compare(const void *va, const void *vb)
-{
- device_t *a = (device_t *)va;
- device_t *b = (device_t *)vb;
-
- return (b->rdev - a->rdev);
-}
-
-static char *
-find_devid(const char *path)
-{
- device_t key;
- device_t *result;
- struct stat buf;
-
- if (!devlist || !devhash)
- return (NULL);
-
- /* See if we already know the device id by this name */
- result = (device_t *)nsc_lookup(devhash, path);
- if (result) {
- return (NULL);
- }
-
- /* try to find it by another name */
- if (stat(path, &buf) < 0)
- return (NULL);
-
- key.rdev = buf.st_rdev;
-
- /* it's storted, so we use the binary-chop method to find it */
- result = bsearch(&key, devlist, devcount, sizeof (device_t), compare);
-
- if (result) {
- return (result->path);
- }
-
- return (NULL);
-}
-
-static void
-free_dev_entries()
-{
- int i;
- device_t *p;
-
- if (!devlist) {
- return;
- }
- for (i = 0, p = devlist; i < devcount; i++, p++) {
- free(p->path);
- }
- free(devlist);
- devlist = NULL;
- devcount = 0;
- devalloc = 0;
-
- if (devhash) {
- nsc_remove_all(devhash, 0);
- devhash = NULL;
- }
-}
diff --git a/usr/src/lib/libdscfg/common/mapfile-vers b/usr/src/lib/libdscfg/common/mapfile-vers
deleted file mode 100644
index 0e1f4f4cae..0000000000
--- a/usr/src/lib/libdscfg/common/mapfile-vers
+++ /dev/null
@@ -1,100 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
-#
-#
-
-#
-# MAPFILE HEADER START
-#
-# WARNING: STOP NOW. DO NOT MODIFY THIS FILE.
-# Object versioning must comply with the rules detailed in
-#
-# usr/src/lib/README.mapfiles
-#
-# You should not be making modifications here until you've read the most current
-# copy of that file. If you need help, contact a gatekeeper for guidance.
-#
-# MAPFILE HEADER END
-#
-
-#
-# Generic interface definition for usr/src/lib/libcfg.
-#
-
-
-$mapfile_version 2
-
-SYMBOL_VERSION SUNWprivate_1.1 {
- global:
- cfg_get_cstring;
- cfg_put_cstring;
- cfg_find_cstring;
- cfg_get_options;
- cfg_put_options;
- cfg_open;
- cfg_close;
- cfg_rewind;
- cfg_update_parser_config;
- cfg_lock;
- cfg_unlock;
- cfg_get_lock;
- cfg_resource;
- cfg_commit;
- cfg_location;
- cfg_error;
- cfg_iscluster;
- cfg_issuncluster;
- cfg_dgname;
- cfg_dgname_islocal;
- cfg_lfinit;
- cfg_filelock;
- cfg_fileunlock;
- cfg_readpid;
- cfg_writepid;
- cfg_lockd_stat;
- cfg_invalidate_hsizes;
- cfg_cfg_isempty;
- cfg_get_section;
- cfg_get_num_entries;
- cfg_add_user;
- cfg_rem_user;
- cfg_vol_enable;
- cfg_vol_disable;
- cfg_load_dsvols;
- cfg_unload_dsvols;
- cfg_load_svols;
- cfg_unload_svols;
- cfg_load_shadows;
- cfg_unload_shadows;
- cfg_get_canonical_name;
- cfg_get_tags;
- cfg_is_cfg;
- cfg_get_srtdsec;
- cfg_free_section;
- cfg_shldskip_vtoc;
- cfg_get_single_option;
- cfg_del_option;
- cfg_get_resource;
- cfg_l_dgname;
- local:
- *;
-};
diff --git a/usr/src/lib/libdscfg/i386/Makefile b/usr/src/lib/libdscfg/i386/Makefile
deleted file mode 100644
index 0e5cdedf26..0000000000
--- a/usr/src/lib/libdscfg/i386/Makefile
+++ /dev/null
@@ -1,34 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-include ../Makefile.com
-
-.KEEP_STATE:
-
-all: $(LIBS)
-
-install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTARLINK)
-
-lint:
-lintinter:
diff --git a/usr/src/lib/libdscfg/sparc/Makefile b/usr/src/lib/libdscfg/sparc/Makefile
deleted file mode 100644
index 7dce46d064..0000000000
--- a/usr/src/lib/libdscfg/sparc/Makefile
+++ /dev/null
@@ -1,34 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-include ../Makefile.com
-
-.KEEP_STATE:
-
-all: $(LIBS)
-
-install: all $(ROOTLIBS) $(ROOTLINKS)
-lint:
-lintinter:
-
diff --git a/usr/src/lib/libnsctl/Makefile b/usr/src/lib/libnsctl/Makefile
deleted file mode 100644
index 47eb07f597..0000000000
--- a/usr/src/lib/libnsctl/Makefile
+++ /dev/null
@@ -1,60 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# lib/libnsctl/Makefile
-
-include ../Makefile.lib
-
-HDRS= nsc_hash.h
-HDRDIR= common
-
-SUBDIRS = $(MACH)
-
-ROOTHDRDIR= $(ROOT)/usr/include/sys/nsctl
-
-ROOTHDRS= $(HDRS:%=$(ROOTHDRDIR)/%)
-
-all := TARGET= all
-clean := TARGET= clean
-clobber := TARGET= clobber
-install := TARGET= install
-lint := TARGET= lint
-
-.KEEP_STATE:
-
-all clean clobber delete install lint: $(SUBDIRS)
-
-$(MACH): FRC
- @cd $@; pwd; $(MAKE) $(TARGET)
-
-install_h: $(ROOTHDRDIR) $(ROOTHDRS)
-
-$(ROOTHDRDIR)/%: common/%
- $(INS.file)
-
-$(ROOTHDRDIR):
- $(INS.dir)
-
-check: $(CHECKHDRS)
-
-FRC:
diff --git a/usr/src/lib/libnsctl/Makefile.com b/usr/src/lib/libnsctl/Makefile.com
deleted file mode 100644
index 36042e4c6f..0000000000
--- a/usr/src/lib/libnsctl/Makefile.com
+++ /dev/null
@@ -1,56 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# lib/libnsctl/Makefile.com
-
-LIBRARY= libnsctl.a
-VERS= .1
-
-OBJECTS= cache.o machdep.o hash.o
-
-# include library definitions
-include ../../Makefile.lib
-
-LIBS= $(DYNLIB) $(LINTLIB)
-
-SRCDIR= ../common
-
-INCS += -I$(SRCDIR)
-
-CSTD= $(CSTD_GNU99)
-C99LMODE= -Xc99=%all
-
-LDLIBS += -lc
-CPPFLAGS += $(INCS)
-LINTFLAGS += -erroff=E_FUNC_RET_MAYBE_IGNORED2
-LINTFLAGS += -erroff=E_FUNC_RET_ALWAYS_IGNOR2
-
-$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC)
-
-.KEEP_STATE:
-
-all: $(LIBS)
-
-lint: lintcheck
-
-include ../../Makefile.targ
diff --git a/usr/src/lib/libnsctl/common/cache.c b/usr/src/lib/libnsctl/common/cache.c
deleted file mode 100644
index e4bbc21f25..0000000000
--- a/usr/src/lib/libnsctl/common/cache.c
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/fcntl.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <strings.h>
-#include <unistd.h>
-#include <stdio.h>
-
-#include "libnsctl.h"
-#include <nsctl.h>
-
-
-static int _nsc_open_path(nsc_fd_t *);
-static int _nsc_open_check(nsc_fd_t *);
-
-
-/*
- * Turn off ckdchk checking of nsc_open()'d volumes since we have no CKD
- * formatted volumes right now. If/when we come back with CKD volumes,
- * we could do this more sanely by completing the implementation of the
- * CKD module, and having nsc_open() prevent any non-NSC_CKD_DISK open
- * of a CKD volume.
- * -- Simon, Thu Feb 18 10:49:46 GMT 1999
- */
-static int ckdchk = 0;
-
-
-nsc_fd_t *
-nsc_open(path, flag, mode)
-char *path;
-int flag, mode;
-{
- nsc_fd_t *fd;
-
- if (strlen(path) >= NSC_MAXPATH) {
- errno = ENAMETOOLONG;
- return (0);
- }
-
- if (!(fd = (nsc_fd_t *)calloc(1, sizeof (nsc_fd_t))))
- return (0);
-
- if ((mode & O_ACCMODE) == O_WRONLY) {
- mode &= ~O_ACCMODE;
- mode |= O_RDWR;
- }
-
- fd->sf_flag = flag;
- fd->sf_fmode = mode;
-
- strcpy(fd->sf_path, path);
-
- if (!_nsc_open_path(fd)) {
- free(fd);
- return (0);
- }
-
- if (ckdchk && !_nsc_open_check(fd)) {
- (void) nsc_close(fd);
- return (0);
- }
-
- return (fd);
-}
-
-
-nsc_fd_t *
-nsc_fdopen(id, path, mode)
-int id, mode;
-char *path;
-{
- struct flock lk;
- nsc_fd_t *fd;
- int i;
-
- if (strlen(path) >= NSC_MAXPATH) {
- errno = ENAMETOOLONG;
- return (0);
- }
-
- if (!(fd = (nsc_fd_t *)calloc(1, sizeof (nsc_fd_t))))
- return (0);
-
- lk.l_type = F_WRLCK;
- lk.l_whence = SEEK_SET;
- lk.l_start = 0;
- lk.l_len = 0;
-
- if (fcntl(id, F_SETLKW, &lk) < 0)
- return (0);
-
- i = fcntl(id, F_GETFL);
-
- if ((mode & O_ACCMODE) != O_RDONLY) {
- if ((i & O_ACCMODE) == O_RDONLY) {
- errno = EBADF;
- return (0);
- }
- }
-
- if ((mode & O_ACCMODE) != O_WRONLY) {
- if ((i & O_ACCMODE) == O_WRONLY) {
- errno = EBADF;
- return (0);
- }
- }
-
- mode = (i & O_ACCMODE) | (mode & ~O_ACCMODE);
-
- if (fcntl(id, F_SETFL, mode) < 0)
- return (0);
-
- if (lseek(id, 0, SEEK_SET) < 0)
- return (0);
-
- fd->sf_fd = id;
- fd->sf_fmode = mode;
-
- strcpy(fd->sf_path, path);
-
- return (fd);
-}
-
-
-static int
-_nsc_open_path(fd)
-nsc_fd_t *fd;
-{
- struct nscioc_open op;
-
- memset(&op, 0, sizeof (op));
-
- op.flag = fd->sf_flag;
- op.mode = fd->sf_fmode;
- strcpy(op.path, fd->sf_path);
-
- if ((fd->sf_fd = open(_NSC_DEV_PATH, fd->sf_fmode)) < 0)
- return (0);
-
- if (ioctl(fd->sf_fd, NSCIOC_OPEN, &op) == 0)
- return (1);
-
- close(fd->sf_fd);
- return (0);
-}
-
-
-static int
-_nsc_open_check(fd)
-nsc_fd_t *fd;
-{
- struct flock lk;
- char s[30];
- pid_t pid;
- int i;
-
- if ((fd->sf_fmode & O_ACCMODE) == O_RDONLY)
- return (1);
-
- if (access(_NSC_CKDCHK_PATH, X_OK) != 0)
- return (0);
-
- lk.l_type = F_WRLCK;
- lk.l_whence = SEEK_SET;
- lk.l_start = 0;
- lk.l_len = 0;
-
- if (fcntl(fd->sf_fd, F_SETLKW, &lk) < 0)
- return (0);
-
- if ((pid = fork()) == 0) {
- for (i = 1; i <= NSIG; i++)
- signal(i, SIG_IGN);
-
- for (i = fd->sf_fd; i <= 2 && (i = dup(i)) != -1; )
- fd->sf_fd = i;
-
- for (i = sysconf(_SC_OPEN_MAX); i >= 0; i--)
- if (i != fd->sf_fd)
- close(i);
-
- fcntl(fd->sf_fd, F_SETFD, 0);
-
- (void) open("/dev/null", 0);
- (void) open(_NSC_CKDCHK_LOG, O_WRONLY|O_CREAT|O_APPEND, 0666);
- (void) open(_NSC_CKDCHK_LOG, O_WRONLY|O_CREAT|O_APPEND, 0666);
-
- (void) sprintf(s, "%d", fd->sf_fd);
-
- (void) execl(_NSC_CKDCHK_PATH, "ckdchk", "-u", "-F",
- s, fd->sf_path, 0);
-
- exit(1);
- }
-
- return (pid != -1);
-}
-
-
-int
-nsc_close(fd)
-nsc_fd_t *fd;
-{
- int rc;
-
- if (!fd)
- return (0);
-
- rc = close(fd->sf_fd);
- free(fd);
-
- return (rc);
-}
-
-
-int
-nsc_reserve(fd)
-nsc_fd_t *fd;
-{
- return ((fd) ? ioctl(fd->sf_fd, NSCIOC_RESERVE, 0) : 0);
-}
-
-
-int
-nsc_release(fd)
-nsc_fd_t *fd;
-{
- if (!fd)
- return (0);
-
- if (ckdchk && (fd->sf_fmode & O_ACCMODE) != O_RDONLY) {
- errno = EINVAL;
- return (-1);
- }
-
- return (ioctl(fd->sf_fd, NSCIOC_RELEASE, 0));
-}
-
-
-int
-nsc_partsize(nsc_fd_t *fd, nsc_size_t *rvp)
-{
- struct nscioc_partsize partsize;
- int rc;
-
- if (!fd)
- return (0);
-
- rc = ioctl(fd->sf_fd, NSCIOC_PARTSIZE, &partsize);
- if (rc != 0) {
- return (rc);
- }
-
- *rvp = (nsc_size_t)partsize.partsize;
- return (0);
-}
-
-
-int
-nsc_fileno(fd)
-nsc_fd_t *fd;
-{
- return ((fd) ? fd->sf_fd : -1);
-}
-
-
-void
-_nsc_nocheck()
-{
- ckdchk = 0;
-}
-
-
-static int
-_nsc_do_ioctl(cmd, arg)
-int cmd;
-void *arg;
-{
- int fd, rc, save_errno;
-
- fd = open(_NSC_DEV_PATH, O_RDONLY);
- if (fd < 0)
- return (-1);
-
- rc = save_errno = 0;
- rc = ioctl(fd, cmd, arg);
- if (rc < 0)
- save_errno = errno;
-
- close(fd);
-
- errno = save_errno;
- return (rc);
-}
-
-
-/*
- * int
- * nsc_freeze(char *path)
- * Freeze a pathname
- *
- * Calling/Exit State:
- * Returns 0 for success, or -1 and sets errno.
- *
- * Description:
- * This is the user level interface to the nsctl freeze operation.
- * See uts/common/ns/nsctl/nsc_freeze.c for more information.
- */
-int
-nsc_freeze(path)
-char *path;
-{
- if (strlen(path) >= NSC_MAXPATH) {
- errno = ENAMETOOLONG;
- return (-1);
- }
-
- return (_nsc_do_ioctl(NSCIOC_FREEZE, path));
-}
-
-/*
- * int
- * nsc_unfreeze(char *path)
- * Unfreeze a pathname
- *
- * Calling/Exit State:
- * Returns 0 for success, or -1 and sets errno.
- *
- * Description:
- * This is the user level interface to the nsctl unfreeze operation.
- * See uts/common/ns/nsctl/nsc_freeze.c for more information.
- */
-int
-nsc_unfreeze(path)
-char *path;
-{
- if (strlen(path) >= NSC_MAXPATH) {
- errno = ENAMETOOLONG;
- return (-1);
- }
-
- return (_nsc_do_ioctl(NSCIOC_UNFREEZE, path));
-}
-
-
-/*
- * int
- * nsc_isfrozen(char *path)
- * Test if a pathname is frozen
- *
- * Calling/Exit State:
- * Returns:
- * 0 path is frozen
- * 1 path is not frozen
- * -1 error (errno will be set)
- *
- * Description
- * This is the user level interface to to the nsctl isfrozen operation.
- * See uts/common/ns/nsctl/nsc_freeze.c for more information.
- */
-int
-nsc_isfrozen(path)
-char *path;
-{
- if (strlen(path) >= NSC_MAXPATH) {
- errno = ENAMETOOLONG;
- return (-1);
- }
-
- return (_nsc_do_ioctl(NSCIOC_ISFROZEN, path));
-}
-
-int
-nsc_gmem_sizes(int *size)
-{
- return (_nsc_do_ioctl(NSCIOC_GLOBAL_SIZES, size));
-}
-
-int
-nsc_gmem_data(char *addr)
-{
- return (_nsc_do_ioctl(NSCIOC_GLOBAL_DATA, addr));
-}
-
-/*
- * int
- * nsc_nvclean()
- * mark nvmem clean, to prevent a warmstart of the cache on reboot
- */
-int
-nsc_nvclean(int force)
-{
- int cmd;
-
- cmd = force ? NSCIOC_NVMEM_CLEANF : NSCIOC_NVMEM_CLEAN;
-
- return (_nsc_do_ioctl(cmd, (void *)0));
-}
diff --git a/usr/src/lib/libnsctl/common/hash.c b/usr/src/lib/libnsctl/common/hash.c
deleted file mode 100644
index 1cc7e8f257..0000000000
--- a/usr/src/lib/libnsctl/common/hash.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <sys/nsctl/nsc_hash.h>
-
-#define HASH_PRIME 2039
-
-static int calc_hash(const char *);
-
-hash_node_t **
-nsc_create_hash()
-{
- hash_node_t **hash;
-
- hash = (hash_node_t **)calloc(HASH_PRIME, sizeof (hash_node_t *));
- return (hash);
-}
-
-int
-nsc_insert_node(hash_node_t **hash, void *data, const char *key)
-{
- int index;
- hash_node_t *node;
-
- node = (hash_node_t *)malloc(sizeof (hash_node_t));
- if (!node) {
- return (-1);
- }
- node->key = strdup(key);
- node->data = data;
-
- /*
- * possible enhancement would be to search
- * in this index for a duplicate
- */
- index = calc_hash(key);
- node->next = hash[ index ];
- hash[ index ] = node;
-
- return (0);
-}
-
-/*
- * lookup
- *
- * Description:
- * Searches the hash to find a node.
- *
- * Return values:
- * 0 if not found.
- * pointer to node if found.
- */
-void *
-nsc_lookup(hash_node_t **hash, const char *key)
-{
- int index;
- hash_node_t *node;
-
- index = calc_hash(key);
- node = hash[ index ];
- while (node) {
- if (strcmp(node->key, key) == 0)
- return (node->data);
- node = node->next;
- }
- return (0);
-}
-
-void *
-nsc_remove_node(hash_node_t **hash, char *key)
-{
- int index;
- hash_node_t *node, *prev;
- void *retval;
-
- index = calc_hash(key);
- if (!hash[ index ]) {
- return (0);
- }
-
- if (strcmp(hash[ index ]->key, key) == 0) {
- node = hash[ index ];
- retval = node->data;
- hash[ index ] = hash[ index ]->next;
- free(node->key);
- free(node);
- return (retval);
- }
- prev = hash[ index ];
- node = prev->next;
- while (node && (strcmp(node->key, key) != 0)) {
- prev = node;
- node = node->next;
- }
-
- /* did we find it? */
- if (node) {
- prev->next = node->next;
- retval = node->data;
- free(node->key);
- free(node);
- return (retval);
- }
- return (0);
-}
-
-void
-nsc_remove_all(hash_node_t **hash, void (*callback)(void *))
-{
- int i;
- hash_node_t *p, *next;
-
- for (i = 0; i < HASH_PRIME; i++) {
- p = hash[ i ];
- while (p) {
- next = p->next;
- if (callback) {
- callback(p->data);
- }
- free(p->key);
- free(p);
- p = next;
- }
- }
- free(hash);
-}
-
-/* ---------------------------------------------------------------------- */
-
-/*
- * Basic rotating hash, as per Knuth.
- */
-static int
-calc_hash(const char *key)
-{
- unsigned int hash, i;
- int len = strlen(key);
- for (hash = len, i = 0; i < len; i++) {
- hash = (hash << 5) ^ (hash >> 27) ^ key[ i ];
- }
- return (hash % HASH_PRIME);
-}
diff --git a/usr/src/lib/libnsctl/common/libnsctl.h b/usr/src/lib/libnsctl/common/libnsctl.h
deleted file mode 100644
index abd165ce42..0000000000
--- a/usr/src/lib/libnsctl/common/libnsctl.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-
-#ifndef _LIBNSCTL_H
-#define _LIBNSCTL_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/nsctl/nsctl.h>
-#include <sys/nsctl/nsc_ioctl.h>
-
-
-/*
- * Standard Definitions.
- */
-
-#ifdef sun
-#define _NSC_DEV_PATH "/dev/nsctl"
-#else
-#define _NSC_DEV_PATH "/dev/sd"
-#endif
-#define _NSC_CKDCHK_PATH "/usr/install/simckd/bin/ckdchk"
-#define _NSC_CKDCHK_LOG "/rsvd/dumps/ckdchk.log"
-
-
-typedef struct nsc_fd_s {
- int sf_fd; /* SD device */
- int sf_flag; /* Open flags */
- int sf_fmode; /* File modes */
- char sf_path[NSC_MAXPATH]; /* Pathname */
-} nsc_fd_t;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _LIBNSCTL_H */
diff --git a/usr/src/lib/libnsctl/common/llib-lnsctl b/usr/src/lib/libnsctl/common/llib-lnsctl
deleted file mode 100644
index 7defea0425..0000000000
--- a/usr/src/lib/libnsctl/common/llib-lnsctl
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/* LINTLIBRARY */
-/* PROTOLIB1 */
-
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <nsctl.h>
-#include <sys/nsctl/nsc_hash.h>
-
-void _nsc_nocheck(void);
-nsc_fd_t *nsc_open(char *path, int flag, int mode);
-nsc_fd_t *nsc_fdopen(int id, char *path, int mode);
-int nsc_close(nsc_fd_t *fd);
-int nsc_fileno(nsc_fd_t *fd);
-int nsc_reserve(nsc_fd_t *fd);
-int nsc_release(nsc_fd_t *fd);
-int nsc_partsize(nsc_fd_t *fd, nsc_size_t *size);
-int nsc_freeze(char *path);
-int nsc_unfreeze(char *path);
-int nsc_isfrozen(char *path);
-int nsc_getsystemid(int *id);
-int nsc_name_to_id(char *name, int *id);
-int nsc_id_to_name(char **name, int id);
-int nsc_check_release(const char *build_rel, nsc_release_t *map, char **reqd);
-hash_node_t **nsc_create_hash();
-int nsc_insert_node(hash_node_t **, void *, const char *);
-void *nsc_lookup(hash_node_t **, const char *);
-void *nsc_remove_node(hash_node_t **, char *);
-void nsc_remove_all(hash_node_t **, void (*)(void *));
diff --git a/usr/src/lib/libnsctl/common/machdep.c b/usr/src/lib/libnsctl/common/machdep.c
deleted file mode 100644
index d577995ad1..0000000000
--- a/usr/src/lib/libnsctl/common/machdep.c
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/utsname.h>
-#include <fcntl.h>
-#include <sys/param.h>
-#include <unistd.h>
-#include <stdarg.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "libnsctl.h"
-#include <nsctl.h>
-#include <sys/ncall/ncall.h>
-
-
-
-/*
- * Internal routine to fetch all the current nodes that are
- * considered 'up'.
- * Returns the number of ncall_info structures that are valid
- * returned via the nodelist pointer, or -1 on an error.
- * If the call succeeds, then the memory returned via the
- * nodelist pointer needs to be freed by the caller.
- */
-
-static int
-nsc_getcurrentnodes(ncall_node_t **nodelist)
-{
- ncall_node_t *mynodelist;
- int size;
- int fd;
- int rc = -1;
- int save_errno = 0;
- int ioctlcmd;
-
- if (nodelist == NULL) {
- errno = EINVAL;
- return (-1);
- }
- *nodelist = NULL;
- if ((fd = open("/dev/ncall", O_RDONLY)) < 0) {
- return (-1);
- }
- if ((size = ioctl(fd, NC_IOC_GETNETNODES, NULL)) < 1) {
- size = 1;
- ioctlcmd = NC_IOC_GETNODE;
- } else {
- ioctlcmd = NC_IOC_GETNETNODES;
- }
-
- mynodelist = malloc(size * sizeof (*mynodelist));
- if (mynodelist == NULL) {
- save_errno = ENOMEM;
- } else {
- rc = ioctl(fd, ioctlcmd, mynodelist);
- if (rc < 0) {
- save_errno = errno;
- free(mynodelist);
- } else {
- /* fixup return value for single node ioctl */
- if (ioctlcmd == NC_IOC_GETNODE)
- rc = 1;
- *nodelist = mynodelist;
- }
- }
- close(fd);
- errno = save_errno;
- return (rc);
-}
-
-
-/*
- * return the system id (the current value in the kernel
- * currently running).
- *
- * on error return -1 and set errno.
- */
-int
-nsc_getsystemid(int *id)
-{
- ncall_node_t node;
- int rval = 0;
- int save_errno = 0;
- int fd;
-
- *id = 0;
-
- fd = open("/dev/ncall", O_RDONLY);
- if (fd < 0)
- return (-1);
-
- memset(&node, 0, sizeof (node));
-
- rval = ioctl(fd, NC_IOC_GETNODE, &node);
- if (rval < 0)
- save_errno = errno;
- else {
- *id = node.nc_nodeid;
- /*
- * Return 0, not the mirror node id as returned
- * from the ioctl.
- */
- rval = 0;
- }
-
- close(fd);
-
- errno = save_errno;
- return (rval);
-}
-
-
-/*
- * Runtime Solaris release checking.
- *
- * Compare the build release to the runtime release to check for an
- * acceptable match.
- *
- * Arguments:
- * build_ver - the string Solaris build release (e.g. "5.8")
- * map - optional array of nsc_release_t defining
- * acceptable build release / runtime release
- * matches. If supplied, must end will a NULL
- * array element. See src/head/nsctl.h for info.
- * reqd - used to return the required OS versions if the
- * return value is not -1. The returned string
- * is readonly.
- *
- * Returns:
- * TRUE - acceptable match
- * FALSE - no match (component should not continue to run)
- * -1 - error (errno is set)
- */
-
-int
-nsc_check_release(const char *build_rel, nsc_release_t *map, char **reqd)
-{
- struct utsname uts;
- nsc_release_t *mp;
- const char *sep = ", ";
- char *cp, *tofree, *last;
- int rc;
-
- if (reqd)
- *reqd = NULL;
-
- if (build_rel == NULL || *build_rel == '\0') {
- errno = EINVAL;
- return (-1);
- }
-
- /* assume that build_rel is the required release for now */
- if (reqd)
- *reqd = (char *)build_rel;
-
- if (uname(&uts) < 0)
- return (-1);
-
- /* build release == runtime release is always acceptable */
- if (strcmp(build_rel, uts.release) == 0)
- return (TRUE);
-
- if (map == NULL)
- return (FALSE);
-
- rc = FALSE;
- tofree = NULL;
-
- for (mp = map; mp->build != NULL && mp->runtime != NULL; mp++) {
- if (strcmp(mp->build, build_rel) == 0) {
- /*
- * found an entry for this build release
- * - search for a match in the runtime releases
- */
-
- /* reset reqd to this entry */
- if (reqd)
- *reqd = (char *)mp->runtime;
-
- /*
- * operate on a copy of the string since strtok
- * is destructive.
- */
- tofree = cp = strdup(mp->runtime);
- if (cp == NULL) {
- errno = ENOMEM;
- rc = -1;
- break;
- }
-
- cp = strtok_r(cp, sep, &last);
- while (cp != NULL) {
- if (strcmp(cp, uts.release) == 0) {
- rc = TRUE;
- break;
- }
-
- cp = strtok_r(NULL, sep, &last);
- }
-
- break;
- }
- }
-
- if (tofree)
- free(tofree);
-
- return (rc);
-}
-
-
-/*
- * return the system id corresponding to name
- *
- * on error return -1 and set errno.
- */
-int
-nsc_name_to_id(char *name, int *id)
-{
- ncall_node_t *nodes;
- int rval = 0;
- int nodecnt;
- int slot;
-
- *id = 0;
-
- nodecnt = nsc_getcurrentnodes(&nodes);
- if (nodecnt < 0) {
- rval = -1;
- } else {
- for (slot = 0; slot < nodecnt; slot++) {
- if (strcmp(name, nodes[slot].nc_nodename) == 0) {
- *id = nodes[slot].nc_nodeid;
- break;
- }
- }
- if (slot >= nodecnt) {
- errno = ENOENT;
- rval = -1;
- }
- free(nodes);
- }
- return (rval);
-}
-
-/*
- * return the node name corresponding to system id
- *
- * on error return -1 and set errno.
- * The returned string has been strdup() and needs
- * to be freed by the caller.
- */
-int
-nsc_id_to_name(char **name, int id)
-{
- ncall_node_t *nodes;
- int rval = 0;
- int nodecnt;
- int slot;
- char *foundname;
-
- *name = 0;
- foundname = NULL;
-
- nodecnt = nsc_getcurrentnodes(&nodes);
- if (nodecnt < 0) {
- rval = -1;
- } else {
- for (slot = 0; slot < nodecnt; slot++) {
- if (nodes[slot].nc_nodeid == id) {
- foundname = strdup(nodes[slot].nc_nodename);
- if (foundname) {
- *name = foundname;
- } else {
- errno = ENOMEM;
- rval = -1;
- }
- break;
- }
- }
- if (slot >= nodecnt) {
- errno = ENOENT;
- rval = -1;
- }
- free(nodes);
- }
- return (rval);
-}
diff --git a/usr/src/lib/libnsctl/common/mapfile-vers b/usr/src/lib/libnsctl/common/mapfile-vers
deleted file mode 100644
index eb399179e2..0000000000
--- a/usr/src/lib/libnsctl/common/mapfile-vers
+++ /dev/null
@@ -1,70 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
-#
-
-#
-# MAPFILE HEADER START
-#
-# WARNING: STOP NOW. DO NOT MODIFY THIS FILE.
-# Object versioning must comply with the rules detailed in
-#
-# usr/src/lib/README.mapfiles
-#
-# You should not be making modifications here until you've read the most current
-# copy of that file. If you need help, contact a gatekeeper for guidance.
-#
-# MAPFILE HEADER END
-#
-
-$mapfile_version 2
-
-#
-# Generic interface definition for usr/src/lib/libnsctl.
-#
-
-SYMBOL_VERSION SUNWprivate_1.1 {
- global:
- _nsc_nocheck;
- nsc_check_release;
- nsc_close;
- nsc_fdopen;
- nsc_fileno;
- nsc_freeze;
- nsc_getsystemid;
- nsc_gmem_data;
- nsc_gmem_sizes;
- nsc_id_to_name;
- nsc_isfrozen;
- nsc_name_to_id;
- nsc_nvclean;
- nsc_open;
- nsc_partsize;
- nsc_release;
- nsc_reserve;
- nsc_unfreeze;
- nsc_create_hash;
- nsc_insert_node;
- nsc_lookup;
- nsc_remove_node;
- nsc_remove_all;
- local:
- *;
-};
diff --git a/usr/src/lib/libnsctl/common/nsc_hash.h b/usr/src/lib/libnsctl/common/nsc_hash.h
deleted file mode 100644
index 80cf846861..0000000000
--- a/usr/src/lib/libnsctl/common/nsc_hash.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _NSC_HASH_H
-#define _NSC_HASH_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct hash_node_s {
- struct hash_node_s *next;
- char *key;
- void *data;
-} hash_node_t;
-
-hash_node_t **nsc_create_hash();
-int nsc_insert_node(hash_node_t **, void *, const char *);
-void *nsc_lookup(hash_node_t **, const char *);
-void *nsc_remove_node(hash_node_t **, char *);
-void nsc_remove_all(hash_node_t **, void (*)(void *));
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _NSC_HASH_H */
diff --git a/usr/src/lib/libnsctl/i386/Makefile b/usr/src/lib/libnsctl/i386/Makefile
deleted file mode 100644
index a360cc9a91..0000000000
--- a/usr/src/lib/libnsctl/i386/Makefile
+++ /dev/null
@@ -1,36 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# lib/libnsctl/i386/Makefile
-
-include ../Makefile.com
-
-.KEEP_STATE:
-
-all: $(LIBS)
-
-install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTARLINK)
-
-lint:
-lintinter:
-
diff --git a/usr/src/lib/libnsctl/sparc/Makefile b/usr/src/lib/libnsctl/sparc/Makefile
deleted file mode 100644
index 9e5f62fb13..0000000000
--- a/usr/src/lib/libnsctl/sparc/Makefile
+++ /dev/null
@@ -1,30 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# lib/libnsctl/sparc/Makefile
-
-include ../Makefile.com
-
-all: $(LIBS)
-
-install: all $(ROOTLIBS) $(ROOTLINKS)
diff --git a/usr/src/lib/librdc/Makefile b/usr/src/lib/librdc/Makefile
deleted file mode 100644
index 8c56e8f017..0000000000
--- a/usr/src/lib/librdc/Makefile
+++ /dev/null
@@ -1,60 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# lib/librdc/Makefile
-
-include ../Makefile.lib
-
-HDRS= librdc.h rdcerr.h rdcrules.h
-HDRDIR= common
-
-SUBDIRS= $(MACH)
-
-ROOTHDRDIR= $(ROOT)/usr/include/sys/nsctl
-
-ROOTHDRS= $(HDRS:%=$(ROOTHDRDIR)/%)
-
-all := TARGET= all
-clean := TARGET= clean
-clobber := TARGET= clobber
-install := TARGET= install
-lint := TARGET= lint
-
-.KEEP_STATE:
-
-all clean clobber install lint: $(SUBDIRS)
-
-$(MACH): FRC
- @cd $@; pwd; $(MAKE) $(TARGET)
-
-install_h: $(ROOTHDRDIR) $(ROOTHDRS)
-
-$(ROOTHDRDIR)/%: common/%
- $(INS.file)
-
-$(ROOTHDRDIR):
- $(INS.dir)
-
-check: $(CHECKHDRS)
-
-FRC:
diff --git a/usr/src/lib/librdc/Makefile.com b/usr/src/lib/librdc/Makefile.com
deleted file mode 100644
index 1819191a1c..0000000000
--- a/usr/src/lib/librdc/Makefile.com
+++ /dev/null
@@ -1,92 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# lib/librdc/Makefile.com
-
-LIBRARY= librdc.a
-VERS= .1
-
-OBJECTS= netaddrs.o rdcerr.o rdcconfig.o rdc_ioctl.o rdcpersist.o rdcrules.o
-
-# include library definitions
-include ../../Makefile.lib
-
-SRCS= ../common/*.c ../../../cmd/avs/rdc/rdc_ioctl.c
-SRCDIR= ../common
-
-LIBS += $(DYNLIB) $(LINTLIB)
-
-# definitions for lint
-
-LINTFLAGS += -u -I.. -DDEBUG
-LINTFLAGS += -erroff=E_FUNC_SET_NOT_USED
-LINTFLAGS += -erroff=E_STATIC_UNUSED
-LINTFLAGS += -erroff=E_SEC_PRINTF_VAR_FMT
-LINTFLAGS += -erroff=E_SEC_SCANF_UNBOUNDED_COPY
-LINTFLAGS += -erroff=E_FUNC_RET_ALWAYS_IGNOR2
-LINTFLAGS += -erroff=E_FUNC_RET_MAYBE_IGNORED2
-LINTFLAGS += -erroff=E_INCONS_VAL_TYPE_DECL2
-LINTFLAGS += -erroff=E_BAD_FORMAT_ARG_TYPE2
-LINTOUT= lint.out
-LINTOUT_INTER= lintinter.out
-
-CERRWARN += -_gcc=-Wno-parentheses
-CERRWARN += -_gcc=-Wno-unused-variable
-CERRWARN += -_gcc=-Wno-address
-
-LINTSRC= $(LINTLIB:%.ln=%)
-ROOTLINTDIR= $(ROOTLIBDIR)
-ROOTLINT= $(LINTSRC:%=$(ROOTLINTDIR)/%)
-
-CLEANFILES += $(LINTOUT) $(LINTLIB) $(LINTOUT_INTER) $(LINT_INTER)
-
-CPPFLAGS += -DBUILD_REV_STR='"5.11"'
-CFLAGS += -I..
-CFLAGS64 += -I..
-LDLIBS += -lsocket -lnsl -lnsctl -lc -lunistat -ldscfg
-
-$(LINTLIB) := SRCS = ../common/llib-lrdc
-$(LINTLIB) := LINTFLAGS = -nvx
-$(LINTLIB) := LINTFLAGS64 = -nvx
-
-$(LINT_INTER) := SRCS += ../common/llib-lrdc
-
-.KEEP_STATE:
-
-lint: lintcheck $(LINTLIB)
-lintinter: $(LINT_INTER)
-
-# include library targets
-include ../../Makefile.targ
-
-objs/%.o pics/%.o: ../common/%.c
- $(COMPILE.c) -o $@ $<
- $(POST_PROCESS_O)
-
-objs/rdc_ioctl.o pics/rdc_ioctl.o: ../../../cmd/avs/rdc/rdc_ioctl.c
- $(COMPILE.c) -o $@ ../../../cmd/avs/rdc/rdc_ioctl.c
- $(POST_PROCESS_O)
-
-# install rule for lint library target
-$(ROOTLINTDIR)/%: ../common/%
- $(INS.file)
diff --git a/usr/src/lib/librdc/common/librdc.h b/usr/src/lib/librdc/common/librdc.h
deleted file mode 100644
index 99ac34afe7..0000000000
--- a/usr/src/lib/librdc/common/librdc.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _LIBRDC_H
-#define _LIBRDC_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern int Is_ipv6present(void);
-extern int self_check(char *);
-extern int gethost_netaddrs(char *, char *, char *, char *);
-extern struct hostent *gethost_byname(const char *);
-extern struct netbuf *get_addr(char *, ulong_t, ulong_t, struct netconfig **,
- char *, char *, struct t_info *, int);
-extern int convert_nconf_to_knconf(struct netconfig *, struct knetconfig *);
-extern int rdc_check_release(char **);
-
-#if !defined(NSC_MAXPATH)
-#define NSC_MAXPATH 64
-#endif
-
-#define RDC_MAX_THREADS 1024
-/* user interface to sndr */
-typedef struct rdcconfig_s {
- char phost[NSC_MAXPATH];
- char pfile[NSC_MAXPATH];
- char pbmp[NSC_MAXPATH];
- char shost[NSC_MAXPATH];
- char sfile[NSC_MAXPATH];
- char sbmp[NSC_MAXPATH];
- char direct[NSC_MAXPATH];
- char mode[NSC_MAXPATH];
- char group[NSC_MAXPATH];
- char ctag[NSC_MAXPATH];
- char options[NSC_MAXPATH];
- int persist; /* 0 no, 1 yes */
- struct rdcconfig_s *next;
-} rdcconfig_t;
-
-#define RDC_ERR_SIZE 256
-
-typedef struct rdc_rc_s {
- int rc;
- char msg[RDC_ERR_SIZE];
- struct rdc_rc_s *next;
- rdcconfig_t set;
-} rdc_rc_t;
-
-#define RDC_FREEONE 0 /* free one rdcconfig_t* */
-#define RDC_FREEALL 1 /* free entire chain of rdcconfig_t* */
-
-/* and it's operations */
-extern rdcconfig_t *rdc_alloc_config(const char *phost, const char *pfile,
- const char *pbmp, const char *shost, const char *sfile, const char *sbmp,
- const char *mode, const char *group, const char *ctag, const char *options,
- int persist);
-extern void rdc_free_config(rdcconfig_t *rdc, int all);
-extern void rdc_free_rclist(rdc_rc_t *rc);
-extern rdc_rc_t *new_rc(void);
-extern rdc_rc_t *rdc_enable(rdcconfig_t *rdc);
-extern rdc_rc_t *rdc_enable_clrbmp(rdcconfig_t *rdc);
-extern rdc_rc_t *rdc_disable(rdcconfig_t *rdc);
-extern rdc_rc_t *rdc_log(rdcconfig_t *rdc);
-extern rdc_rc_t *rdc_usync(rdcconfig_t *rdc);
-extern rdc_rc_t *rdc_fsync(rdcconfig_t *rdc);
-extern rdc_rc_t *rdc_rsync(rdcconfig_t *rdc);
-extern rdc_rc_t *rdc_ursync(rdcconfig_t *rdc);
-extern rdc_rc_t *rdc_wait(rdcconfig_t *rdc);
-extern rdc_rc_t *rdc_set_autosync(rdcconfig_t *rdc, int autosync);
-extern rdc_rc_t *rdc_set_maxqfbas(rdcconfig_t *rdc, int maxqfbas);
-extern rdc_rc_t *rdc_set_maxqitems(rdcconfig_t *rdc, int maxqitems);
-extern int rdc_get_maxqfbas(rdcconfig_t *rdc);
-extern int rdc_get_maxqitems(rdcconfig_t *rdc);
-extern int rdc_get_autosync(rdcconfig_t *rdc);
-extern rdc_rc_t *rdc_reconfig_pbmp(rdcconfig_t *rdc, char *pbmp);
-extern rdc_rc_t *rdc_reconfig_sbmp(rdcconfig_t *rdc, char *sbmp);
-extern rdc_rc_t *rdc_reconfig_group(rdcconfig_t *rdc, char *group);
-extern rdc_rc_t *rdc_reconfig_ctag(rdcconfig_t *rdc, char *ctag);
-extern rdc_rc_t *rdc_set_sync(rdcconfig_t *rdc);
-extern rdc_rc_t *rdc_set_async(rdcconfig_t *rdc);
-extern rdc_rc_t *rdc_health(rdcconfig_t *rdc);
-extern rdc_rc_t *rdc_reverse_role(rdcconfig_t *rdc);
-extern char *rdc_error(int *sev);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _LIBRDC_H */
diff --git a/usr/src/lib/librdc/common/llib-lrdc b/usr/src/lib/librdc/common/llib-lrdc
deleted file mode 100644
index 03b796f3be..0000000000
--- a/usr/src/lib/librdc/common/llib-lrdc
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/* LINTLIBRARY */
-/* PROTOLIB1 */
-
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/stream.h>
-#include <sys/socket.h>
-#include <sys/poll.h>
-#include <rpc/rpc.h>
-#include <netconfig.h>
-#include "librdc.h"
-
-int Is_ipv6present(void);
-int self_check(char *hostname);
-int gethost_netaddrs(char *fromhost, char *tohost, char *fromnetaddr,
- char *tonetaddr);
-struct hostent *gethost_byname(const char *name);
-struct netbuf *get_addr(char *hostname, ulong_t prog, ulong_t vers,
- struct netconfig **nconfp, char *proto, char *srvport,
- struct t_info *tinfo, int portmap);
-int convert_nconf_to_knconf(struct netconfig *nconf, struct knetconfig *knconf);
-int rdc_check_release(char **reqd);
diff --git a/usr/src/lib/librdc/common/mapfile-vers b/usr/src/lib/librdc/common/mapfile-vers
deleted file mode 100644
index e38650b2a3..0000000000
--- a/usr/src/lib/librdc/common/mapfile-vers
+++ /dev/null
@@ -1,84 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
-#
-
-#
-# MAPFILE HEADER START
-#
-# WARNING: STOP NOW. DO NOT MODIFY THIS FILE.
-# Object versioning must comply with the rules detailed in
-#
-# usr/src/lib/README.mapfiles
-#
-# You should not be making modifications here until you've read the most current
-# copy of that file. If you need help, contact a gatekeeper for guidance.
-#
-# MAPFILE HEADER END
-#
-
-#
-# Generic interface definition for usr/src/lib/librdc.
-#
-
-$mapfile_version 2
-
-SYMBOL_VERSION SUNWprivate_1.1 {
- global:
- Is_ipv6present;
- convert_nconf_to_knconf;
- get_addr;
- gethost_byname;
- gethost_netaddrs;
- rdc_check_release;
- rdc_set_error;
- rdc_alloc_config;
- rdc_free_config;
- rdc_free_rclist;
- self_check;
- rdc_enable;
- rdc_enable_clrbmp;
- rdc_disable;
- rdc_log;
- rdc_usync;
- rdc_fsync;
- rdc_rsync;
- rdc_ursync;
- rdc_wait;
- rdc_set_autosync;
- rdc_set_maxqfbas;
- rdc_set_maxqitems;
- rdc_get_maxqfbas;
- rdc_get_maxqitems;
- rdc_get_autosync;
- rdc_reconfig_pbmp;
- rdc_reconfig_sbmp;
- rdc_reconfig_group;
- rdc_reconfig_ctag;
- rdc_set_sync;
- rdc_set_async;
- rdc_health;
- rdc_reverse_role;
- rdc_error;
-
- local:
- *;
-};
diff --git a/usr/src/lib/librdc/common/netaddrs.c b/usr/src/lib/librdc/common/netaddrs.c
deleted file mode 100644
index ed90358618..0000000000
--- a/usr/src/lib/librdc/common/netaddrs.c
+++ /dev/null
@@ -1,670 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <locale.h>
-#include <stdio.h>
-#include <string.h>
-#include <memory.h>
-#include <varargs.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <sys/param.h>
-#include <rpc/rpc.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <netdb.h>
-#include <sys/pathconf.h>
-#include <netdir.h>
-#include <netconfig.h>
-#include <sys/sockio.h>
-#include <net/if.h>
-#include <syslog.h>
-#include <netinet/in.h>
-#include <nfs/nfs_sec.h>
-#include <strings.h>
-#include <sys/nsctl/rdc_prot.h>
-#include <nsctl.h>
-
-#include "librdc.h"
-
-#define MAXIFS 32
-
-/* number of transports to try */
-#define MNT_PREF_LISTLEN 2
-#define FIRST_TRY 1
-#define SECOND_TRY 2
-
-
-int
-Is_ipv6present(void)
-{
-#ifdef AF_INET6
- int sock;
- struct lifnum lifn;
-
- sock = socket(AF_INET6, SOCK_DGRAM, 0);
- if (sock < 0)
- return (0);
-
- lifn.lifn_family = AF_INET6;
- lifn.lifn_flags = 0;
- if (ioctl(sock, SIOCGLIFNUM, (char *)&lifn) < 0) {
- close(sock);
- return (0);
- }
- close(sock);
- if (lifn.lifn_count == 0)
- return (0);
- return (1);
-#else
- return (0);
-#endif
-}
-
-/*
- * The following is stolen from autod_nfs.c
- */
-static void
-getmyaddrs(struct ifconf *ifc)
-{
- int sock;
- int numifs;
- char *buf;
- int family;
-
- ifc->ifc_buf = NULL;
- ifc->ifc_len = 0;
-
-#ifdef AF_INET6
- family = AF_INET6;
-#else
- family = AF_INET;
-#endif
- if ((sock = socket(family, SOCK_DGRAM, 0)) < 0) {
-#ifdef DEBUG
- perror("getmyaddrs(): socket");
-#endif
- return;
- }
-
- if (ioctl(sock, SIOCGIFNUM, (char *)&numifs) < 0) {
-#ifdef DEBUG
- perror("getmyaddrs(): SIOCGIFNUM");
-#endif
- numifs = MAXIFS;
- }
-
- buf = (char *)malloc(numifs * sizeof (struct ifreq));
- if (buf == NULL) {
-#ifdef DEBUG
- fprintf(stderr, "getmyaddrs(): malloc failed\n");
-#endif
- (void) close(sock);
- return;
- }
-
- ifc->ifc_buf = buf;
- ifc->ifc_len = numifs * sizeof (struct ifreq);
-
- if (ioctl(sock, SIOCGIFCONF, (char *)ifc) < 0) {
-#ifdef DEBUG
- perror("getmyaddrs(): SIOCGIFCONF");
-#else
- ;
- /*EMPTY*/
-#endif
- }
-
- (void) close(sock);
-}
-
-int
-self_check(char *hostname)
-{
- int n;
- struct sockaddr_in *s1, *s2;
- struct ifreq *ifr;
- struct nd_hostserv hs;
- struct nd_addrlist *retaddrs;
- struct netconfig *nconfp;
- struct ifconf *ifc;
- int retval;
-
- ifc = malloc(sizeof (struct ifconf));
- if (ifc == NULL)
- return (0);
- memset((char *)ifc, 0, sizeof (struct ifconf));
- getmyaddrs(ifc);
- /*
- * Get the IP address for hostname
- */
- nconfp = getnetconfigent("udp");
- if (nconfp == NULL) {
-#ifdef DEBUG
- fprintf(stderr, "self_check(): getnetconfigent failed\n");
-#endif
- retval = 0;
- goto out;
- }
- hs.h_host = hostname;
- hs.h_serv = "rpcbind";
- if (netdir_getbyname(nconfp, &hs, &retaddrs) != ND_OK) {
- freenetconfigent(nconfp);
- retval = 0;
- goto out;
- }
- freenetconfigent(nconfp);
- /* LINTED pointer alignment */
- s1 = (struct sockaddr_in *)retaddrs->n_addrs->buf;
-
- /*
- * Now compare it against the list of
- * addresses for the interfaces on this
- * host.
- */
- ifr = ifc->ifc_req;
- n = ifc->ifc_len / sizeof (struct ifreq);
- s2 = NULL;
- for (; n > 0; n--, ifr++) {
- if (ifr->ifr_addr.sa_family != AF_INET)
- continue;
-
- /* LINTED pointer alignment */
- s2 = (struct sockaddr_in *)&ifr->ifr_addr;
-
- if (memcmp((char *)&s2->sin_addr,
- (char *)&s1->sin_addr, sizeof (s1->sin_addr)) == 0) {
- netdir_free((void *)retaddrs, ND_ADDRLIST);
- retval = 1;
- goto out; /* it's me */
- }
- }
- netdir_free((void *)retaddrs, ND_ADDRLIST);
- retval = 0;
-
-out:
- if (ifc->ifc_buf != NULL)
- free(ifc->ifc_buf);
- free(ifc);
- return (retval);
-}
-
-
-int
-convert_nconf_to_knconf(struct netconfig *nconf, struct knetconfig *knconf)
-{
- struct stat sb;
-
- if (stat(nconf->nc_device, &sb) < 0) {
- (void) syslog(LOG_ERR, "can't find device for transport %s\n",
- nconf->nc_device);
- return (-1);
- }
-#ifdef DEBUG_ADDR
- printf("lib knconf %x %s %s %x\n", nconf->nc_semantics,
- nconf->nc_protofmly, nconf->nc_proto, sb.st_rdev);
-#endif
-
- knconf->knc_semantics = nconf->nc_semantics;
- knconf->knc_protofmly = nconf->nc_protofmly;
- knconf->knc_proto = nconf->nc_proto;
- knconf->knc_rdev = sb.st_rdev;
-
- return (0);
-}
-
-struct hostent *
-gethost_byname(const char *name)
-{
- int errnum;
-#ifdef AF_INET6
- return (getipnodebyname(name, AF_INET6, AI_DEFAULT, &errnum));
-#else /* !AF_INET6 */
- return (gethostbyname(name));
-#endif /* AF_INET6 */
-}
-
-int
-gethost_netaddrs(char *fromhost, char *tohost,
- char *fromnetaddr, char *tonetaddr)
-{
- struct hostent *host;
- int j;
- int errnum;
-
-#ifdef AF_INET6
- host = getipnodebyname(fromhost, AF_INET6, AI_DEFAULT, &errnum);
- if (host == NULL) {
-#ifdef DEBUG
- (void) fprintf(stderr, dgettext("sndr",
- "Could not find host %s"), fromhost);
-#endif
- return (-1);
- }
- for (j = 0; j < host->h_length; j++)
- fromnetaddr[j] = host->h_addr[j];
- freehostent(host);
-#else /* !AF_INET6 */
- host = gethostbyname(fromhost);
- if (host == NULL) {
-#ifdef DEBUG
- (void) fprintf(stderr, dgettext("sndr",
- "Could not find host %s"), fromhost);
-#endif
- return (-1);
- }
-
- if (host->h_length < 4) {
-#ifdef DEBUG
- fprintf(stderr, "host->h_length(%d) < 4!\n", host->h_length);
-#endif
- return (-1);
- }
-
- for (j = 0; j < host->h_length; j++)
- fromnetaddr[j] = host->h_addr[j];
-#endif /* AF_INET6 */
-
-#ifdef AF_INET6
- host = getipnodebyname(tohost, AF_INET6, AI_DEFAULT, &errnum);
- if (host == NULL) {
-#ifdef DEBUG
- (void) fprintf(stderr, dgettext("sndr",
- "Could not find host %s"), tohost);
-#endif
- return (-1);
- }
- for (j = 0; j < host->h_length; j++)
- tonetaddr[j] = host->h_addr[j];
- freehostent(host);
-#else /* !AF_INET6 */
- host = gethostbyname(tohost);
- if (host == NULL) {
-#ifdef DEBUG
- (void) fprintf(stderr, dgettext("sndr",
- "Could not find host %s"), tohost);
-#endif
- return (-1);
- }
-
- if (host->h_length < 4) {
-#ifdef DEBUG
- fprintf(stderr, "host->h_length(%d) < 4!\n", host->h_length);
-#endif
- return (-1);
- }
-
- for (j = 0; j < host->h_length; j++)
- tonetaddr[j] = host->h_addr[j];
-#endif /* AF_INET6 */
- return (0);
-}
-
-/*
- * Get the network address on "hostname" for program "prog"
- * with version "vers" by using the nconf configuration data
- * passed in.
- *
- * If the address of a netconfig pointer is null then
- * information is not sufficient and no netbuf will be returned.
- *
- * Finally, ping the null procedure of that service.
- *
- */
-static struct netbuf *
-get_the_addr(char *hostname, ulong_t prog, ulong_t vers,
- struct netconfig *nconf, ushort_t port, struct t_info *tinfo,
- int portmap)
-{
- struct netbuf *nb = NULL;
- struct t_bind *tbind = NULL;
- CLIENT *cl = NULL;
- struct timeval tv;
- int fd = -1;
- AUTH *ah = NULL;
-
- if (nconf == NULL)
- return (NULL);
-
- if ((fd = t_open(nconf->nc_device, O_RDWR, tinfo)) == -1)
- goto done;
-
- /* LINTED pointer alignment */
- if ((tbind = (struct t_bind *)t_alloc(fd, T_BIND, T_ADDR)) == NULL)
- goto done;
-
- if (portmap) { /* contact rpcbind */
- if (rpcb_getaddr(prog, vers, nconf, &tbind->addr,
- hostname) == FALSE) {
- goto done;
- }
-
- if (port) {
- if (strcmp(nconf->nc_protofmly, NC_INET) == 0)
- /* LINTED pointer alignment */
- ((struct sockaddr_in *)tbind->addr.buf)->sin_port
- = port;
-#ifdef NC_INET6
- else if (strcmp(nconf->nc_protofmly, NC_INET6) == 0)
- /* LINTED pointer alignment */
- ((struct sockaddr_in6 *)tbind->addr.buf)->sin6_port
- = port;
-#endif
- }
-
- /* Simon -- we never use the client we create?! */
- cl = clnt_tli_create(fd, nconf, &tbind->addr, prog, vers, 0, 0);
- if (cl == NULL)
- goto done;
-
- ah = authsys_create_default();
- if (ah != NULL)
- cl->cl_auth = ah;
-
- tv.tv_sec = 5;
- tv.tv_usec = 0;
-
- (void) clnt_control(cl, CLSET_TIMEOUT, (char *)&tv);
- } else { /* create our own address and skip rpcbind */
- struct netbuf *nb;
- struct hostent *hp;
- int j;
- int errnum;
- unsigned short family;
- nb = &(tbind->addr);
-
-#ifdef AF_INET6
- if (strcmp(nconf->nc_protofmly, NC_INET6) == 0) {
- hp = getipnodebyname(hostname, AF_INET6, 0, &errnum);
- family = AF_INET6;
- nb->len = nb->maxlen = sizeof (struct sockaddr_in6);
- } else {
- hp = getipnodebyname(hostname, AF_INET, 0, &errnum);
- family = AF_INET;
- nb->len = nb->maxlen = sizeof (struct sockaddr_in);
- }
- if (hp == NULL) {
-#ifdef DEBUG_ADDR
- (void) fprintf(stderr, dgettext("sndr",
- "Could not find host %s\n"), hostname);
-#endif
- goto done;
- }
- nb->buf = (char *)calloc(1, nb->maxlen);
- if (nb->buf == NULL) {
- (void) printf(dgettext("sndr", "no memory\n"));
- goto done;
- }
-
- if (family == AF_INET) {
- for (j = 0; j < hp->h_length; j++)
- nb->buf[j+4] = hp->h_addr[j];
- /* LINTED pointer alignment */
- ((struct sockaddr_in *)(nb->buf))->sin_port = port;
- /* LINTED pointer alignment */
- ((struct sockaddr_in *)(nb->buf))->sin_family = AF_INET;
- } else {
- for (j = 0; j < hp->h_length; j++)
- nb->buf[j+8] = hp->h_addr[j];
- /* LINTED pointer alignment */
- ((struct sockaddr_in6 *)(nb->buf))->sin6_port = port;
- /* LINTED pointer alignment */
- ((struct sockaddr_in6 *)(nb->buf))->sin6_family =
- AF_INET6;
- }
- freehostent(hp);
-#else
- hp = gethostbyname(hostname);
- if (hp == NULL) {
-#ifdef DEBUG
- (void) fprintf(stderr, dgettext("sndr",
- "Could not find host %s"), hostname);
-#endif
- goto done;
- }
-
- nb->len = nb->maxlen = sizeof (struct sockaddr_in);
- nb->buf = (char *)calloc(1, nb->maxlen);
- if (nb->buf == NULL) {
- (void) printf(dgettext("sndr", "no memory\n"));
- free(nb);
- nb = NULL;
- goto done;
- }
-
- for (j = 0; j < hp->h_length; j++)
- nb->buf[j+4] = hp->h_addr[j];
-
- if (hp->h_addrtype == AF_INET) {
- ((struct sockaddr_in *)(nb->buf))->sin_port = port;
- ((struct sockaddr_in *)(nb->buf))->sin_family = AF_INET;
- }
-#endif
- }
-
- /*
- * Make a copy of the netbuf to return
- */
- nb = (struct netbuf *)calloc(1, sizeof (*nb));
- if (nb == NULL) {
- (void) printf(dgettext("sndr", "no memory\n"));
- goto done;
- }
-
- *nb = tbind->addr; /* structure copy */
-
- nb->buf = (char *)calloc(1, nb->maxlen);
- if (nb->buf == NULL) {
- (void) printf(dgettext("sndr", "no memory\n"));
- free(nb);
- nb = NULL;
- goto done;
- }
-
- (void) memcpy(nb->buf, tbind->addr.buf, tbind->addr.len);
-
-done:
- if (cl) {
- if (ah != NULL) {
- AUTH_DESTROY(cl->cl_auth);
- cl->cl_auth = NULL;
- }
-
- clnt_destroy(cl);
- cl = NULL;
- }
-
- if (tbind) {
- t_free((char *)tbind, T_BIND);
- tbind = NULL;
- }
-
- if (fd >= 0)
- (void) t_close(fd);
- return (nb);
-}
-
-/*
- * Get a network address on "hostname" for program "prog"
- * with version "vers". If the port number is specified (non zero)
- * then try for a TCP/UDP transport and set the port number of the
- * resulting IP address.
- *
- * If the address of a netconfig pointer was passed and
- * if it's not null, use it as the netconfig otherwise
- * assign the address of the netconfig that was used to
- * establish contact with the service.
- * If portmap is false, we return a similiar address and we do not
- * contact rpcbind
- *
- */
-struct netbuf *
-get_addr(char *hostname, ulong_t prog, ulong_t vers, struct netconfig **nconfp,
- char *proto, char *srvport, struct t_info *tinfo, int portmap)
-{
- struct netbuf *nb = NULL;
- struct netconfig *nconf = NULL;
- NCONF_HANDLE *nc = NULL;
- int nthtry = FIRST_TRY;
- struct servent *svp;
- ushort_t port;
-
- /*
- * First lets get the requested port
- */
-
- if ((svp = getservbyname(srvport, proto)) == NULL)
- goto done;
- port = svp->s_port;
- /*
- * No nconf passed in.
- *
- * Try to get a nconf from /etc/netconfig filtered by
- * the NETPATH environment variable.
- * First search for COTS, second for CLTS unless proto
- * is specified. When we retry, we reset the
- * netconfig list so that we would search the whole list
- * all over again.
- */
- if ((nc = setnetpath()) == NULL)
- goto done;
-
- /*
- * If proto is specified, then only search for the match,
- * otherwise try COTS first, if failed, try CLTS.
- */
- if (proto) {
- while (nconf = getnetpath(nc)) {
- if (strcmp(nconf->nc_netid, proto) == 0) {
- /*
- * If the port number is specified then TCP/UDP
- * is needed. Otherwise any cots/clts will do.
- */
- if (port == 0)
- break;
-
- if ((strcmp(nconf->nc_protofmly, NC_INET) == 0
-#ifdef NC_INET6
- /* CSTYLED */
- || strcmp(nconf->nc_protofmly, NC_INET6) == 0
-#endif
- /* CSTYLED */
- ) &&
- (strcmp(nconf->nc_proto, NC_TCP) == 0 ||
- strcmp(nconf->nc_proto, NC_UDP) == 0))
- break;
- else {
- nconf = NULL;
- break;
- }
- }
- }
- if (nconf == NULL)
- goto done;
- if ((nb = get_the_addr(hostname, prog, vers, nconf, port,
- tinfo, portmap)) == NULL) {
- goto done;
- }
- } else {
-retry:
- while (nconf = getnetpath(nc)) {
- if (nconf->nc_flag & NC_VISIBLE) {
- if (nthtry == FIRST_TRY) {
- if ((nconf->nc_semantics == NC_TPI_COTS_ORD) ||
- (nconf->nc_semantics == NC_TPI_COTS)) {
- if (port == 0)
- break;
- if ((strcmp(nconf->nc_protofmly,
- NC_INET) == 0
-#ifdef NC_INET6
- /* CSTYLED */
- || strcmp(nconf->nc_protofmly,
- NC_INET6) == 0
-#endif
- /* CSTYLED */
- ) &&
- (strcmp(nconf->nc_proto, NC_TCP) == 0))
- break;
- }
- }
- }
- } /* while */
- if (nconf == NULL) {
- if (++nthtry <= MNT_PREF_LISTLEN) {
- endnetpath(nc);
- if ((nc = setnetpath()) == NULL)
- goto done;
- goto retry;
- } else
- goto done;
- } else {
- if ((nb = get_the_addr(hostname, prog, vers, nconf,
- port, tinfo, portmap)) == NULL) {
- /*
- * Continue the same search path in the
- * netconfig db until no more matched
- * nconf (nconf == NULL).
- */
- goto retry;
- }
-#ifdef AF_INET6
- if ((nb->len == 8) &&
- (strcmp(nconf->nc_protofmly, NC_INET6) == 0)) {
- /*
- * We have a mismatch in the netconfig retry
- */
- free(nb);
- goto retry;
- }
-#endif
- }
- }
-
- /*
- * Got nconf and nb. Now dup the netconfig structure (nconf)
- * and return it thru nconfp.
- */
- *nconfp = getnetconfigent(nconf->nc_netid);
- if (*nconfp == NULL) {
- syslog(LOG_ERR, "no memory\n");
- free(nb);
- nb = NULL;
- }
-done:
- if (nc)
- endnetpath(nc);
- return (nb);
-}
-
-
-/* return values as for nsc_check_release() */
-int
-rdc_check_release(char **reqd)
-{
- /* librdc.so must be built on the runtime OS release */
- return (nsc_check_release(BUILD_REV_STR, NULL, reqd));
-}
diff --git a/usr/src/lib/librdc/common/rdcconfig.c b/usr/src/lib/librdc/common/rdcconfig.c
deleted file mode 100644
index b8fc2ade37..0000000000
--- a/usr/src/lib/librdc/common/rdcconfig.c
+++ /dev/null
@@ -1,1318 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <errno.h>
-#include <strings.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <netdb.h>
-#include <sys/stream.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <ctype.h>
-#include <thread.h>
-#include <pthread.h>
-
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_u.h>
-#include <sys/unistat/spcs_s_impl.h>
-#include <sys/unistat/spcs_errors.h>
-
-#include <sys/nsctl/rdc_io.h>
-#include <sys/nsctl/rdc_ioctl.h>
-#include <sys/nsctl/rdc_prot.h>
-#include <sys/nsctl/librdc.h>
-#include <sys/nsctl/rdcrules.h>
-#include <sys/nsctl/rdcerr.h>
-#include <sys/nsctl/cfg.h>
-
-#include <sys/unistat/spcs_dtrinkets.h>
-#include <sys/unistat/spcs_etrinkets.h>
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netinet/tcp.h>
-#include <rpc/rpc_com.h>
-#include <rpc/rpc.h>
-
-struct netbuf svaddr, *svp;
-struct netconfig nconf, *conf;
-struct knetconfig knconf;
-
-/*
- * libdscfg type stuff here
- */
-extern int sv_enable(CFGFILE *cfg, rdcconfig_t *rdc);
-extern int add_to_rdc_cfg(rdcconfig_t *rdcs);
-extern int remove_from_rdc_cfg(rdcconfig_t *rdcs);
-extern int replace_cfgfield(rdcconfig_t *rdcs, char *field, char *value);
-extern int reverse_in_cfg(rdcconfig_t *rdcs);
-
-rdcconfig_t *
-rdc_dup_config(rdcconfig_t *orig)
-{
- rdcconfig_t *rc;
-
- rc = (rdcconfig_t *)calloc(1, sizeof (*rc));
- if (!rc) {
- rdc_set_error(NULL, RDC_OS, RDC_FATAL, NULL);
- return (NULL);
- }
-
- *rc = *orig;
- rc->next = NULL; /* don't want to hook into wrong chaing */
- return (rc);
-}
-
-/*
- * takes in a chain of rdcconfig_t's and a chain
- * of rdc_rc_t's, checks for success in the rdc_rc_t,
- * then adds the corresponding rdcconfig_t to the return
- * chain.
- */
-rdcconfig_t *
-chain_successful(rdcconfig_t *rdcs, rdc_rc_t *rcs)
-{
- rdc_rc_t *rcp;
- rdcconfig_t *rdcp;
- rdcconfig_t *ret = NULL;
- rdcconfig_t *retp = NULL;
-
- rcp = rcs;
- rdcp = rdcs;
-
- while (rcp) {
- if (rcp->rc == 0) {
- if ((ret == NULL) && (rdcp->persist)) {
- retp = ret = rdc_dup_config(rdcp);
-
- } else if ((ret) && (rdcp->persist)) {
- retp->next = rdc_dup_config(rdcp);
- retp = retp->next;
- }
- }
- rcp = rcp->next;
- rdcp = rdcp->next;
- }
- return (ret);
-
-}
-
-rdc_set_t
-config2set(rdcconfig_t *rdc)
-{
- rdc_set_t urdc;
-
- bzero(&urdc, sizeof (rdc_set_t));
- strncpy(urdc.primary.intf, rdc->phost, MAX_RDC_HOST_SIZE);
- strncpy(urdc.primary.file, rdc->pfile, NSC_MAXPATH);
- strncpy(urdc.primary.bitmap, rdc->pbmp, NSC_MAXPATH);
- strncpy(urdc.secondary.intf, rdc->shost, MAX_RDC_HOST_SIZE);
- strncpy(urdc.secondary.file, rdc->sfile, NSC_MAXPATH);
- strncpy(urdc.secondary.bitmap, rdc->sbmp, NSC_MAXPATH);
- strncpy(urdc.group_name, rdc->group, NSC_MAXPATH);
-
- return (urdc);
-}
-
-rdc_rc_t *
-new_rc()
-{
- rdc_rc_t *rc;
-
- rc = (rdc_rc_t *)calloc(1, sizeof (*rc));
- if (rc == NULL) {
- rdc_set_error(NULL, RDC_OS, RDC_FATAL, NULL);
- return (NULL);
- }
- return (rc);
-}
-
-rdc_rc_t
-rdc_config(rdc_config_t *rdccfg)
-{
- rdc_rc_t rc;
- rdc_set_t *set;
- spcs_s_info_t ustatus;
-
- bzero(&rc, sizeof (rc));
- ustatus = spcs_s_ucreate();
-
- if (self_check(rdccfg->rdc_set->primary.intf)) {
- rdccfg->options |= RDC_OPT_PRIMARY;
- /* this needs changin if we do campus */
- rdccfg->rdc_set->direct_file[0] = 0;
- } else {
- rdccfg->options |= RDC_OPT_SECONDARY;
- }
-
- /* set up return stuff.. */
- set = &rdccfg->rdc_set[0];
- strncpy(rc.set.phost, set->primary.intf, MAX_RDC_HOST_SIZE);
- strncpy(rc.set.pfile, set->primary.file, NSC_MAXPATH);
- strncpy(rc.set.shost, set->secondary.intf, MAX_RDC_HOST_SIZE);
- strncpy(rc.set.sfile, set->secondary.file, NSC_MAXPATH);
-
- rc.rc = RDC_IOCTL(RDC_CONFIG, rdccfg, NULL, 0, 0, 0, ustatus);
-
- if (rc.rc < 0) {
- rdc_set_error(&ustatus, RDC_SPCS, 0, 0);
- strncpy(rc.msg, rdc_error(NULL), RDC_ERR_SIZE);
- }
-
- return (rc);
-}
-
-void *
-rdc_mtconfig(void *rdc)
-{
- rdc_rc_t *rc[1];
- rdc_set_t *set;
- spcs_s_info_t ustatus;
- rdc_config_t *rdccfg = (rdc_config_t *)rdc;
-
- ustatus = spcs_s_ucreate();
-
- if (self_check(rdccfg->rdc_set->primary.intf)) {
- rdccfg->options |= RDC_OPT_PRIMARY;
- /* this needs changin if we do campus */
- rdccfg->rdc_set->direct_file[0] = 0;
- } else {
- rdccfg->options |= RDC_OPT_SECONDARY;
- }
-
- set = &rdccfg->rdc_set[0];
- *rc = new_rc();
-
- strncpy(rc[0]->set.phost, set->primary.intf, MAX_RDC_HOST_SIZE);
- strncpy(rc[0]->set.pfile, set->primary.file, NSC_MAXPATH);
- strncpy(rc[0]->set.pbmp, set->primary.bitmap, NSC_MAXPATH);
- strncpy(rc[0]->set.shost, set->secondary.intf, MAX_RDC_HOST_SIZE);
- strncpy(rc[0]->set.sfile, set->secondary.file, NSC_MAXPATH);
- strncpy(rc[0]->set.sbmp, set->secondary.bitmap, NSC_MAXPATH);
-
- rc[0]->rc = RDC_IOCTL(RDC_CONFIG, rdccfg, NULL, 0, 0, 0, ustatus);
-
- if (rc[0]->rc < 0) {
- rdc_set_error(&ustatus, RDC_SPCS, 0, 0);
- strncpy(rc[0]->msg, rdc_error(NULL), RDC_ERR_SIZE);
- }
-
- sleep(1); /* give thr_join a chance to be called */
- free(rdccfg);
- thr_exit((void **) *rc);
- return (NULL);
-}
-int
-populate_addrs(rdc_set_t *urdc, int isenable)
-{
- struct t_info tinfo;
- struct hostent *hp;
- char toname[MAX_RDC_HOST_SIZE];
- char fromname[MAX_RDC_HOST_SIZE];
-
- strncpy(fromname, urdc->primary.intf, MAX_RDC_HOST_SIZE);
- strncpy(toname, urdc->secondary.intf, MAX_RDC_HOST_SIZE);
-
- if ((fromname[0] == '\0') || (fromname[0] == '\0')) {
- rdc_set_error(NULL, RDC_INTERNAL, RDC_FATAL,
- "NULL hostname recieved");
- return (-1);
- }
-
- hp = gethost_byname(fromname);
- strncpy(fromname, hp->h_name, MAX_RDC_HOST_SIZE);
- hp = gethost_byname(toname);
- strncpy(toname, hp->h_name, MAX_RDC_HOST_SIZE);
-
- if (self_check(fromname) && self_check(toname)) {
- rdc_set_error(NULL, RDC_INTERNAL, RDC_FATAL, "");
- }
-
- if (isenable) {
- svp = get_addr(toname, RDC_PROGRAM, RDC_VERS_MIN,
- &conf, NULL, "rdc", &tinfo, 0);
- if (svp == NULL)
- return (-1);
- svaddr = *svp;
- } else {
- bzero(&svaddr, sizeof (svaddr));
- }
-
- urdc->secondary.addr.len = svaddr.len;
- urdc->secondary.addr.maxlen = svaddr.maxlen;
- urdc->secondary.addr.buf = (void*)svaddr.buf;
-
- if (isenable) {
- svp = get_addr(fromname, RDC_PROGRAM, RDC_VERS_MIN,
- &conf, NULL, "rdc", &tinfo, 0);
- if (svp == NULL)
- return (-1);
- svaddr = *svp;
- } else {
- bzero(&svaddr, sizeof (svaddr));
- }
-
- urdc->primary.addr.len = svaddr.len;
- urdc->primary.addr.maxlen = svaddr.maxlen;
- urdc->primary.addr.buf = (void*)svaddr.buf;
-
- if (isenable) {
- convert_nconf_to_knconf(conf, &knconf);
- urdc->netconfig = &knconf;
- } else {
- urdc->netconfig = NULL;
- }
- urdc->syshostid = (int32_t)gethostid();
-
- return (1);
-
-}
-void
-rdc_free_config(rdcconfig_t *rdc, int all)
-{
- rdcconfig_t *rdcp;
- rdcconfig_t *rdcq;
-
- rdcp = rdc;
- if (all == RDC_FREEONE) {
- free(rdcp);
- } else while (rdcp) {
- rdcq = rdcp->next;
- free(rdcp);
- rdcp = rdcq;
- }
- rdc = NULL;
-}
-
-void
-rdc_free_rclist(rdc_rc_t *rc)
-{
- rdc_rc_t *rcp, *rcq;
-
- rcp = rc;
- while (rcp) {
- rcq = rcp->next;
- free(rcp);
- rcp = rcq;
- }
-
-}
-/*ARGSUSED*/
-rdcconfig_t *
-rdc_alloc_config(const char *phost, const char *pfile,
- const char *pbmp, const char *shost, const char *sfile, const char *sbmp,
- const char *mode, const char *group, const char *ctag, const char *options,
- int persist)
-{
- rdcconfig_t *rc;
-
- rc = (rdcconfig_t *)calloc(1, sizeof (*rc));
- if (!rc) {
- rdc_set_error(NULL, RDC_OS, RDC_FATAL, NULL);
- return (NULL);
- }
- if (phost)
- strncpy(rc->phost, phost, NSC_MAXPATH);
- if (pfile)
- strncpy(rc->pfile, pfile, NSC_MAXPATH);
- if (pbmp)
- strncpy(rc->pbmp, pbmp, NSC_MAXPATH);
- if (shost)
- strncpy(rc->shost, shost, NSC_MAXPATH);
- if (sfile)
- strncpy(rc->sfile, sfile, NSC_MAXPATH);
- if (sbmp)
- strncpy(rc->sbmp, sbmp, NSC_MAXPATH);
-
- strncpy(rc->direct, "ip", 2);
-
- if (mode)
- strncpy(rc->mode, mode, NSC_MAXPATH);
- if (ctag)
- strncpy(rc->ctag, ctag, NSC_MAXPATH);
- if (options)
- strncpy(rc->options, options, NSC_MAXPATH);
-
- rc->persist = persist;
- rc->next = NULL;
-
- return (rc);
-
-}
-
-void
-populate_rc(rdc_rc_t *rcp, rdcconfig_t *rdcp)
-{
- rcp->rc = -1;
- strncpy(rcp->msg, rdc_error(NULL), RDC_ERR_SIZE);
- strncpy(rcp->set.phost, rdcp->phost, NSC_MAXPATH);
- strncpy(rcp->set.pfile, rdcp->pfile, NSC_MAXPATH);
- strncpy(rcp->set.shost, rdcp->shost, NSC_MAXPATH);
- strncpy(rcp->set.sfile, rdcp->sfile, NSC_MAXPATH);
-}
-
-/*
- * rdc_enable
- * return values
- * NULL on error
- * pointer to rdc_rc_t list of return values
- */
-rdc_rc_t *
-rdc_enable(rdcconfig_t *rdc)
-{
- rdc_config_t rdccfg;
- rdcconfig_t *rdcp = NULL;
- rdcconfig_t *cfg_rdcs = NULL;
- rdc_rc_t *rc = NULL;
- rdc_rc_t *rcp = NULL;
-
- rdcp = rdc;
- rc = new_rc();
- if (!rc) { /* error already set */
- return (NULL);
- }
- rcp = rc;
- while (rdcp) {
- if (!rdcp->mode) {
- rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
- RDC_EINVAL);
- return (NULL);
- }
- bzero(&rdccfg, sizeof (rdc_config_t));
- rdccfg.rdc_set[0] = config2set(rdcp);
- rdccfg.command = RDC_CMD_ENABLE;
- rdccfg.options = RDC_OPT_SETBMP;
- if (strncmp(rdcp->mode, "sync", NSC_MAXPATH) == 0) {
- rdccfg.options |= RDC_OPT_SYNC;
- } else if (strncmp(rdc->mode, "async", NSC_MAXPATH) == 0) {
- rdccfg.options |= RDC_OPT_ASYNC;
- } else {
- rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
- RDC_EINVAL);
- return (NULL);
- }
-
- populate_addrs(&rdccfg.rdc_set[0], 1);
-
- if (can_enable(rdcp)) {
- /* do the operation */
- *rcp = rdc_config(&rdccfg);
-
- } else { /* set up what rdc_config would've set up */
-
- populate_rc(rcp, rdcp);
-
- }
- if ((rcp->rc == 0) && (!rdcp->persist)) {
- /*
- * if we are not persisting, do this now,
- * otherwise we will do it when
- * we have a lock on the cfg in add_to_rdc_cfg
- */
- sv_enable(NULL, rdcp);
- }
-
- rdcp = rdcp->next;
- if (!rdcp)
- break;
-
- rcp->next = new_rc();
- rcp = rcp->next;
- if (!rcp) {
- /* dont free here, return what you have */
- break;
- }
- }
-
- /*
- * travel the rc chain and rdc chain checking results,
- * building a new chain, and updating dscfg
- */
- rcp = rc;
- rdcp = rdc;
-
- cfg_rdcs = chain_successful(rdcp, rcp);
-
- if (add_to_rdc_cfg(cfg_rdcs) < 0) {
- /* XXX should disable or something here */
- return (rc);
- }
- rdc_free_config(cfg_rdcs, RDC_FREEALL);
- return (rc);
-
-}
-
-rdc_rc_t *
-rdc_enable_clrbmp(rdcconfig_t *rdc)
-{
- rdc_config_t rdccfg;
- rdcconfig_t *rdcp = NULL;
- rdcconfig_t *cfg_rdcs = NULL;
- rdc_rc_t *rc = NULL;
- rdc_rc_t *rcp = NULL;
-
- rdcp = rdc;
- rc = (rdc_rc_t *)calloc(1, sizeof (rdc_rc_t));
- if (!rc) {
- rdc_set_error(NULL, RDC_OS, RDC_FATAL, NULL);
- return (NULL);
- }
- rcp = rc;
- while (rdcp) {
- if (!rdcp->mode) {
- rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
- RDC_EINVAL);
- return (NULL);
- }
- bzero(&rdccfg, sizeof (rdc_config_t));
- rdccfg.rdc_set[0] = config2set(rdcp);
- rdccfg.command = RDC_CMD_ENABLE;
- rdccfg.options = RDC_OPT_CLRBMP;
- if (strncmp(rdcp->mode, "sync", NSC_MAXPATH) == 0) {
- rdccfg.options |= RDC_OPT_SYNC;
- } else if (strncmp(rdc->mode, "async", NSC_MAXPATH) == 0) {
- rdccfg.options |= RDC_OPT_ASYNC;
- } else {
- rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
- RDC_EINVAL);
- return (NULL);
- }
-
- populate_addrs(&rdccfg.rdc_set[0], 1);
-
- if (can_enable(rdcp)) {
- /* do the operation */
- *rcp = rdc_config(&rdccfg);
-
- } else { /* set up what rdc_config would've set up */
-
- populate_rc(rcp, rdcp);
-
- }
- rdcp = rdcp->next;
- if (!rdcp)
- break;
-
- rcp->next = (rdc_rc_t *)calloc(1, sizeof (rdc_rc_t));
- rcp = rcp->next;
- if (!rcp)
- break;
- }
-
- /*
- * travel the rc chain and rdc chain checking results,
- * building a new chain, and updating dscfg
- */
- rcp = rc;
- rdcp = rdc;
-
- cfg_rdcs = chain_successful(rdcp, rcp);
-
- if (add_to_rdc_cfg(cfg_rdcs) < 0) {
- /* XXX should disable or something here */
- return (rc);
- }
- rdc_free_config(cfg_rdcs, RDC_FREEALL);
-
- return (rc);
-
-}
-
-rdc_rc_t *
-rdc_disable(rdcconfig_t *rdc)
-{
- rdc_config_t rdccfg;
- rdcconfig_t *rdcp = NULL;
- rdcconfig_t *cfg_rdcs = NULL;
- rdc_rc_t *rc = NULL;
- rdc_rc_t *rcp = NULL;
-
- rdcp = rdc;
- rc = new_rc();
- if (!rc) {
- return (NULL);
- }
- rcp = rc;
-
- while (rdcp) {
-
- bzero(&rdccfg, sizeof (rdc_config_t));
- rdccfg.rdc_set[0] = config2set(rdcp);
- rdccfg.command = RDC_CMD_DISABLE;
- populate_addrs(&rdccfg.rdc_set[0], 0);
-
- *rcp = rdc_config(&rdccfg);
-
- rdcp = rdcp->next;
- if (!rdcp)
- break;
-
- rcp->next = new_rc();
- rcp = rcp->next;
- if (!rcp)
- return (rc);
-
- }
- rcp = rc;
- rdcp = rdc;
-
- cfg_rdcs = chain_successful(rdcp, rcp);
-
- remove_from_rdc_cfg(cfg_rdcs);
-
- rdc_free_config(cfg_rdcs, RDC_FREEALL);
-
- return (rc);
-}
-
-rdc_rc_t *
-rdc_log(rdcconfig_t *rdc)
-{
- rdc_config_t rdccfg;
- rdcconfig_t *rdcp = NULL;
- rdc_rc_t *rc = NULL;
- rdc_rc_t *rcp = NULL;
-
- rdcp = rdc;
- rc = new_rc();
- if (!rc) {
- return (NULL);
- }
- rcp = rc;
-
- while (rdcp) {
- bzero(&rdccfg, sizeof (rdc_config_t));
- rdccfg.rdc_set[0] = config2set(rdcp);
- rdccfg.command = RDC_CMD_LOG;
- populate_addrs(&rdccfg.rdc_set[0], 0);
-
- *rcp = rdc_config(&rdccfg);
-
- rdcp = rdcp->next;
- if (!rdcp)
- break;
-
- rcp->next = new_rc();
- rcp = rcp->next;
- if (!rcp)
- break;
- }
- return (rc);
-}
-
-rdc_rc_t *
-rdc_usync(rdcconfig_t *rdc)
-{
- rdc_config_t *rdccfg;
- rdcconfig_t *rdcp = NULL;
- rdc_rc_t *rc = NULL;
- rdc_rc_t *rcp = NULL;
- rdc_rc_t *tmprc;
-
- rdcp = rdc;
-
- while (rdcp) {
- /* freed in rdc_mtconfig */
- rdccfg = (rdc_config_t *)calloc(1, sizeof (rdc_config_t));
- rdccfg->rdc_set[0] = config2set(rdcp);
- rdccfg->command = RDC_CMD_COPY;
- rdccfg->options = RDC_OPT_UPDATE|RDC_OPT_FORWARD;
- populate_addrs(&rdccfg->rdc_set[0], 0);
- (void) thr_create(NULL, 0, rdc_mtconfig,
- (void **) rdccfg, THR_BOUND, NULL);
- rdcp = rdcp->next;
- if (!rdcp)
- break;
-
- }
-
- /*
- * collect status here from thr_join-status,
- * and add to rdc_rc_t chain ?
- * this will block, but caller could always thread too
- */
- while (thr_join(NULL, NULL, (void**) &tmprc) == 0) {
- if (rc == NULL) {
- rcp = rc = (rdc_rc_t *)tmprc;
- } else {
- rcp->next = (rdc_rc_t *)tmprc;
- rcp = rcp->next;
- }
- }
-
- return (rc);
-}
-
-rdc_rc_t *
-rdc_fsync(rdcconfig_t *rdc)
-{
- rdc_config_t *rdccfg;
- rdcconfig_t *rdcp = NULL;
- rdc_rc_t *rc = NULL;
- rdc_rc_t *rcp = NULL;
- rdc_rc_t *tmprc = NULL;
-
- rdcp = rdc;
- rc = new_rc();
- if (!rc) {
- return (NULL);
- }
- rcp = rc;
-
- while (rdcp) {
- /* freed in rdc_mtconfig */
- rdccfg = (rdc_config_t *)calloc(1, sizeof (rdc_config_t));
- rdccfg->rdc_set[0] = config2set(rdcp);
- rdccfg->command = RDC_CMD_COPY;
- rdccfg->options = RDC_OPT_FULL|RDC_OPT_FORWARD;
- populate_addrs(&rdccfg->rdc_set[0], 0);
- (void) thr_create(NULL, 0, rdc_mtconfig,
- (void **) rdccfg, THR_BOUND, NULL);
- rdcp = rdcp->next;
- if (!rdcp)
- break;
-
- }
-
- /*
- * collect status here from thr_join-status,
- * and add to rdc_rc_t chain ?
- * this will block, but caller could always thread too
- */
- while (thr_join(NULL, NULL, (void**) &tmprc) == 0) {
- if (rc == NULL) {
- rcp = rc = (rdc_rc_t *)tmprc;
- } else {
- rcp->next = (rdc_rc_t *)tmprc;
- rcp = rcp->next;
- }
- }
-
- return (rc);
-}
-
-rdc_rc_t *
-rdc_rsync(rdcconfig_t *rdc)
-{
- rdc_config_t *rdccfg;
- rdcconfig_t *rdcp = NULL;
- rdc_rc_t *rc = NULL;
- rdc_rc_t *rcp = NULL;
- rdc_rc_t *tmprc = NULL;
-
- rdcp = rdc;
- rc = new_rc();
- if (!rc) {
- return (NULL);
- }
- rcp = rc;
-
- while (rdcp) {
- tmprc = cant_rsync(rdcp);
- if (tmprc != NULL) {
- if (rc == NULL) {
- rcp = rc = tmprc;
- } else {
- rcp->next = tmprc;
- rcp = rcp->next;
- }
- goto next;
- }
-
- /* freed in rdc_mtconfig */
- rdccfg = (rdc_config_t *)calloc(1, sizeof (rdc_config_t));
- rdccfg->rdc_set[0] = config2set(rdcp);
- rdccfg->command = RDC_CMD_COPY;
- rdccfg->options = RDC_OPT_REVERSE|RDC_OPT_FULL;
- populate_addrs(&rdccfg->rdc_set[0], 0);
- (void) thr_create(NULL, 0, rdc_mtconfig,
- (void **) rdccfg, THR_BOUND, NULL);
-next:
- rdcp = rdcp->next;
- if (!rdcp)
- break;
- }
-
- /*
- * collect status here from thr_join-status,
- * and add to rdc_rc_t chain ?
- * this will block, but caller could always thread too
- */
- while (thr_join(NULL, NULL, (void**) &tmprc) == 0) {
- if (rc == NULL) {
- rcp = rc = (rdc_rc_t *)tmprc;
- } else {
- rcp->next = (rdc_rc_t *)tmprc;
- rcp = rcp->next;
- }
- }
-
- return (rc);
-}
-
-rdc_rc_t *
-rdc_ursync(rdcconfig_t *rdc)
-{
- rdc_config_t *rdccfg;
- rdcconfig_t *rdcp = NULL;
- rdc_rc_t *rc = NULL;
- rdc_rc_t *rcp = NULL;
- rdc_rc_t *tmprc = NULL;
-
- rdcp = rdc;
-
- while (rdcp) {
- tmprc = cant_rsync(rdcp);
- if (tmprc != NULL) {
- if (rc == NULL) {
- rcp = rc = tmprc;
- } else {
- rcp->next = tmprc;
- rcp = rcp->next;
- }
- goto next;
- }
-
- /* freed in rdc_mtconfig */
- rdccfg = (rdc_config_t *)calloc(1, sizeof (rdc_config_t));
- rdccfg->rdc_set[0] = config2set(rdcp);
- rdccfg->command = RDC_CMD_COPY;
- rdccfg->options = RDC_OPT_REVERSE | RDC_OPT_UPDATE;
- populate_addrs(&rdccfg->rdc_set[0], 0);
- (void) thr_create(NULL, 0, rdc_mtconfig,
- (void **) rdccfg, THR_BOUND, NULL);
-next:
- rdcp = rdcp->next;
- if (!rdcp)
- break;
-
- }
-
- /*
- * collect status here from thr_join-status,
- * and add to rdc_rc_t chain ?
- * this will block, but caller could always thread too
- */
- while (thr_join(NULL, NULL, (void**) &tmprc) == 0) {
- if (rc == NULL) {
- rcp = rc = (rdc_rc_t *)tmprc;
- } else {
- rcp->next = (rdc_rc_t *)tmprc;
- rcp = rcp->next;
- }
- }
-
- return (rc);
-}
-
-rdc_rc_t *
-rdc_wait(rdcconfig_t *rdc)
-{
- rdc_config_t rdccfg;
- rdcconfig_t *rdcp = NULL;
- rdc_rc_t *rc = NULL;
- rdc_rc_t *rcp = NULL;
-
- rdcp = rdc;
- rc = new_rc();
- if (!rc) {
- return (NULL);
- }
- rcp = rc;
-
- while (rdcp) {
- bzero(&rdccfg, sizeof (rdc_config_t));
- rdccfg.rdc_set[0] = config2set(rdcp);
- rdccfg.command = RDC_CMD_WAIT;
- populate_addrs(&rdccfg.rdc_set[0], 0);
-
- *rcp = rdc_config(&rdccfg);
-
- rdcp = rdcp->next;
- if (!rdcp)
- break;
-
- rcp->next = new_rc();
- rcp = rcp->next;
- if (!rcp)
- break;
- }
- return (rc);
-}
-
-rdc_rc_t *
-rdc_set_autosync(rdcconfig_t *rdc, int autosync)
-{
- rdc_config_t rdccfg;
- rdcconfig_t *rdcp = NULL;
- rdc_rc_t *rc = NULL;
- rdc_rc_t *rcp = NULL;
-
- rdcp = rdc;
- rc = new_rc();
- if (!rc) {
- return (NULL);
- }
- rcp = rc;
-
- while (rdcp) {
- bzero(&rdccfg, sizeof (rdc_config_t));
- rdccfg.rdc_set[0] = config2set(rdcp);
- rdccfg.command = RDC_CMD_TUNABLE;
- rdccfg.rdc_set[0].autosync = autosync;
- rdccfg.rdc_set[0].maxqitems = -1;
- rdccfg.rdc_set[0].maxqfbas = -1;
- populate_addrs(&rdccfg.rdc_set[0], 0);
-
- *rcp = rdc_config(&rdccfg);
-
- rdcp = rdcp->next;
- if (!rdcp)
- break;
-
- rcp->next = new_rc();
- rcp = rcp->next;
- if (!rcp)
- break;
- }
- return (rc);
-}
-
-rdc_rc_t *
-rdc_set_maxqfbas(rdcconfig_t *rdc, int maxqfbas)
-{
- rdc_config_t rdccfg;
- rdcconfig_t *rdcp = NULL;
- rdc_rc_t *rc = NULL;
- rdc_rc_t *rcp = NULL;
-
- rdcp = rdc;
- rc = new_rc();
- if (!rc) {
- return (NULL);
- }
- rcp = rc;
-
- while (rdcp) {
- bzero(&rdccfg, sizeof (rdc_config_t));
- rdccfg.rdc_set[0] = config2set(rdcp);
- rdccfg.command = RDC_CMD_TUNABLE;
- rdccfg.rdc_set[0].autosync = -1;
- rdccfg.rdc_set[0].maxqitems = -1;
- rdccfg.rdc_set[0].maxqfbas = maxqfbas;
- populate_addrs(&rdccfg.rdc_set[0], 0);
-
- *rcp = rdc_config(&rdccfg);
-
- rdcp = rdcp->next;
- if (!rdcp)
- break;
-
- rcp->next = new_rc();
- rcp = rcp->next;
- if (!rcp)
- break;
- }
- return (rc);
-}
-
-rdc_rc_t *
-rdc_set_maxqitems(rdcconfig_t *rdc, int maxqitems)
-{
- rdc_config_t rdccfg;
- rdcconfig_t *rdcp = NULL;
- rdc_rc_t *rc = NULL;
- rdc_rc_t *rcp = NULL;
-
- rdcp = rdc;
- rc = new_rc();
-
- if (!rc) {
- return (NULL);
- }
- rcp = rc;
-
- while (rdcp) {
- bzero(&rdccfg, sizeof (rdc_config_t));
- rdccfg.rdc_set[0] = config2set(rdc);
- rdccfg.command = RDC_CMD_TUNABLE;
- rdccfg.rdc_set[0].autosync = -1;
- rdccfg.rdc_set[0].maxqitems = maxqitems;
- rdccfg.rdc_set[0].maxqfbas = -1;
- populate_addrs(&rdccfg.rdc_set[0], 0);
-
- *rcp = rdc_config(&rdccfg);
-
- rdcp = rdcp->next;
- if (!rdcp)
- break;
-
- rcp->next = new_rc();
- rcp = rcp->next;
- if (!rcp)
- break;
- }
- return (rc);
-}
-
-rdc_set_t
-rdc_status(rdcconfig_t *rdc)
-{
- rdc_config_t rdccfg;
-
- bzero(&rdccfg, sizeof (rdc_config_t));
- rdccfg.rdc_set[0] = config2set(rdc);
- rdccfg.command = RDC_CMD_STATUS;
- populate_addrs(&rdccfg.rdc_set[0], 0);
- rdc_config(&rdccfg);
-
- return (rdccfg.rdc_set[0]);
-}
-
-int
-rdc_get_autosync(rdcconfig_t *rdc)
-{
- rdc_set_t rdcset;
-
- rdcset = rdc_status(rdc);
- return (rdcset.autosync);
-}
-
-int
-rdc_get_maxqfbas(rdcconfig_t *rdc)
-{
- rdc_set_t rdcset;
-
- rdcset = rdc_status(rdc);
- return (rdcset.maxqfbas);
-
-}
-
-int
-rdc_get_maxqitems(rdcconfig_t *rdc)
-{
- rdc_set_t rdcset;
-
- rdcset = rdc_status(rdc);
- return (rdcset.maxqitems);
-
-}
-
-int
-set_mode(rdcconfig_t *rdc)
-{
- if (strcmp(rdc->mode, "async") == 0)
- return (RDC_OPT_ASYNC);
- else
- return (RDC_OPT_SYNC);
-}
-
-/*
- * reconfig bitmaps are single set only ops
- * for obvious reasons
- */
-rdc_rc_t *
-rdc_reconfig_pbmp(rdcconfig_t *rdc, char *pbmp)
-{
- rdc_config_t rdccfg;
- rdc_rc_t *rc;
-
- rc = new_rc();
- if ((!rc) || (!pbmp))
- return (NULL);
-
- bzero(&rdccfg, sizeof (rdc_config_t));
- rdccfg.rdc_set[0] = config2set(rdc);
- strncpy(rdccfg.rdc_set[0].primary.bitmap, pbmp, NSC_MAXPATH);
- rdccfg.command = RDC_CMD_RECONFIG;
- rdccfg.options |= set_mode(rdc);
- populate_addrs(&rdccfg.rdc_set[0], 0);
-
- if (can_reconfig_pbmp(rdc, pbmp))
- *rc = rdc_config(&rdccfg);
- else
- populate_rc(rc, rdc);
-
- if ((rc->rc == 0) && (rdc->persist))
- if (replace_cfgfield(rdc, "pbitmap", pbmp) < 0) {
- rc->rc = -1;
- strncpy(rc->msg, rdc_error(NULL), RDC_ERR_SIZE);
- }
- return (rc);
-}
-
-rdc_rc_t *
-rdc_reconfig_sbmp(rdcconfig_t *rdc, char *sbmp)
-{
- rdc_config_t rdccfg;
- rdc_rc_t *rc;
-
- rc = new_rc();
- if (!rc)
- return (NULL);
-
- bzero(&rdccfg, sizeof (rdc_config_t));
- rdccfg.rdc_set[0] = config2set(rdc);
- strncpy(rdccfg.rdc_set[0].secondary.bitmap, sbmp, NSC_MAXPATH);
- rdccfg.command = RDC_CMD_RECONFIG;
- rdccfg.options |= set_mode(rdc);
- populate_addrs(&rdccfg.rdc_set[0], 0);
-
- if (can_reconfig_sbmp(rdc, sbmp))
- *rc = rdc_config(&rdccfg);
- else
- populate_rc(rc, rdc);
-
- if ((rc->rc == 0) && (rdc->persist))
- replace_cfgfield(rdc, "sbitmap", sbmp);
-
- return (rc);
-}
-
-rdc_rc_t *
-rdc_reconfig_group(rdcconfig_t *rdc, char *group)
-{
- rdc_config_t rdccfg;
- rdcconfig_t *rdcp = NULL;
- rdcconfig_t *cfg_rdcs = NULL;
- rdc_rc_t *rc = NULL;
- rdc_rc_t *rcp = NULL;
-
- rdcp = rdc;
- rc = new_rc();
- if (!rc) {
- return (NULL);
- }
- rcp = rc;
-
- while (rdcp) {
- bzero(&rdccfg, sizeof (rdc_config_t));
- /* just in case */
- strncpy(rdcp->group, group, NSC_MAXPATH);
- rdccfg.rdc_set[0] = config2set(rdcp);
- rdccfg.command = RDC_CMD_RECONFIG;
- rdccfg.options |= set_mode(rdcp);
- populate_addrs(&rdccfg.rdc_set[0], 0);
-
- /* reconfig group rules enforced in kernel */
- *rcp = rdc_config(&rdccfg);
-
- rdcp = rdcp->next;
- if (!rdcp)
- break;
-
- rcp->next = new_rc();
- rcp = rcp->next;
- if (!rcp)
- break;
- }
- rcp = rc;
- rdcp = rdc;
- cfg_rdcs = chain_successful(rdcp, rcp);
- replace_cfgfield(cfg_rdcs, "group", group);
- rdc_free_config(cfg_rdcs, RDC_FREEALL);
-
- return (rc);
-}
-/*ARGSUSED*/
-rdc_rc_t *
-rdc_reconfig_ctag(rdcconfig_t *rdc, char *ctag)
-{
- return (NULL);
-}
-
-rdc_rc_t *
-rdc_set_sync(rdcconfig_t *rdc)
-{
- rdc_config_t rdccfg;
- rdcconfig_t *rdcp = NULL;
- rdcconfig_t *cfg_rdcs = NULL;
- rdc_rc_t *rc = NULL;
- rdc_rc_t *rcp = NULL;
-
- rdcp = rdc;
- rc = new_rc();
- if (!rc) {
- return (NULL);
- }
- rcp = rc;
-
- while (rdcp) {
- bzero(&rdccfg, sizeof (rdc_config_t));
- rdccfg.rdc_set[0] = config2set(rdc);
- rdccfg.command = RDC_CMD_RECONFIG;
- rdccfg.options |= RDC_OPT_SYNC;
- populate_addrs(&rdccfg.rdc_set[0], 0);
-
- *rcp = rdc_config(&rdccfg);
-
- rdcp = rdcp->next;
- if (!rdcp)
- break;
-
- rcp->next = new_rc();
- rcp = rcp->next;
- if (!rcp)
- break;
- }
-
- rcp = rc;
- rdcp = rdc;
- cfg_rdcs = chain_successful(rdcp, rcp);
- replace_cfgfield(cfg_rdcs, "mode", "sync");
- rdc_free_config(cfg_rdcs, RDC_FREEALL);
-
- return (rc);
-}
-
-rdc_rc_t *
-rdc_set_async(rdcconfig_t *rdc)
-{
- rdc_config_t rdccfg;
- rdcconfig_t *rdcp = NULL;
- rdcconfig_t *cfg_rdcs = NULL;
- rdc_rc_t *rc = NULL;
- rdc_rc_t *rcp = NULL;
-
- rdcp = rdc;
- rc = new_rc();
- if (!rc) {
- return (NULL);
- }
- rcp = rc;
-
- while (rdcp) {
- bzero(&rdccfg, sizeof (rdc_config_t));
- rdccfg.rdc_set[0] = config2set(rdcp);
- rdccfg.command = RDC_CMD_RECONFIG;
- rdccfg.options |= RDC_OPT_ASYNC;
- populate_addrs(&rdccfg.rdc_set[0], 0);
-
- *rcp = rdc_config(&rdccfg);
-
- rdcp = rdcp->next;
- if (!rdcp)
- break;
-
- rcp->next = new_rc();
- rcp = rcp->next;
- if (!rcp)
- break;
- }
- rcp = rc;
- rdcp = rdc;
- cfg_rdcs = chain_successful(rdcp, rcp);
- replace_cfgfield(cfg_rdcs, "mode", "async");
- rdc_free_config(cfg_rdcs, RDC_FREEALL);
-
- return (rc);
-}
-
-rdc_rc_t *
-rdc_health(rdcconfig_t *rdc)
-{
- rdc_config_t rdccfg;
- rdcconfig_t *rdcp = NULL;
- rdc_rc_t *rc = NULL;
- rdc_rc_t *rcp = NULL;
-
- rdcp = rdc;
- rc = new_rc();
- if (!rc) {
- return (NULL);
- }
- rcp = rc;
-
- while (rdcp) {
- bzero(&rdccfg, sizeof (rdc_config_t));
- rdccfg.rdc_set[0] = config2set(rdcp);
- rdccfg.command = RDC_CMD_HEALTH;
- populate_addrs(&rdccfg.rdc_set[0], 0);
-
- *rcp = rdc_config(&rdccfg);
-
- rdcp = rdcp->next;
- if (!rdcp)
- break;
-
- rcp->next = new_rc();
- rcp = rcp->next;
-
- if (!rcp)
- break;
-
- }
- return (rc);
-}
-
-rdc_rc_t *
-rdc_reverse_role(rdcconfig_t *rdc)
-{
- rdc_config_t rdccfg;
- rdcconfig_t *rdcp = NULL;
- rdcconfig_t *cfg_rdcs = NULL;
- rdc_rc_t *rc = NULL;
- rdc_rc_t *rcp = NULL;
-
- rdcp = rdc;
- rc = new_rc();
- if (!rc) {
- return (NULL);
- }
- rcp = rc;
-
- while (rdcp) {
- bzero(&rdccfg, sizeof (rdc_config_t));
- rdccfg.rdc_set[0] = config2set(rdcp);
- rdccfg.command = RDC_CMD_RECONFIG;
- rdccfg.options |= RDC_OPT_REVERSE_ROLE;
- rdccfg.options |= set_mode(rdcp);
- populate_addrs(&rdccfg.rdc_set[0], 0);
-
- *rcp = rdc_config(&rdccfg);
-
- rdcp = rdcp->next;
- if (!rdcp)
- break;
-
- rcp->next = new_rc();
- rcp = rcp->next;
- if (!rcp)
- break;
- }
- rcp = rc;
- rdcp = rdc;
- cfg_rdcs = chain_successful(rdcp, rcp);
- reverse_in_cfg(cfg_rdcs);
- rdc_free_config(cfg_rdcs, RDC_FREEALL);
-
- return (rc);
-}
diff --git a/usr/src/lib/librdc/common/rdcerr.c b/usr/src/lib/librdc/common/rdcerr.c
deleted file mode 100644
index 6328371ecd..0000000000
--- a/usr/src/lib/librdc/common/rdcerr.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <errno.h>
-#include <libintl.h>
-#include <locale.h>
-#include <stdlib.h>
-#include <stdarg.h>
-
-#include <sys/nsctl/rdcerr.h>
-#include <sys/nsctl/cfg.h>
-
-#include <sys/unistat/spcs_dtrinkets.h>
-#include <sys/unistat/spcs_etrinkets.h>
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_u.h>
-#include <sys/unistat/spcs_s_impl.h>
-#include <sys/unistat/spcs_errors.h>
-
-
-int rdc_severity;
-char *rdc_error_str;
-char err[RDC_ERR_SIZE];
-
-void
-rdc_set_error(spcs_s_info_t *ustatus, int context, int severity,
- char *errorstr, ...)
-{
- char msg[1024];
- va_list ap;
-
- bzero(err, RDC_ERR_SIZE);
- switch (context) {
- case RDC_INTERNAL:
- rdc_severity = severity;
- if (errorstr) {
- va_start(ap, errorstr);
- vsprintf(err, errorstr, ap);
- va_end(ap);
- }
- rdc_error_str = dgettext("librdc", err ? err : "");
- break;
-
- case RDC_OS:
- rdc_severity = severity ? severity : RDC_FATAL;
- rdc_error_str = strerror(errno);
- break;
-
- case RDC_SPCS:
- rdc_severity = severity ? severity : RDC_FATAL;
- rdc_error_str = spcs_s_string(*ustatus, msg);
- break;
-
- case RDC_DSCFG:
- rdc_error_str = cfg_error(&rdc_severity);
- break;
-
- default:
- break;
- }
-
- spcs_log("librdc", NULL, dgettext("librdc", "%s"),
- rdc_error_str ? rdc_error_str : "");
-
-}
-
-char *
-rdc_error(int *severity)
-{
- if (severity != NULL)
- *severity = rdc_severity;
- return (rdc_error_str ? rdc_error_str : "");
-}
diff --git a/usr/src/lib/librdc/common/rdcerr.h b/usr/src/lib/librdc/common/rdcerr.h
deleted file mode 100644
index f8c8b83423..0000000000
--- a/usr/src/lib/librdc/common/rdcerr.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _RDCERR_H
-#define _RDCERR_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <strings.h>
-#include <stdlib.h>
-
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_u.h>
-#include <sys/unistat/spcs_s_impl.h>
-#include <sys/unistat/spcs_errors.h>
-
-/* serious error? */
-#define RDC_FATAL 0x02
-#define RDC_NONFATAL 0x03
-
-/* types of errors */
-#define RDC_INTERNAL 0x01
-#define RDC_OS 0X02
-#define RDC_SPCS 0x04
-#define RDC_DSCFG 0x08
-
-/* errors */
-#define RDC_EINVAL "Invalid argument"
-
-#define RDC_NAME_DU_JOUR "Remote Mirror"
-
-#ifndef RDC_ERR_SIZE
-#define RDC_ERR_SIZE 256
-#endif
-
-
-void
-rdc_set_error(spcs_s_info_t *ustatus, int context, int severity,
-char *errorstr, ...);
-
-char *
-rdc_err(int *severity);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _RDCERR_H */
diff --git a/usr/src/lib/librdc/common/rdcpersist.c b/usr/src/lib/librdc/common/rdcpersist.c
deleted file mode 100644
index 703c8eef11..0000000000
--- a/usr/src/lib/librdc/common/rdcpersist.c
+++ /dev/null
@@ -1,716 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mkdev.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stropts.h>
-#include <stdio.h>
-#include <errno.h>
-#include <libintl.h>
-#include <locale.h>
-#include <stdlib.h>
-
-#include <sys/nsctl/rdcerr.h>
-#include <sys/nsctl/rdc_ioctl.h>
-#include <sys/nsctl/librdc.h>
-#include <sys/nsctl/cfg.h>
-#include <sys/nsctl/nsc_hash.h>
-#include <sys/nsctl/sv.h>
-
-#include <sys/unistat/spcs_dtrinkets.h>
-#include <sys/unistat/spcs_etrinkets.h>
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_u.h>
-#include <sys/unistat/spcs_s_impl.h>
-#include <sys/unistat/spcs_errors.h>
-
-typedef struct volcount_s {
- int count;
-} volcount_t;
-
-hash_node_t **volhash = NULL;
-
-char *
-config2buf(char *buf, rdcconfig_t *rdc)
-{
- snprintf(buf, CFG_MAX_BUF, "%s %s %s %s %s %s %s %s %s %s %s",
- rdc->phost, rdc->pfile, rdc->pbmp, rdc->shost, rdc->sfile,
- rdc->sbmp, rdc->direct, rdc->mode, rdc->group ? rdc->group : "",
- rdc->ctag ? rdc->ctag : "", rdc->options ? rdc->options : "");
- return (buf);
-
-}
-
-/*
- * SV type functions.
- */
-
-static void
-load_rdc_vols(CFGFILE *cfg)
-{
- int set;
- char key[ CFG_MAX_KEY ];
- char buf[ CFG_MAX_BUF ];
- char *vol, *bmp, *host1, *host2;
- volcount_t *volcount;
-
- if (volhash) {
- return;
- }
-
- cfg_rewind(cfg, CFG_SEC_CONF);
- volhash = nsc_create_hash();
- for (set = 1; /*CSTYLED*/; set++) {
- snprintf(key, CFG_MAX_KEY, "sndr.set%d", set);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF)) {
- break;
- }
-
- host1 = strtok(buf, " ");
- vol = strtok(NULL, " ");
- bmp = strtok(NULL, " ");
-
- if (!self_check(host1)) {
- /* next one had better be ours */
- host2 = strtok(NULL, " ");
- vol = strtok(NULL, " ");
- bmp = strtok(NULL, " ");
-
- if (!self_check(host2)) {
- continue;
- }
- }
-
- /* primary vol may be used more than once */
- volcount = (volcount_t *)nsc_lookup(volhash, vol);
- if (volcount) {
- volcount->count++;
- } else {
- volcount = (volcount_t *)malloc(sizeof (volcount_t));
- volcount->count = 1;
- nsc_insert_node(volhash, volcount, vol);
- }
-
- /* bitmap ought to be only used once */
- volcount = (volcount_t *)nsc_lookup(volhash, bmp);
- if (volcount) {
- /* argh */
- volcount->count++;
- } else {
- volcount = (volcount_t *)malloc(sizeof (volcount_t));
- volcount->count = 1;
- nsc_insert_node(volhash, volcount, bmp);
- }
- }
-}
-
-int
-sv_enable_one_nocfg(char *vol)
-{
- struct stat sb;
- sv_conf_t svc;
- int fd;
-
- bzero(&svc, sizeof (svc));
- if (stat(vol, &sb) != 0) {
- rdc_set_error(NULL, RDC_OS, 0, "unable to stat %s", vol);
- return (-1);
- }
- if (!S_ISCHR(sb.st_mode)) {
- rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL, "%s is not"
- " a character device", vol);
- return (-1);
- }
-
- svc.svc_major = major(sb.st_rdev);
- svc.svc_minor = minor(sb.st_rdev);
- strncpy(svc.svc_path, vol, sizeof (svc.svc_path));
-
- fd = open(SV_DEVICE, O_RDONLY);
- if (fd < 0) {
- rdc_set_error(NULL, RDC_OS, 0, 0);
- return (-1);
- }
-
- svc.svc_flag = (NSC_DEVICE | NSC_CACHE);
- svc.svc_error = spcs_s_ucreate();
-
- if (ioctl(fd, SVIOC_ENABLE, &svc) < 0) {
- if (errno != SV_EENABLED) {
- rdc_set_error(&svc.svc_error, RDC_INTERNAL,
- RDC_NONFATAL, 0);
- return (-1);
- }
- }
-
- spcs_log("sv", NULL, gettext("enabled %s"), svc.svc_path);
-
- close(fd);
- return (1);
-}
-
-int
-sv_enable_nocfg(rdcconfig_t *rdc)
-{
- struct stat stbv;
- struct stat stbb;
- sv_conf_t svcv;
- sv_conf_t svcb;
- char vol[NSC_MAXPATH];
- char bmp[NSC_MAXPATH];
- int fd = -1;
-
-
- if (self_check(rdc->phost)) {
- strncpy(vol, rdc->pfile, NSC_MAXPATH);
- strncpy(bmp, rdc->pbmp, NSC_MAXPATH);
- } else {
- strncpy(vol, rdc->sfile, NSC_MAXPATH);
- strncpy(bmp, rdc->sbmp, NSC_MAXPATH);
- }
-
- bzero(&svcv, sizeof (svcv));
- bzero(&svcb, sizeof (svcb));
-
- if ((stat(vol, &stbv) != 0) || (stat(bmp, &stbb) != 0))
- return (-1);
-
- if ((!S_ISCHR(stbv.st_mode)) || (!S_ISCHR(stbb.st_mode)))
- return (-1);
-
- svcv.svc_major = major(stbv.st_rdev);
- svcb.svc_minor = minor(stbb.st_rdev);
-
- strncpy(svcv.svc_path, vol, sizeof (svcv.svc_path));
- strncpy(svcb.svc_path, bmp, sizeof (svcb.svc_path));
-
- fd = open(SV_DEVICE, O_RDONLY);
- if (fd < 0)
- return (-1);
-
- /* SV enable the volume */
- svcv.svc_flag = (NSC_DEVICE | NSC_CACHE);
- svcv.svc_error = spcs_s_ucreate();
-
- if (ioctl(fd, SVIOC_ENABLE, &svcv) < 0) {
- if (errno != SV_EENABLED) {
- spcs_log("sv", &svcv.svc_error,
- gettext("unable to enable %s"),
- svcv.svc_path);
- spcs_s_ufree(&svcv.svc_error);
- return (-1);
- }
- }
-
- /* SV enable the bitmap disable the vol on error */
- svcb.svc_flag = (NSC_DEVICE | NSC_CACHE);
- svcb.svc_error = spcs_s_ucreate();
-
- if (ioctl(fd, SVIOC_ENABLE, &svcb) < 0) {
- if (errno != SV_EENABLED) {
- spcs_log("sv", &svcb.svc_error,
- gettext("unable to enable %s"),
- svcb.svc_path);
- if (ioctl(fd, SVIOC_DISABLE, &svcv) < 0)
- spcs_log("sv", &svcv.svc_error,
- gettext("unable to disable %s"),
- svcv.svc_path);
-
- spcs_s_ufree(&svcv.svc_error);
- spcs_s_ufree(&svcb.svc_error);
- return (-1);
- }
- }
-
-
- spcs_log("sv", NULL, gettext("enabled %s"), svcv.svc_path);
- spcs_log("sv", NULL, gettext("enabled %s"), svcb.svc_path);
- spcs_s_ufree(&svcv.svc_error);
- spcs_s_ufree(&svcb.svc_error);
-
-
- if (fd >= 0)
- (void) close(fd);
-
- return (1);
-}
-
-int
-do_autosv_enable(CFGFILE *cfg, rdcconfig_t *rdc)
-{
- char vol[NSC_MAXPATH];
- char bmp[NSC_MAXPATH];
-
- cfg_load_svols(cfg);
- cfg_load_dsvols(cfg);
- cfg_load_shadows(cfg);
- load_rdc_vols(cfg);
-
- if (self_check(rdc->phost)) {
- strncpy(vol, rdc->pfile, NSC_MAXPATH);
- strncpy(bmp, rdc->pbmp, NSC_MAXPATH);
- } else {
- strncpy(vol, rdc->sfile, NSC_MAXPATH);
- strncpy(bmp, rdc->sbmp, NSC_MAXPATH);
- }
- if (nsc_lookup(volhash, vol) == NULL) {
- if (cfg_vol_enable(cfg, vol, rdc->ctag, "sndr") < 0) {
- rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
- "auto sv enable failed for %s", vol);
- return (-1);
- }
- }
- if (nsc_lookup(volhash, bmp) == NULL) {
- if (cfg_vol_enable(cfg, bmp, rdc->ctag, "sndr") < 0) {
- rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
- "auto sv enable failed for %s", vol);
- return (-1);
- }
- }
-
- nsc_remove_all(volhash, free);
- volhash = NULL;
-
- cfg_unload_shadows();
- cfg_unload_dsvols();
- cfg_unload_svols();
-
- return (1);
-}
-
-int
-do_autosv_disable(CFGFILE *cfg, rdcconfig_t *rdc)
-{
- char vol[NSC_MAXPATH];
- char bmp[NSC_MAXPATH];
- volcount_t *vc;
-
- cfg_load_svols(cfg);
- cfg_load_dsvols(cfg);
- cfg_load_shadows(cfg);
- load_rdc_vols(cfg);
-
- if (self_check(rdc->phost)) {
- strncpy(vol, rdc->pfile, NSC_MAXPATH);
- strncpy(bmp, rdc->pbmp, NSC_MAXPATH);
- } else {
- strncpy(vol, rdc->sfile, NSC_MAXPATH);
- strncpy(bmp, rdc->sbmp, NSC_MAXPATH);
- }
-
- vc = nsc_lookup(volhash, vol);
- if (vc && (vc->count == 1)) {
- if (cfg_vol_disable(cfg, vol, rdc->ctag, "sndr") < 0)
- rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
- "auto sv disable failed for %s", vol);
- } else if (!vc) {
- rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
- "Unable to find %s in config", vol);
- }
- vc = nsc_lookup(volhash, bmp);
- if (vc && (vc->count == 1)) {
- if (cfg_vol_disable(cfg, bmp, rdc->ctag, "sndr") < 0)
- rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
- "auto sv disable failed for %s", bmp);
-
- } else if (!vc) {
- rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
- "Unable to find %s in config", bmp);
- }
-
- return (1);
-
-}
-
-/*
- * do sv enables for the appropriate vol
- * and bitmap. If called without persistance
- * it will follow a chain and sv enable all
- * otherwise, it will enable only the one
- * set.
- */
-int
-sv_enable(CFGFILE *cfg, rdcconfig_t *rdcs)
-{
- rdcconfig_t *rdcp = NULL;
-
- rdcp = rdcs;
- if (!rdcp->persist) {
-
- return (sv_enable_nocfg(rdcp));
-
- } else if (cfg == NULL) {
-
- return (-1);
-
- }
-
- do_autosv_enable(cfg, rdcp);
-
- return (1);
-}
-
-int
-sv_disable(CFGFILE *cfg, rdcconfig_t *rdcs)
-{
- rdcconfig_t *rdcp;
-
- rdcp = rdcs;
- if (!rdcp->persist) { /* don't disable */
-
- return (1);
-
- } else if (cfg == NULL) {
-
- return (-1);
-
- }
-
- do_autosv_disable(cfg, rdcp);
-
- return (1);
-
-}
-
-/*
- * disable the appropriate bitmap in rdc
- * and replace it with bitmap
- */
-int
-sv_reconfig(CFGFILE *cfg, rdcconfig_t *rdc, char *oldbmp, char *newbmp)
-{
- rdcconfig_t *rdcp;
- int fail = 0;
-
- rdcp = rdc;
- if (!rdcp->persist) { /* just enable, don't disable */
-
- sv_enable_one_nocfg(newbmp);
-
- } else if (rdcp->persist) { /* do sv disable and enable */
- volcount_t *vc;
-
- cfg_load_svols(cfg);
- cfg_load_dsvols(cfg);
- cfg_load_shadows(cfg);
- load_rdc_vols(cfg);
-
- vc = (volcount_t *)nsc_lookup(volhash, oldbmp);
- if (vc && (vc->count == 1)) {
- if (cfg_vol_disable(cfg, oldbmp, rdc->ctag, "sndr") < 0)
- rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
- "auto sv disable failed for %s", oldbmp);
-
- }
- if (nsc_lookup(volhash, newbmp) == NULL) {
- if (cfg_vol_enable(cfg,
- newbmp, rdc->ctag, "sndr") < 0) {
-
- rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
- "auto sv enable failed for %s", newbmp);
- fail++;
- }
- }
- nsc_remove_all(volhash, free);
- volhash = NULL;
-
- cfg_unload_shadows();
- cfg_unload_dsvols();
- cfg_unload_svols();
- if (fail)
- return (-1);
-
- }
- return (1);
-
-}
-
-/*
- * SNDR functions
- */
-
-/*
- * add_to_rdc_cfg
- * this adds the successfully created rdc sets to libdscfg,
- * also, as auto_sv stuff is part of libdscfg, it does the
- * auto_sv stuff and enables the correct volumes
- */
-int
-add_to_rdc_cfg(rdcconfig_t *rdcs)
-{
- CFGFILE *cfg;
- rdcconfig_t *rdcp;
- char *buf;
-
-
- buf = calloc(CFG_MAX_BUF, sizeof (char));
- if (!buf) {
- rdc_set_error(NULL, RDC_OS, RDC_FATAL, NULL);
- return (NULL);
- }
-
- if ((cfg = cfg_open(NULL)) == NULL) {
- rdc_set_error(NULL, RDC_DSCFG, 0, 0);
- return (-1);
- }
- if ((cfg_lock(cfg, CFG_WRLOCK)) < 0) {
- rdc_set_error(NULL, RDC_DSCFG, 0, 0);
- return (-1);
- }
-
- rdcp = rdcs;
- while (rdcp) {
- buf = config2buf(buf, rdcp);
- if ((sv_enable(cfg, rdcp) < 0) ||
- (cfg_put_cstring(cfg, "sndr", buf, CFG_MAX_BUF) < 0)) {
- rdc_set_error(NULL, RDC_DSCFG, 0, 0);
- free(buf);
- return (-1);
- }
- rdcp = rdcp->next;
- }
- if (!cfg_commit(cfg)) {
- rdc_set_error(NULL, RDC_DSCFG, 0, NULL);
- return (-1);
- }
-
- cfg_close(cfg);
-
- return (0);
-}
-
-int
-cfg_lookup(CFGFILE *cfg, char *shost, char *sfile)
-{
- char buf[CFG_MAX_BUF];
- char key[CFG_MAX_KEY];
- int setnum;
- int numsets = 0;
-
- numsets = cfg_get_num_entries(cfg, "sndr");
- for (setnum = 1; setnum <= numsets; setnum++) {
- bzero(key, CFG_MAX_KEY);
- snprintf(key, CFG_MAX_KEY, "sndr.set%d.shost", setnum);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) {
- rdc_set_error(NULL, RDC_DSCFG, 0, 0);
- return (-1);
- }
- if (strncmp(buf, shost, strlen(shost)))
- continue;
-
- bzero(key, CFG_MAX_KEY);
- snprintf(key, CFG_MAX_KEY, "sndr.set%d.secondary", setnum);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) {
- rdc_set_error(NULL, RDC_DSCFG, 0, 0);
- return (-1);
- }
- if (strncmp(buf, sfile, strlen(sfile)))
- continue;
- break;
- }
- return (setnum);
-}
-
-void
-remove_from_rdc_cfg(rdcconfig_t *rdcs)
-{
- CFGFILE *cfg;
- rdcconfig_t *rdcp;
- char key[CFG_MAX_KEY];
-
- rdcp = rdcs;
- cfg = cfg_open(NULL);
- cfg_lock(cfg, CFG_WRLOCK);
-
- while (rdcp) {
- snprintf(key, CFG_MAX_KEY, "sndr.set%d",
- cfg_lookup(cfg, rdcp->shost, rdcp->sfile));
- if ((sv_disable(cfg, rdcp) < 0) ||
- (cfg_put_cstring(cfg, key, NULL, 0)) < 0) {
- rdc_set_error(NULL, RDC_DSCFG, 0, 0);
- }
-
- rdcp = rdcp->next;
- }
- cfg_commit(cfg);
- cfg_close(cfg);
-}
-/*ARGSUSED*/
-int
-replace_entry(int offset, char *entry)
-{
- return (1);
-}
-
-/*
- * this will set the value at "field" in dscfg to the
- * value contained in entry.
- * for things like bitmap reconfigs, only pass one rdc
- * not a chain
- */
-int
-replace_cfgfield(rdcconfig_t *rdc, char *field, char *entry)
-{
- CFGFILE *cfg;
- rdcconfig_t *rdcp;
- char key[CFG_MAX_KEY];
- char newentry[CFG_MAX_BUF];
- char oldbmp[CFG_MAX_BUF];
- int setnum;
- int ispbmp = 0;
- int issbmp = 0;
-
- if (strncmp(field, "pbitmap", NSC_MAXPATH) == 0)
- ispbmp++;
- if (strncmp(field, "sbitmap", NSC_MAXPATH) == 0)
- issbmp++;
-
- bzero(newentry, sizeof (newentry));
- if (!entry || strlen(entry) == 0)
- *newentry = '-';
- else
- strncpy(newentry, entry, CFG_MAX_BUF);
-
-
- if ((cfg = cfg_open(NULL)) == NULL) {
- rdc_set_error(NULL, RDC_DSCFG, 0, 0);
- return (-1);
- }
- if ((cfg_lock(cfg, CFG_WRLOCK)) < 0) {
- rdc_set_error(NULL, RDC_DSCFG, 0, 0);
- return (-1);
- }
-
- rdcp = rdc;
- while (rdcp) {
- if ((setnum = cfg_lookup(cfg, rdcp->shost, rdcp->sfile)) < 0) {
- rdc_set_error(NULL, RDC_DSCFG, 0, 0);
- return (-1);
- }
- snprintf(key, CFG_MAX_KEY, "sndr.set%d.%s", setnum, field);
- if (!((ispbmp || issbmp) &&
- (cfg_get_cstring(cfg, key, oldbmp, CFG_MAX_BUF)) == 0)) {
- rdc_set_error(NULL, RDC_DSCFG, 0, "unable to get %s",
- key);
- }
- if (((ispbmp && self_check(rdcp->phost)) ||
- (issbmp && self_check(rdcp->shost))) &&
- (sv_reconfig(cfg, rdcp, oldbmp, newentry) < 0)) {
- rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
- "unable to sv reconfig %s to %s", oldbmp, newentry);
- return (-1);
- }
-
- if ((cfg_put_cstring(cfg, key, newentry, CFG_MAX_BUF)) < 0) {
- rdc_set_error(NULL, RDC_DSCFG, 0, 0);
- return (-1);
- }
- rdcp = rdcp->next;
- }
- cfg_commit(cfg);
- cfg_close(cfg);
- return (1);
-}
-
-/*
- * reverse_in_cfg
- * used by RDC_OPT_REVERSE_ROLE
- * swaps primary info and secondary info
- */
-int
-reverse_in_cfg(rdcconfig_t *rdc)
-{
- CFGFILE *cfg;
- rdcconfig_t *rdcp = NULL;
- char key[CFG_MAX_KEY];
- int setnum;
-
- if ((cfg = cfg_open(NULL)) == NULL) {
- rdc_set_error(NULL, RDC_DSCFG, 0, 0);
- return (-1);
- }
- if ((cfg_lock(cfg, CFG_WRLOCK)) < 0) {
- rdc_set_error(NULL, RDC_DSCFG, 0, 0);
- return (-1);
- }
-
- rdcp = rdc;
- while (rdcp) {
- if ((setnum = cfg_lookup(cfg, rdcp->shost, rdcp->sfile)) < 0) {
- rdc_set_error(NULL, RDC_DSCFG, 0, 0);
- goto badconfig;
- }
- bzero(key, CFG_MAX_KEY);
- snprintf(key, CFG_MAX_KEY, "sndr.set%d.phost", setnum);
- if ((cfg_put_cstring(cfg, key, rdcp->shost, CFG_MAX_BUF)) < 0) {
- rdc_set_error(NULL, RDC_DSCFG, 0, 0);
- goto badconfig;
- }
- bzero(key, CFG_MAX_KEY);
- snprintf(key, CFG_MAX_KEY, "sndr.set%d.primary", setnum);
- if ((cfg_put_cstring(cfg, key, rdcp->sfile, CFG_MAX_BUF)) < 0) {
- rdc_set_error(NULL, RDC_DSCFG, 0, 0);
- goto badconfig;
- }
- bzero(key, CFG_MAX_KEY);
- snprintf(key, CFG_MAX_KEY, "sndr.set%d.pbitmap", setnum);
- if ((cfg_put_cstring(cfg, key, rdcp->sbmp, CFG_MAX_BUF)) < 0) {
- rdc_set_error(NULL, RDC_DSCFG, 0, 0);
- goto badconfig;
- }
- bzero(key, CFG_MAX_KEY);
- snprintf(key, CFG_MAX_KEY, "sndr.set%d.shost", setnum);
- if ((cfg_put_cstring(cfg, key, rdcp->phost, CFG_MAX_BUF)) < 0) {
- rdc_set_error(NULL, RDC_DSCFG, 0, 0);
- goto badconfig;
- }
- bzero(key, CFG_MAX_KEY);
- snprintf(key, CFG_MAX_KEY, "sndr.set%d.secondary", setnum);
- if ((cfg_put_cstring(cfg, key, rdcp->pfile, CFG_MAX_BUF)) < 0) {
- rdc_set_error(NULL, RDC_DSCFG, 0, 0);
- goto badconfig;
- }
- bzero(key, CFG_MAX_KEY);
- snprintf(key, CFG_MAX_KEY, "sndr.set%d.sbitmap", setnum);
- if ((cfg_put_cstring(cfg, key, rdcp->pbmp, CFG_MAX_BUF)) < 0) {
- rdc_set_error(NULL, RDC_DSCFG, 0, 0);
- goto badconfig;
- }
- rdcp = rdcp->next;
- }
- if (!cfg_commit(cfg)) {
- cfg_close(cfg);
- return (-1);
- }
- cfg_close(cfg);
- return (0);
-
-badconfig:
- cfg_close(cfg);
- return (-1);
-}
diff --git a/usr/src/lib/librdc/common/rdcrules.c b/usr/src/lib/librdc/common/rdcrules.c
deleted file mode 100644
index 76fe39d48d..0000000000
--- a/usr/src/lib/librdc/common/rdcrules.c
+++ /dev/null
@@ -1,545 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/utsname.h>
-#include <sys/mdb_modapi.h>
-#include <stdio.h>
-#include <errno.h>
-#include <strings.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <netdb.h>
-#include <libintl.h>
-#include <sys/stream.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <ctype.h>
-#include <thread.h>
-#include <pthread.h>
-
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_u.h>
-#include <sys/unistat/spcs_s_impl.h>
-#include <sys/unistat/spcs_errors.h>
-
-#include <sys/nsctl/rdc_io.h>
-#include <sys/nsctl/rdc_ioctl.h>
-#include <sys/nsctl/rdc_prot.h>
-#include <sys/nsctl/librdc.h>
-#include <sys/nsctl/rdcerr.h>
-#include <sys/nsctl/cfg.h>
-
-#include <sys/unistat/spcs_dtrinkets.h>
-#include <sys/unistat/spcs_etrinkets.h>
-
-#include <sys/socket.h>
-#include <sys/mnttab.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netinet/tcp.h>
-#include <rpc/rpc_com.h>
-#include <rpc/rpc.h>
-
-#define RDC_LOCAL_TAG "local"
-
-/*
- * bitmap_in_use
- * return 1 if in use
- * return 0 if not in use
- * return -1 on error
- */
-
-int
-bitmap_in_use(int cmd, char *hostp, char *bmp)
-{
- int i, setnumber;
- CFGFILE *cfg;
- char host[CFG_MAX_BUF];
- char shost[CFG_MAX_BUF];
- char pri[CFG_MAX_BUF]; /* rdc primary vol */
- char sec[CFG_MAX_BUF]; /* rdc secondary vol */
- char sbm[CFG_MAX_BUF]; /* rdc secondary bitmap */
- char bit[CFG_MAX_BUF]; /* a bitmap */
- char mas[CFG_MAX_BUF]; /* II master */
- char sha[CFG_MAX_BUF]; /* II shadow */
- char mod[CFG_MAX_BUF]; /* II mode */
- char ovr[CFG_MAX_BUF]; /* II overflow */
- char buf[CFG_MAX_BUF];
- char key[CFG_MAX_KEY];
- int rc;
- int ret = 0;
-
-
- if ((cfg = cfg_open(NULL)) == NULL) {
- rdc_set_error(NULL, RDC_DSCFG, 0, NULL);
- return (-1);
- }
- if (!cfg_lock(cfg, CFG_RDLOCK)) {
- rdc_set_error(NULL, RDC_DSCFG, 0, NULL);
- cfg_close(cfg);
- return (-1);
- }
-
- /*
- * look into II config to see if this is being used elsewhere
- */
- /*CSTYLED*/
- for (i = 0; ; i++) {
- setnumber = i + 1;
- snprintf(key, sizeof (key), "ii.set%d", setnumber);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
- break;
-
- rc = sscanf(buf, "%s %s %s %s %s", mas, sha, bit, mod, ovr);
- if (rc != 5) {
- rdc_set_error(NULL, RDC_OS, 0, NULL);
- ret = -1;
- goto done;
- }
-
- /*
- * got master shadow bitmap, now compare
- */
- if ((strcmp(bmp, mas) == 0) ||
- (strcmp(bmp, sha) == 0) ||
- (strcmp(bmp, bit) == 0) ||
- (strcmp(bmp, ovr) == 0)) {
- rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
- "bitmap %s is in use by"
- "Point-in-Time Copy", bmp);
- ret = 1;
- goto done;
- }
- }
- /*
- * and last but not least, make sure sndr is not using vol for anything
- */
- /*CSTYLED*/
- for (i = 0; ; i++) {
- setnumber = i + 1;
- snprintf(key, sizeof (key), "sndr.set%d", setnumber);
- if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
- break;
- /*
- * I think this is quicker than
- * having to double dip into the config
- */
- (void) sscanf(buf, "%s %s %s %s %s %s", host, pri, bit,
- shost, sec, sbm);
- if (cmd == RDC_CMD_ENABLE) {
- if (self_check(host)) {
- if ((strcmp(bmp, pri) == 0) ||
- (strcmp(bmp, bit) == 0)) {
- rdc_set_error(NULL, RDC_INTERNAL,
- RDC_NONFATAL, dgettext("librdc",
- "bitmap %s is in use by %s"),
- bmp, RDC_NAME_DU_JOUR);
-
-
- ret = 1;
- goto done;
- }
- } else {
- if ((strcmp(bmp, sec) == 0) ||
- (strcmp(bmp, sbm) == 0)) {
- rdc_set_error(NULL, RDC_INTERNAL,
- RDC_NONFATAL, dgettext("librdc",
- "bitmap %s is in use by %s"),
- bmp, RDC_NAME_DU_JOUR);
- ret = 1;
- goto done;
- }
- }
- } else if (cmd == RDC_CMD_RECONFIG) {
-
- /*
- * read this logic 1000 times and consider
- * multi homed, one to many, many to one (marketing)
- * etc, etc, before changing
- */
- if (self_check(hostp)) {
- if (self_check(host)) {
- if ((strcmp(bmp, pri) == 0) ||
- (strcmp(bmp, bit) == 0)) {
- rdc_set_error(NULL,
- RDC_INTERNAL, RDC_NONFATAL,
- dgettext("librdc", "bitmap"
- " %s is in use by %s"),
- bmp, RDC_NAME_DU_JOUR);
- ret = 1;
- goto done;
- }
- } else {
- if ((strcmp(hostp, shost) == 0) &&
- (strcmp(bmp, sec) == 0) ||
- (strcmp(bmp, sbm) == 0)) {
- rdc_set_error(NULL,
- RDC_INTERNAL, RDC_NONFATAL,
- dgettext("librdc", "bitmap"
- " %s is in use by %s"),
- bmp, RDC_NAME_DU_JOUR);
- ret = 1;
- goto done;
- }
- }
- } else { /* self_check(hostp) failed */
- if (self_check(host)) {
- if ((strcmp(shost, hostp) == 0) &&
- (strcmp(bmp, sec) == 0) ||
- (strcmp(bmp, sbm) == 0)) {
- rdc_set_error(NULL,
- RDC_INTERNAL, RDC_NONFATAL,
- dgettext("librdc", "bitmap"
- " %s is in use by %s"),
- bmp, RDC_NAME_DU_JOUR);
- ret = 1;
- goto done;
- }
- } else {
- if ((strcmp(host, hostp) == 0) &&
- (strcmp(bmp, pri) == 0) ||
- (strcmp(bmp, bit) == 0)) {
- rdc_set_error(NULL,
- RDC_INTERNAL, RDC_NONFATAL,
- dgettext("librdc", "bitmap"
- " %s is in use by %s"),
- bmp, RDC_NAME_DU_JOUR);
- ret = 1;
- goto done;
- }
- }
- }
-
- }
-
- }
-done:
- cfg_close(cfg);
- return (ret);
-
-}
-
-int
-check_dgislocal(char *dgname)
-{
- char *othernode;
- int rc;
-
- /*
- * check where this disk service is mastered
- */
-
- rc = cfg_dgname_islocal(dgname, &othernode);
- if (rc < 0) {
- rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
- gettext("unable to find "
- "disk service, %s: %s"), dgname, strerror(errno));
- return (-1);
- }
-
- if (rc == 0) {
- rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
- gettext("disk service, %s, is "
- "active on node \"%s\"\nPlease re-issue "
- "the command on that node"), dgname, othernode);
- return (-1);
- }
- return (DCMD_OK);
-}
-
-int
-ctag_check(rdcconfig_t *rdc)
-{
- char *file_dgname;
- char *bmp_dgname;
- char *fromhost, *tohost;
- char *fromfile, *tofile;
- char *frombitmap, *tobitmap;
- char *localfile;
- char *ctag;
- char file_buf[MAX_RDC_HOST_SIZE];
- char bmp_buf[MAX_RDC_HOST_SIZE];
- int is_primary;
- int islocal = 0;
- struct hostent *hp;
- char fromname[MAXHOSTNAMELEN], toname[MAXHOSTNAMELEN];
-
- fromhost = rdc->phost;
- fromfile = rdc->pfile;
- frombitmap = rdc->pbmp;
- tohost = rdc->shost;
- tofile = rdc->sfile;
- tobitmap = rdc->sbmp;
- ctag = rdc->ctag;
-
- /*
- * Check for the special (local) cluster tag
- */
- if (!cfg_iscluster())
- return (0);
-
- if (ctag != NULL && strcmp(rdc->ctag, RDC_LOCAL_TAG) == 0) {
- strcpy(rdc->ctag, "-");
- islocal = TRUE;
- } else {
- islocal = FALSE;
- }
-
- hp = gethost_byname(fromhost);
- strncpy(fromname, hp->h_name, MAXHOSTNAMELEN);
- hp = gethost_byname(tohost);
- strncpy(toname, hp->h_name, MAXHOSTNAMELEN);
- if (!self_check(fromname) && !self_check(toname)) {
- /*
- * If we could get a list of logical hosts on this cluster
- * then we could print something intelligent about where
- * the volume is mastered. For now, just print some babble
- * about the fact that we have no idea.
- */
- rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
- gettext("either %s:%s or %s:%s is not local"),
- fromhost, fromfile, tohost, tofile);
- return (-1);
- }
-
- is_primary = self_check(fromname);
-
- /*
- * If implicit disk group name and no ctag specified by user,
- * we set the ctag to it.
- * If implicit disk group name, it must match any supplied ctag.
- */
- if (is_primary)
- localfile = fromfile;
- else
- localfile = tofile;
- file_dgname = cfg_dgname(localfile, file_buf, sizeof (file_buf));
- if (file_dgname != NULL && file_dgname[0] != '\0')
- if (check_dgislocal(file_dgname) < 0) {
- /* errors already set */
- return (-1);
- }
-
- if (strlen(ctag) == 0 && file_dgname && strlen(file_dgname))
- strncpy(ctag, file_dgname, MAX_RDC_HOST_SIZE);
-
- /*
- * making an exception here for users giving the "local"tag
- * this overrides this error message. (rdc_islocal ! = 1)
- */
- if (strlen(ctag) != 0 && file_dgname && islocal != 1 &&
- strlen(file_dgname) != 0 &&
- strncmp(ctag, file_dgname, MAX_RDC_HOST_SIZE) != 0) {
- rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
- gettext("ctag \"%s\" does not "
- "match disk group name \"%s\" of volume %s"), ctag,
- file_dgname, localfile);
- return (-1);
- }
- if ((file_dgname == NULL) || ((strlen(ctag) == 0) &&
- (strlen(file_dgname) == 0))) {
- /*
- * we must have a non-volume managed disk here
- * so ask for a tag and get out
- */
- rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
- gettext("volume \"%s\" is not part"
- " of a disk group,\nplease specify resource ctag\n"),
- localfile);
-
- }
-
- /*
- * Local bitmap must also have same ctag.
- */
- if (is_primary)
- localfile = frombitmap;
- else
- localfile = tobitmap;
- bmp_dgname = cfg_dgname(localfile, bmp_buf, sizeof (bmp_buf));
- if (bmp_dgname != NULL && bmp_dgname[0] != '\0')
- if (check_dgislocal(bmp_dgname) < 0) {
- /* error already set */
- return (-1);
- }
-
- if (file_dgname && strlen(file_dgname) != 0) {
- /* File is in a real disk group */
- if ((bmp_dgname == NULL) || (strlen(bmp_dgname) == 0)) {
- /* Bitmap is not in a real disk group */
- rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
- gettext("bitmap %s is not in disk group \"%s\""),
- localfile, islocal < 1?file_dgname:ctag);
- return (-1);
- }
- }
- if (strlen(ctag) != 0 && bmp_dgname && islocal != 1 &&
- strlen(bmp_dgname) != 0 &&
- strncmp(ctag, bmp_dgname, MAX_RDC_HOST_SIZE) != 0) {
- rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
- gettext("ctag \"%s\" does not "
- "match disk group name \"%s\" of bitmap %s"),
- ctag, bmp_dgname, localfile);
- return (-1);
- }
-
- return (0);
-}
-int
-mounted(char *device)
-{
- char target[NSC_MAXPATH];
- struct mnttab mntref;
- struct mnttab mntent;
- FILE *mntfp;
- int rdsk;
- char *s;
- int rc;
- int i;
-
- rdsk = i = 0;
- for (s = target; i < NSC_MAXPATH && (*s = *device++); i++) {
- if (*s == 'r' && rdsk == 0 && strncmp(device, "dsk/", 4) == 0)
- rdsk = 1;
- else
- s++;
- }
- *s = '\0';
-
- mntref.mnt_special = target;
- mntref.mnt_mountp = NULL;
- mntref.mnt_fstype = NULL;
- mntref.mnt_mntopts = NULL;
- mntref.mnt_time = NULL;
-
- mntfp = fopen(MNTTAB, "r");
-
- if (mntfp == NULL) {
- /* Assume the worst, that it is mounted */
- return (1);
- }
-
- if ((rc = getmntany(mntfp, &mntent, &mntref)) != -1) {
- /* found something before EOF */
- fclose(mntfp);
- return (1);
- }
-
- fclose(mntfp);
- return (0);
-}
-
-int
-can_enable(rdcconfig_t *rdc)
-{
- struct stat stb;
-
- if ((strcmp(rdc->pfile, rdc->pbmp) == 0) ||
- (strcmp(rdc->sfile, rdc->sbmp) == 0)) {
- rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
- dgettext("librdc", "volumes and bitmaps must not match"));
- return (0);
- }
- if (ctag_check(rdc) < 0) {
- /* rdc_error should already be set */
- return (0);
- }
-
- if (self_check(rdc->phost)) {
- if (stat(rdc->pfile, &stb) != 0) {
- rdc_set_error(NULL, RDC_OS, RDC_FATAL, NULL);
- return (0);
- }
- if (!S_ISCHR(stb.st_mode)) {
- rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
- dgettext("librdc", "%s is not a character device"),
- rdc->pfile);
- return (0);
- }
- return (rdc->persist ?
- !bitmap_in_use(RDC_CMD_ENABLE, rdc->phost, rdc->pbmp) : 1);
- } else { /* on the secondary */
- if (stat(rdc->sfile, &stb) != 0) {
- rdc_set_error(NULL, RDC_OS, 0,
- dgettext("librdc", "unable to access %s: %s"),
- rdc->sfile, strerror(errno));
- }
- if (!S_ISCHR(stb.st_mode)) {
- rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL,
- dgettext("librdc",
- "%s is not a character device"), rdc->sfile);
- }
- return (rdc->persist ?
- !bitmap_in_use(RDC_CMD_ENABLE, rdc->shost, rdc->sbmp) : 1);
- }
-}
-
-int
-can_reconfig_pbmp(rdcconfig_t *rdc, char *bmp)
-{
- if (!rdc->persist)
- return (0);
-
- return (!bitmap_in_use(RDC_CMD_RECONFIG, rdc->phost, bmp));
-}
-
-int
-can_reconfig_sbmp(rdcconfig_t *rdc, char *bmp)
-{
- if (!rdc->persist)
- return (0);
-
- return (!bitmap_in_use(RDC_CMD_RECONFIG, rdc->shost, bmp));
-}
-
-rdc_rc_t *
-cant_rsync(rdcconfig_t *rdc)
-{
- rdc_rc_t *rc;
-
- if (mounted(rdc->pfile)) {
- rc = new_rc();
- if (rc == NULL)
- return (NULL);
- strncpy(rc->set.phost, rdc->phost, MAX_RDC_HOST_SIZE);
- strncpy(rc->set.pfile, rdc->pfile, NSC_MAXPATH);
- strncpy(rc->set.pbmp, rdc->pbmp, NSC_MAXPATH);
- strncpy(rc->set.shost, rdc->shost, MAX_RDC_HOST_SIZE);
- strncpy(rc->set.sfile, rdc->sfile, NSC_MAXPATH);
- strncpy(rc->set.sbmp, rdc->sbmp, NSC_MAXPATH);
-
- rc->rc = -1;
-
- rdc_set_error(NULL, RDC_INTERNAL, 0, "unable to sync %s volume"
- " is currently mounted", rdc->pfile);
- strncpy(rc->msg, rdc_error(NULL), RDC_ERR_SIZE);
-
- return (rc);
- }
- return (NULL);
-}
diff --git a/usr/src/lib/librdc/common/rdcrules.h b/usr/src/lib/librdc/common/rdcrules.h
deleted file mode 100644
index ab111fbdce..0000000000
--- a/usr/src/lib/librdc/common/rdcrules.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _RDCRULES_H
-#define _RDCRULES_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* insert handy rule enforcing functions here */
-
-extern int bitmap_in_use(int cmd, char *hostp, char *bmp);
-extern int mounted(char *);
-extern int can_enable(rdcconfig_t *rdc);
-extern int can_reconfig_pbmp(rdcconfig_t *rdc, char *bmp);
-extern int can_reconfig_sbmp(rdcconfig_t *rdc, char *bmp);
-extern rdc_rc_t *cant_rsync(rdcconfig_t *rdc);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _RDCRULES_H */
diff --git a/usr/src/lib/librdc/i386/Makefile b/usr/src/lib/librdc/i386/Makefile
deleted file mode 100644
index d3a87b4acc..0000000000
--- a/usr/src/lib/librdc/i386/Makefile
+++ /dev/null
@@ -1,33 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# lib/librdc/i386/Makefile
-
-include ../Makefile.com
-
-.KEEP_STATE:
-
-all: $(LIBS)
-
-install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTARLINK)
-lint:
diff --git a/usr/src/lib/librdc/sparc/Makefile b/usr/src/lib/librdc/sparc/Makefile
deleted file mode 100644
index d96edd5d5e..0000000000
--- a/usr/src/lib/librdc/sparc/Makefile
+++ /dev/null
@@ -1,31 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-include ../Makefile.com
-
-.KEEP_STATE:
-
-all: $(LIBS)
-
-install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTARLINK)
-lint:
diff --git a/usr/src/lib/libunistat/Makefile b/usr/src/lib/libunistat/Makefile
deleted file mode 100644
index c27cb5079a..0000000000
--- a/usr/src/lib/libunistat/Makefile
+++ /dev/null
@@ -1,96 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# lib/libunistat/Makefile
-
-include ../Makefile.lib
-
-UTSBASE= ../../uts
-
-SUBDIRS= $(MACH)
-
-all := TARGET= all
-clean := TARGET= clean
-clobber := TARGET= clobber
-delete := TARGET= delete
-install := TARGET= install
-lint := TARGET= lint
-lintinter := TARGET= lintinter
-_msg := TARGET= _msg
-package := TARGET= package
-
-LIBRARY= libunistat.a
-
-HDRS= spcs_dtrinkets.h \
- spcs_etrinkets.h \
- spcs_errors.h \
- spcs_etext.h
-HDRDIR= common
-
-ROOTHDRDIR= $(ROOT)/usr/include/sys/unistat
-ROOTHDRS= $(HDRS:%=$(ROOTHDRDIR)/%)
-
-.KEEP_STATE:
-
-all clean clobber delete lint package lintinter: $(SUBDIRS)
-
-install: $(SUBDIRS)
-install_h: $(ROOTHDRDIR) $(ROOTHDRS)
-
-check:
-
-# install rule for install_h target
-$(ROOTHDRDIR):
- $(INS.dir)
-
-$(ROOTHDRDIR)/spcs_errors.h: $(MACH)/spcs_errors.h
- $(INS.file) $(MACH)/spcs_errors.h
-
-$(MACH)/spcs_errors.h: FRC
- @ cd $(MACH); pwd; $(MAKE) spcs_errors.h
-
-$(ROOTHDRDIR)/spcs_s_u.h: common/spcs_s_u.h
- $(INS.file) common/spcs_s_u.h
-
-$(ROOTHDRDIR)/spcs_etext.h: $(MACH)/spcs_etext.h
- $(INS.file) $(MACH)/spcs_etext.h
-
-$(MACH)/spcs_etext.h: FRC
- @ cd $(MACH); pwd; $(MAKE) spcs_etext.h
-
-$(ROOTHDRDIR)/spcs_dtrinkets.h: $(MACH)/spcs_dtrinkets.h
- $(INS.file) $(MACH)/spcs_dtrinkets.h
-
-$(MACH)/spcs_dtrinkets.h: FRC
- @ cd $(MACH); pwd; $(MAKE) spcs_dtrinkets.h
-
-$(ROOTHDRDIR)/spcs_etrinkets.h: $(MACH)/spcs_etrinkets.h
- $(INS.file) $(MACH)/spcs_etrinkets.h
-
-$(MACH)/spcs_etrinkets.h: FRC
- @ cd $(MACH); pwd; $(MAKE) spcs_etrinkets.h
-
-$(MACH) $(MACH64): FRC
- @cd $@; pwd; $(MAKE) $(TARGET)
-
-FRC:
diff --git a/usr/src/lib/libunistat/Makefile.com b/usr/src/lib/libunistat/Makefile.com
deleted file mode 100644
index 522a938a4b..0000000000
--- a/usr/src/lib/libunistat/Makefile.com
+++ /dev/null
@@ -1,189 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# lib/libunistat/Makefile.com
-#
-# include global definitions
-include ../../../Makefile.master
-
-LIBRARY= libunistat.a
-VERS= .1
-
-OBJECTS= spcs_s_u.o spcs_log.o
-
-# include library definitions
-include ../../Makefile.lib
-
-SRCS= $(OBJECTS:%.o=../common/%.c)
-SRCDIR= ../common
-
-LIBS += $(DYNLIB) $(LINTLIB)
-
-# definitions for lint
-
-LINTFLAGS += -u -I..
-LINTFLAGS += -erroff=E_UNDEFINED_SYMBOL
-LINTFLAGS += -erroff=E_STATIC_UNUSED
-LINTFLAGS += -erroff=E_BAD_PTR_INT_COMB_ARG
-LINTFLAGS += -erroff=E_VAR_USED_BEFORE_SET
-LINTFLAGS += -erroff=E_SEC_FORBIDDEN_WARN_CFTIME
-LINTFLAGS += -erroff=E_SEC_PRINTF_VAR_FMT
-LINTFLAGS += -erroff=E_OLD_STYLE_DECL_OR_BAD_TYPE
-LINTFLAGS += -erroff=E_YACC_ERROR
-LINTFLAGS += -erroff=E_FUNC_RET_MAYBE_IGNORED2
-LINTFLAGS += -erroff=E_FUNC_RET_ALWAYS_IGNOR2
-LINTOUT= lint.out
-LINTOUT_INTER= lintinter.out
-
-CERRWARN += -_gcc=-Wno-parentheses
-CERRWARN += -_gcc=-Wno-unused-variable
-
-LINTSRC= $(LINTLIB:%.ln=%)
-ROOTLINTDIR= $(ROOTLIBDIR)
-ROOTLINT= $(LINTSRC:%=$(ROOTLINTDIR)/%)
-
-CLEANFILES += $(LINTOUT) $(LINTLIB) $(LINTOUT_INTER) $(LINT_INTER)
-
-all:= TARGET= all
-clean:= TARGET= clean
-clobber:= TARGET= clobber
-install:= TARGET= install
-lint:= TARGET= lint
-lintinter:= TARGET= lintinter
-
-MODS= dsw \
- rdc \
- spcs \
- sdbc \
- solaris \
- sv
-
-ERRS= $(MODS:%=$(SRCDIR)/%/%.err)
-MSGS= $(MODS:%=$(SRCDIR)/%/%.msg)
-EDEFS= $(MODS:%=$(SRCDIR)/%/%.edef)
-TRNKS= $(MODS:%=$(SRCDIR)/%/%.trnk)
-DTRNKS= $(MODS:%=$(SRCDIR)/%/%.dtrnk)
-
-ERRGEN_DIR= $(SRC)/cmd/avs/errgen
-ERRGEN= $(ERRGEN_DIR)/errgen
-
-# production (non-debug)
-DFLAGS = -DISSTATIC=static
-
-# development (debug) - cstyle prohibits use of "STATIC"
-DFLAGS = -g -DISSTATIC=" "
-
-CFLAGS += $(CCVERBOSE) $(DFLAGS) -I. -DLIBSPCS_CLIENT\
- -I$(JAVAINC) -I$(JAVAINCSOL)\
- -DLIBUNISTAT_LOCALE=\"/usr/install/unistat/locale\"
-CFLAGS64 += $(CCVERBOSE) $(DFLAGS) -I. -DLIBSPCS_CLIENT\
- -I$(JAVAINC) -I$(JAVAINCSOL)\
- -DLIBUNISTAT_LOCALE=\"/usr/install/unistat/locale\"
-LDLIBS += -lc
-
-$(LINTLIB) := SRCS = ../common/llib-lunistat
-$(LINTLIB) := LINTFLAGS = -nvx -DLIBSPCS_CLIENT -I$(JAVAINC) -I$(JAVAINCSOL)\
- -DISSTATIC=static \
- -DLIBUNISTAT_LOCALE=\"/usr/install/unistat/locale\"
-$(LINTLIB) := LINTFLAGS64 = -nvx -Xarch=v9 -DLIBSPCS_CLIENT \
- -I$(JAVAINC) -I$(JAVAINCSOL) \
- -DISSTATIC=static \
- -DLIBUNISTAT_LOCALE=\"/usr/install/unistat/locale\"
-
-$(LINT_INTER) := SRCS += ../common/llib-lunistat
-$(LINT_INTER) := LINTFLAGS = -nvx -DLIBSPCS_CLIENT -I$(JAVAINC) -I$(JAVAINCSOL)\
- -DISSTATIC=static \
- -DLIBUNISTAT_LOCALE=\"/usr/install/unistat/locale\"
-$(LINT_INTER) := LINTFLAGS64 = -nvx -Xarch=v9 -DLIBSPCS_CLIENT \
- -I$(JAVAINC) -I$(JAVAINCSOL) \
- -DISSTATIC=static \
- -DLIBUNISTAT_LOCALE=\"/usr/install/unistat/locale\"
-
-COMMENT= "/* THIS FILE IS AUTOMATICALLY GENERATED: DO NOT EDIT */"
-
-CLEANFILES += *.h *.po\
- $(SRCDIR)/*/*.msg\
- $(SRCDIR)/*/*.properties\
- $(SRCDIR)/*/*.exc\
- $(SRCDIR)/*/*.edef\
- $(SRCDIR)/*/*.trnk\
- $(SRCDIR)/*/*.dtrnk
-
-# note that the properties files are generated in ../libspcs/java
-
-.SUFFIXES: .err .exc .properties .edef .msg .trnk .dtrnk
-
-.err.msg:
- $(ERRGEN) -m `basename $*` <$*.err >$*.msg
-
-.err.edef:
- $(ERRGEN) -c `basename $*` <$*.err >$*.edef
-
-.err.trnk:
- $(ERRGEN) -t `basename $*` <$*.err >$*.trnk
-
-.err.dtrnk:
- $(ERRGEN) -x `basename $*` <$*.err >$*.dtrnk
-
-all: spcs_etext.h spcs_errors.h spcs_etrinkets.h spcs_dtrinkets.h $(LIB)
-
-spcs_dtrinkets.h: $(ERRGEN) $(DTRNKS)
- @echo $(COMMENT) > $@
- cat $(DTRNKS) >>spcs_dtrinkets.h
-
-spcs_etrinkets.h: $(ERRGEN) $(TRNKS)
- @echo $(COMMENT) > $@
- cat $(TRNKS) $(SRCDIR)/spcs_etrinkets.stub >> $@
-
-spcs_etext.h: $(ERRGEN) $(MSGS)
- @echo $(COMMENT) > $@
- $(CAT) $(MSGS) $(SRCDIR)/spcs_etext.stub >> $@
- $(SED) "s/ \"/ gettext(\"/" < $@ |\
- sed "s/\",/\"),/" > temp
- xgettext -d unistat temp ; rm temp
-
-spcs_errors.h: $(ERRGEN) $(EDEFS)
- @echo $(COMMENT) > $@
- $(CAT) $(EDEFS) $(SRCDIR)/spcs_errors.stub >> $@
-
-$(ERRGEN):
- @cd $(ERRGEN_DIR); pwd; $(MAKE) install
-
-
-.KEEP_STATE:
-
-FRC:
-
-lint: lintcheck $(LINTLIB)
-lintinter: $(LINT_INTER)
-
-# include library targets
-include ../../Makefile.targ
-
-objs/%.o pics/%.o: ../common/%.c
- $(COMPILE.c) -o $@ $<
- $(POST_PROCESS_O)
-
-# install rule for lint library target
-$(ROOTLINTDIR)/%: ../common/%
- $(INS.file)
diff --git a/usr/src/lib/libunistat/common/README b/usr/src/lib/libunistat/common/README
deleted file mode 100644
index e651404de7..0000000000
--- a/usr/src/lib/libunistat/common/README
+++ /dev/null
@@ -1,33 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-The error resource files in *.err of the subdirectories must only contain
-embedded "%s" format descriptors for info to be edited into messages returned
-from ioctls. Special "bytestream" data to be passed with status
-(implementation TBD) is signified by "@@@" as the last three characters of
-the message text. Don't try to use this to pass a bytestream back via an
-ioctl: it will just trigger an error.
-
-After early development when the first creation of foreign language locale
-files by the company for a product takes place you are NOT free to make edits
-to existing messages or their status code labels nor do any insertions. You
-may ONLY ONLY ONLY append new lines to the end of the file.
diff --git a/usr/src/lib/libunistat/common/dsw/dsw.err b/usr/src/lib/libunistat/common/dsw/dsw.err
deleted file mode 100644
index 960a41122a..0000000000
--- a/usr/src/lib/libunistat/common/dsw/dsw.err
+++ /dev/null
@@ -1,54 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-EMPTY = Empty string
-HDRBMP = Unable to read or write bitmap header
-INVALBMP = Bitmap magic number is not valid
-MISMATCH = Arguments inconsistent with current bitmap
-SHDSIZE = Shadow too small
-BMPSIZE = Bitmap too small
-REGISTER = Registration failed
-DIRTY = Bitmap is dirty
-SHUTDOWN = Shadow shutting down
-OPEN = nsc_open failed
-INUSE = Volume in use
-NOTFOUND = Volume not enabled
-COPYING = Volume copy in progress
-IO = I/O error copying data
-ABORTED = Copy operation aborted
-PARTSIZE = nsc_partsize failed
-DEPENDENCY = Volumes are not currently independent
-MAPMEMORY = Could not allocate memory for bitmaps in interface library (malloc)
-RSRVFAIL = nsc_reserve failed
-OPACKAGE = Another package would not allow target to be changed at this moment
-INCOMPLETE = Source shadow volume is not complete due to earlier overflow
-NOTEXPORTED = Shadow volume is not exported
-ALREADY = Operation already successfully performed
-WRONGTYPE = Wrong type of shadow group
-OMAGIC = Overflow volume magic number or name does not match
-ODEPENDENCY = Volumes are currently dependent on overflow volume
-OFFLINE = Volume offline
-NOTLOCKED = Set not pid-locked
-CNOTFOUND = Cluster resource group not found
-GNOTFOUND = No such group defined
-DISABLE = One or more sets failed to be disabled
-ISEXPORTED = Update or copy not allowed on an exported shadow volume
diff --git a/usr/src/lib/libunistat/common/llib-lunistat b/usr/src/lib/libunistat/common/llib-lunistat
deleted file mode 100644
index 9b31630c45..0000000000
--- a/usr/src/lib/libunistat/common/llib-lunistat
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/* LINTLIBRARY */
-/* PROTOLIB1 */
-
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_u.h>
-
-void spcs_s_uinit(spcs_s_info_t ustatus);
-spcs_s_info_t spcs_s_ucreate(void);
-char *spcs_s_string(spcs_s_info_t ustatus, char *msg);
-void spcs_s_report(spcs_s_info_t ustatus, FILE *fd);
-void spcs_s_exception(spcs_s_info_t ustatus, void *env);
-void spcs_s_ufree(spcs_s_info_t *ustatus_a);
-void spcs_log(const char *product, spcs_s_info_t *status,
- const char *format, ...);
diff --git a/usr/src/lib/libunistat/common/mapfile-vers b/usr/src/lib/libunistat/common/mapfile-vers
deleted file mode 100644
index 8c4028fc96..0000000000
--- a/usr/src/lib/libunistat/common/mapfile-vers
+++ /dev/null
@@ -1,55 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
-#
-
-#
-# MAPFILE HEADER START
-#
-# WARNING: STOP NOW. DO NOT MODIFY THIS FILE.
-# Object versioning must comply with the rules detailed in
-#
-# usr/src/lib/README.mapfiles
-#
-# You should not be making modifications here until you've read the most current
-# copy of that file. If you need help, contact a gatekeeper for guidance.
-#
-# MAPFILE HEADER END
-#
-
-#
-# Generic interface definition for usr/src/lib/libunistat.
-#
-
-$mapfile_version 2
-
-SYMBOL_VERSION SUNWprivate {
- global:
- spcs_s_uinit;
- spcs_s_ucreate;
- spcs_s_string;
- spcs_s_report;
- spcs_s_exception;
- spcs_s_ufree;
- spcs_log;
- local:
- *;
-};
diff --git a/usr/src/lib/libunistat/common/rdc/rdc.err b/usr/src/lib/libunistat/common/rdc/rdc.err
deleted file mode 100644
index a06b5476f8..0000000000
--- a/usr/src/lib/libunistat/common/rdc/rdc.err
+++ /dev/null
@@ -1,93 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-EPERM = Must be super-user to execute
-EINVAL = Invalid flag %s
-ALREADY = %s ==> %s not already enabled
-DISABLEPENDING = Disable pending on %s ==> %s, try again later
-ENABLEPENDING = Enable pending on %s ==> %s, try again later
-OPNSECSRC = Host %s: Source %s, open remote host failed
-OPNPRISRC = Host %s: Source %s, open failed
-OPNSECTGT = Host %s: Target %s, open remote host failed
-OPNPRITGT = Host %s: Target %s, open failed
-NOLOCHOST = Disks %s,%s do not reside on host %s or host %s
-NOTREMOTE = Master %s and Slave %s have same id %s
-MASTERNOTLOCAL = Master %s does not reside on this host: %s
-YOUNGER = %s is failed from %s..cannot proceed
-NODISABLE = Currently syncing, unable to disable
-CONN = Unable to connect to %s: local disable complete, remote disable aborted
-FLUSH = Will disable when ATM queue flushes on %s ==> %s
-SYNCING = Request not serviced, %s is currently being synced.
-INITREMOTE = Could not initialize remote data structures on %s ==> %s set
-INITLOCAL = Could not initialize local data structures on %s ==> %s set
-NOSLAVE = Target %s is failed, cannot set up for sync operation
-SIZE = Size of Primary %s:%s(%s) must be less than or equal to size of Secondary %s:%s(%s)
-SIZCHG = Device size change in dual copy set
-NOBMAP = Recovery bitmaps not allocated
-INITAFTERSYNC = Could not initialize data structures on %s ==> %s set after sync
-FAIL = Dual copy failed, offset:%s
-MIRRORDOWN = Mirror node is down
-GETSIZE = %s:%s has invalid size (%s)..cannot proceed
-UPDATE = Update sync %s:%s ==> %s:%s only allowed for an rdc device set
-EQUAL = Illegal device set %s:%s to itself
-MATCH = Device %s:%s belongs to another RDC device set
-MASTER = Changing the primary SNDR device %s:%s to become secondary and the secondary SNDR device %s:%s to become primary is not allowed in advanced configs
-CONNOPEN = Could not open file %s:%s on remote node
-NOPROC = Could not create rdc_config process
-BITMAP = Allocation of bitmap device %s failed
-MIRRORUP = Change request denied, volume mirror is up
-VERSION = Change request denied, don't understand request version
-EMPTY = Empty string
-ENABLED = %s:%s ==> %s:%s is already enabled
-OPEN = Unable to open %s:%s
-ADDTOIF = Unable to add interface %s to %s
-REGISTER = Unable to register %s
-NOTPRIMARY = Not primary, cannot sync %s:%s and %s:%s
-RSYNCNEEDED = Reverse sync needed, cannot sync %s:%s ==> %s:%s
-NOTHREADS = Unable to initialize the kernel thread set
-NETCONFIG = NULL struct knetconfig passed down from user program
-NETBUF = NULL struct netbuf passed down from user program for %s
-STATE = The state of %s:%s ==> %s:%s prevents this operation
-MANY2ONE = Cannot enable %s:%s ==> %s:%s, secondary in use in another set
-RSTATE = The remote state of %s:%s ==> %s:%s prevents this operation
-BMPINUSE = The bitmap %s is already in use
-VOLINUSE = The volume %s is already in use
-MULTI = Cannot use direct I/O on first leg of multi hop config
-GROUP = Cannot add %s:%s ==> %s:%s to group %s
-GROUPMODE = Cannot reconfigure sync/async on members of a group
-NOTLOGGING = Cannot reconfig %s:%s to %s:%s, Must be in logging mode
-BMPRECONFIG = Bitmap reconfig failed %s:%s
-BMAPLOGGING = Cannot overwrite bitmap as the set %s:%s is not in logging mode
-QDISABLEPEND = Disable pending on diskq %s, try again later
-QNOTLOGGING = Cannot change disk queue %s, all associated sets must be in logging mode
-QALREADY = %s:%s ==> %s:%s already has a disk queue attached
-QNOQUEUE = Disk queue does not exist for set %s:%s ==> %s:%s
-QFLUSHING = Operation not possible. Disk queue %s is flushing, try again later
-QWRONGMODE = Disk queue operations on synchronous sets not allowed
-DISKQINUSE = Disk queue %s is already in use
-QNOADD = Unable to enable disk queue %s
-QINITFAIL = Initialization of disk queue %s failed
-QNOTEMPTY = Operation not possible, disk queue %s is not empty.
-QUEISREP = Disk queue %s operation not possible, set is in replicating mode
-QNORSYNC = Cannot reverse sync %s:%s <== %s:%s, set is in queuing mode
-SETNOTLOGGING = can not start sync as set %s:%s is not logging
-BITMAP2SMALL = Allocation of bitmap device %s failed, volume is too small
diff --git a/usr/src/lib/libunistat/common/sdbc/sdbc.err b/usr/src/lib/libunistat/common/sdbc/sdbc.err
deleted file mode 100644
index b7583c85ea..0000000000
--- a/usr/src/lib/libunistat/common/sdbc/sdbc.err
+++ /dev/null
@@ -1,60 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-DUMMY = SDBC Place holder until definitions checked in by coresw dev.
-OBSOLETE = Obsolete sdbc ioctl used
-DISABLE = Cache deconfig failed. Not initialized
-CLUSTER_SIZE = Get cluster size operation failed. Cache not initialized
-CLUSTER_DATA = Get cluster data operation failed. Cache not initialized
-GLMUL_SIZE = Get global size operation failed. Cache not initialized
-GLMUL_INFO = Get global info operation failed. Cache not initialized
-TOGGLE_FLUSH = Cache flushing mode is (mode %s)
-UNSUPPORTED = Unknown ioctl: unsupported (cmd %s)
-DISABLEFAIL = Cache not deconfigured
-PINNED = Pinned data on %s
-ACTIVERDC = Active RDC pair not closed
-UNREG = Could not unregister sdbc io module
-ALREADY = Cache enable failed. Already initialized.
-ENABLEFAIL = Cache enable failed.
-SIZE = Cache block size %s not supported.
-MAGIC = Mismatched versions of scmadm and sdbc module.
-NONETMEM = Insufficient memory for cache.
-NOIOBMEM = No memory for iobuf hooks.
-NOIOBCB = Missing iobuf driver callback.
-NOHANDLEMEM = No memory for buffer handles.
-MEMCONFIG = Cache memory initialzation error.
-FLUSHTHRD = Flush threads create failure.
-NOHASH = Cannot create hash table
-NOCB = Cannot allocate cache block structures
-NOCCTL = Cannot allocate cctl sync structures
-NOCD = Cannot allocate cache data structures
-NOMIRRORCD = Cannot allocate cache data structures for mirror areas
-NOSHAREDFILE = Cannot allocate shared file area
-NOSFNV = Cannot allocate shared file area in nvmem
-NOREFRESH = Unable to refresh host memory
-INVHOSTID = Hostid %s greater than maximum (%s)
-NOTSAME = Self host %s and mirror host %s cannot be the same
-NORMLOCKS = No RM locks configured
-GLDMAFAIL = Global information transfer failed
-MODELCONVERT = 64 bit conversion called on a 32 bit system
-ABUFS = Anonymous buffers currently allocated from sdbc
-NODEVENABLED = Device not enabled in cache
diff --git a/usr/src/lib/libunistat/common/solaris/solaris.err b/usr/src/lib/libunistat/common/solaris/solaris.err
deleted file mode 100644
index 41b6ab6a00..0000000000
--- a/usr/src/lib/libunistat/common/solaris/solaris.err
+++ /dev/null
@@ -1,173 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-PERM = Not super-user
-NOENT = No such file or directory
-SRCH = No such process
-INTR = interrupted system call
-IO = I/O error
-NXIO = No such device or address
-2BIG = Arg list too long
-NOEXEC = Exec format error
-BADF = Bad file number
-CHILD = No children
-AGAIN = Resource temporarily unavailable
-NOMEM = Not enough core
-ACCES = Permission denied
-FAULT = Bad address
-NOTBLK = Block device required
-BUSY = Mount device busy
-EXIST = File exists
-XDEV = Cross-device link
-NODEV = No such device
-NOTDIR = Not a directory
-ISDIR = Is a directory
-INVAL = Invalid argument
-NFILE = File table overflow
-MFILE = Too many open files
-NOTTY = Inappropriate ioctl for device
-TXTBSY = Text file busy
-FBIG = File too large
-NOSPC = No space left on device
-SPIPE = Illegal seek
-ROFS = Read only file system
-MLINK = Too many links
-PIPE = Broken pipe
-DOM = Math arg out of domain of func
-RANGE = Math result not representable
-NOMSG = No message of desired type
-IDRM = Identifier removed
-CHRNG = Channel number out of range
-L2NSYNC = Level 2 not synchronized
-L3HLT = Level 3 halted
-L3RST = Level 3 reset
-LNRNG = Link number out of range
-UNATCH = Protocol driver not attached
-NOCSI = No CSI structure available
-L2HLT = Level 2 halted
-DEADLK = Deadlock condition.
-NOLCK = No record locks available.
-CANCELED = Operation canceled
-NOTSUP = Operation not supported
-DQUOT = Disc quota exceeded
-BADE = invalid exchange
-BADR = invalid request descriptor
-XFULL = exchange full
-NOANO = no anode
-BADRQC = invalid request code
-BADSLT = invalid slot
-DEADLOCK = file locking deadlock error
-BFONT = bad font file fmt
-UNUSED58 = not defined
-UNUSED59 = not defined
-NOSTR = Device not a stream
-NODATA = no data (for no delay io)
-TIME = timer expired
-NOSR = out of streams resources
-NONET = Machine is not on the network
-NOPKG = Package not installed
-REMOTE = The object is remote
-NOLINK = the link has been severed
-ADV = advertise error
-SRMNT = srmount error
-COMM = Communication error on send
-PROTO = Protocol error
-UNISED72 = undefined
-UNISED73 = undefined
-MULTIHOP = multihop attempted
-UNISED75 = undefined
-UNISED76 = undefined
-BADMSG = trying to read unreadable message
-NAMETOOLONG = path name is too long
-OVERFLOW = value too large to be stored in data type
-NOTUNIQ = given log. name not unique
-BADFD = f.d. invalid for this operation
-REMCHG = Remote address changed
-LIBACC = Can't access a needed shared lib.
-LIBBAD = Accessing a corrupted shared lib.
-LIBSCN = .lib section in a.out corrupted.
-LIBMAX = Attempting to link in too many libs.
-LIBEXEC = Attempting to exec a shared library.
-ILSEQ = Illegal byte sequence.
-NOSYS = Unsupported file system operation
-LOOP = Symbolic link loop
-RESTART = Restartable system call
-STRPIPE = if pipe/FIFO, don't sleep in stream head
-NOTEMPTY = directory not empty
-USERS = Too many users (for UFS)
-NOTSOCK = Socket operation on non-socket
-DESTADDRREQ = Destination address required
-MSGSIZE = Message too long
-PROTOTYPE = Protocol wrong type for socket
-NOPROTOOPT = Protocol not available
-UNUSED100 = undefined
-UNUSED101 = undefined
-UNUSED102 = undefined
-UNUSED103 = undefined
-UNUSED104 = undefined
-UNUSED105 = undefined
-UNUSED106 = undefined
-UNUSED107 = undefined
-UNUSED108 = undefined
-UNUSED109 = undefined
-UNUSED110 = undefined
-UNUSED111 = undefined
-UNUSED112 = undefined
-UNUSED113 = undefined
-UNUSED114 = undefined
-UNUSED115 = undefined
-UNUSED116 = undefined
-UNUSED117 = undefined
-UNUSED118 = undefined
-UNUSED119 = undefined
-PROTONOSUPPORT = Protocol not supported
-SOCKTNOSUPPORT = Socket type not supported
-OPNOTSUPP = Operation not supported on socket
-PFNOSUPPORT = Protocol family not supported
-AFNOSUPPORT = Address family not supported by protocol family
-ADDRINUSE = Address already in use
-ADDRNOTAVAIL = Can't assign requested address operational errors
-NETDOWN = Network is down
-NETUNREACH = Network is unreachable
-NETRESET = Network dropped connection because of reset
-CONNABORTED = Software caused connection abort
-CONNRESET = Connection reset by peer
-NOBUFS = No buffer space available
-ISCONN = Socket is already connected
-NOTCONN = Socket is not connected
-XENIX135 = XENIX 135
-XENIX136 = XENIX 136
-XENIX137 = XENIX 137
-XENIX138 = XENIX 138
-XENIX139 = XENIX 139
-XENIX140 = XENIX 140
-XENIX141 = XENIX 141
-XENIX142 = XENIX 142
-SHUTDOWN = Can't send after socket shutdown
-TOOMANYREFS = Too many references: can't splice
-TIMEDOUT = Connection timed out
-CONNREFUSED = Connection refused
-HOSTDOWN = Host is down
-HOSTUNREACH = No route to host
-ALREADY = operation already in progress
-INPROGRESS = operation now in progress
-STALE = Stale NFS file handle
diff --git a/usr/src/lib/libunistat/common/spcs/spcs.err b/usr/src/lib/libunistat/common/spcs/spcs.err
deleted file mode 100644
index 44f526a795..0000000000
--- a/usr/src/lib/libunistat/common/spcs/spcs.err
+++ /dev/null
@@ -1,39 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# TODO: In order to put %s in these, since most are "internal errors" where a
-# direct Throw() or ThrowNew() is being done, need to use unistat and
-# call spcs_s_exception instead.
-OVERFLOW = status codes and/or supporting information lost
-BADHANDLE = The handle presented for access is not valid
-ACCESS = Unable to grant access
-INTERNAL = An internal error happened
-INUSE = The handle is already in use
-NODRIVER = The referenced SPCS driver could not be loaded:
-VERSION = Expected version not found, got libspcs.jar version:
-UNEXPECTED = The libspcs.jar version does not match the libspcs.so version
-WRONGMOD = Handle presented belongs to some other SPCS module
-# BUG: there is a weird bug, probably in errgen, that deletes the "i" from
-# required in this message when creating the java resource file!
-NEEDROOT = Root privilege required for libspcs access
-# developer test status: will never appear to a customer
-ASYNCTEST = Test of asynch status output@@
diff --git a/usr/src/lib/libunistat/common/spcs_errors.stub b/usr/src/lib/libunistat/common/spcs_errors.stub
deleted file mode 100644
index 19d5e814d4..0000000000
--- a/usr/src/lib/libunistat/common/spcs_errors.stub
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
-*/
-/*
- * The SPCS subsystem numbers
- * TODO: derive the static finals in Spcs.java from these or visa versa!
- */
-
-#define SPCS_SOLARIS 0
-#define SPCS_SPCS 1
-#define SPCS_DSW 2
-#define SPCS_SV 3
-#define SPCS_RDC 4
-#define SPCS_SDBC 5
-#define SPCS_MAX_SUBSYSTEM 5
diff --git a/usr/src/lib/libunistat/common/spcs_etext.stub b/usr/src/lib/libunistat/common/spcs_etext.stub
deleted file mode 100644
index c37e5599ba..0000000000
--- a/usr/src/lib/libunistat/common/spcs_etext.stub
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
-*/
-static char **SPCS_S_MSG[] = {
- SPCS_MSG_SOLARIS,
- SPCS_MSG_SPCS,
- SPCS_MSG_DSW,
- SPCS_MSG_SV,
- SPCS_MSG_RDC,
- SPCS_MSG_SDBC
-};
-static int SPCS_S_MSGLEN[] = {
- SPCS_MSGLEN_SOLARIS,
- SPCS_MSGLEN_SPCS,
- SPCS_MSGLEN_DSW,
- SPCS_MSGLEN_SV,
- SPCS_MSGLEN_RDC,
- SPCS_MSGLEN_SDBC
-};
diff --git a/usr/src/lib/libunistat/common/spcs_etrinkets.stub b/usr/src/lib/libunistat/common/spcs_etrinkets.stub
deleted file mode 100644
index 04889cd61b..0000000000
--- a/usr/src/lib/libunistat/common/spcs_etrinkets.stub
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-static char **SPCS_S_TRNK[] = {
- SPCS_TRNK_SOLARIS,
- SPCS_TRNK_SPCS,
- SPCS_TRNK_DSW,
- SPCS_TRNK_SV,
- SPCS_TRNK_RDC,
- SPCS_TRNK_SDBC
-};
-static int SPCS_S_TRNKLEN[] = {
- SPCS_TRNKLEN_SOLARIS,
- SPCS_TRNKLEN_SPCS,
- SPCS_TRNKLEN_DSW,
- SPCS_TRNKLEN_SV,
- SPCS_TRNKLEN_RDC,
- SPCS_TRNKLEN_SDBC
-};
-static char *SPCS_S_EXC_PATH[] = {
- "com/sun/esm/library/spcs/SolarisException",
- "com/sun/esm/library/spcs/SpcsException",
- "com/sun/esm/library/spcs/dsw/DswException",
- "com/sun/esm/library/spcs/sv/SvException",
- "com/sun/esm/library/spcs/rdc/RdcException",
- "com/sun/esm/library/spcs/sdbc/SdbcException"
-};
diff --git a/usr/src/lib/libunistat/common/spcs_log.c b/usr/src/lib/libunistat/common/spcs_log.c
deleted file mode 100644
index 476529c11f..0000000000
--- a/usr/src/lib/libunistat/common/spcs_log.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <values.h>
-#include <locale.h>
-#include <sys/stat.h>
-#include <strings.h>
-#include <stdarg.h>
-#include <sys/param.h>
-#include <sys/nsctl/nsctl.h>
-
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_u.h>
-#include <sys/unistat/spcs_errors.h>
-
-#define MAX_SESSION_LOG (10 * 1024 * 1024) /* allowable log file size */
-
-static char sessionlog[] = "/var/adm/ds.log";
-static char sessionlog_bak[] = "/var/adm/ds.log.bak";
-
-static char *spcstime();
-
-void
-spcs_log(const char *product, spcs_s_info_t *status, const char *format, ...)
-{
- struct stat st;
- FILE *fp = NULL;
- struct flock lk;
- va_list ap;
-
- bzero(&lk, sizeof (lk));
-
- /*
- * check the file size, if > than MAX_SESSION_LOG bytes make a .bak
- * and truncate
- */
- if (stat(sessionlog, &st) == 0) {
- if (st.st_size > MAX_SESSION_LOG) {
- rename(sessionlog, sessionlog_bak);
- }
- }
-
- va_start(ap, format);
- if ((fp = fopen(sessionlog, "a")) == (FILE *)NULL)
- goto fail;
- lk.l_type = F_WRLCK;
- lk.l_whence = SEEK_SET;
- lk.l_start = (off_t)0;
- lk.l_len = (off_t)0;
-
- if (fcntl(fileno(fp), F_SETLKW, &lk) < 0)
- goto fail;
-
-
- fprintf(fp, "%s %s: ", spcstime(), product);
- (void) vfprintf(fp, format, ap);
- fputs("\n", fp);
- if (status)
- spcs_s_report(*status, fp);
-
- fflush(fp);
-
- lk.l_type = F_UNLCK;
-
- (void) fcntl(fileno(fp), F_SETLKW, &lk);
-
-fail:
- if (fp)
- fclose(fp);
- va_end(ap);
-}
-
-/*
- * spcstime(): gets current time
- */
-static char *
-spcstime()
-{
- static char timeptr[20];
- time_t tnow;
-
- tnow = time((time_t *)0);
- cftime(timeptr, "%b %d %T", &tnow);
- return (timeptr);
-}
diff --git a/usr/src/lib/libunistat/common/spcs_s_u.c b/usr/src/lib/libunistat/common/spcs_s_u.c
deleted file mode 100644
index f5f946b31b..0000000000
--- a/usr/src/lib/libunistat/common/spcs_s_u.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-/*
- * The SPCS status support user utilities
- * See spcs_s_u.h and the docs subdirectory for functional spec
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <locale.h>
-#include <libintl.h>
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_u.h>
-#include <sys/unistat/spcs_s_impl.h>
-#include <sys/unistat/spcs_errors.h>
-#include <sys/unistat/spcs_etext.h>
-#include <sys/unistat/spcs_etrinkets.h>
-#include <sys/unistat/spcs_dtrinkets.h>
-
-/*
- * Initialize ioctl status storage to "remove" any old status present
- */
-
-void
-spcs_s_uinit(spcs_s_info_t ustatus)
-{
- spcs_s_pinfo_t *p = (spcs_s_pinfo_t *)ustatus;
- p->major = SPCS_S_MAJOR_REV;
- p->minor = SPCS_S_MINOR_REV;
- p->icount = 0;
- p->scount = 0;
- p->tcount = 0;
-}
-
-/*
- * Create and initialize local status. Call this prior to invoking
- * an ioctl.
- */
-
-spcs_s_info_t
-spcs_s_ucreate()
-{
- static int need_to_bind = 1;
- spcs_s_pinfo_t *ustatus;
-
- if (need_to_bind) {
- (void) setlocale(LC_ALL, "");
- (void) bindtextdomain("unistat", LIBUNISTAT_LOCALE);
- need_to_bind = 0;
- };
-
- ustatus = (spcs_s_pinfo_t *)malloc(sizeof (spcs_s_pinfo_t));
- spcs_s_uinit((spcs_s_info_t)ustatus);
-
- return ((spcs_s_info_t)ustatus);
-}
-
-/*
- * Return the idata index of the last status code in the array (i.e.
- * the "youngest" code present). The assumption is that the caller has
- * checked to see that pcount is nonzero.
- */
-
-ISSTATIC int
-last_code_idx(spcs_s_pinfo_t *p)
-{
- int last = 0;
- int idx = 0;
-
- while (idx < p->icount) {
- last = idx;
- idx += p->idata[idx].f.sup_count + 1;
- }
- return (last);
-}
-
-/*
- * Return a string with the module label and error message text or NULL
- * if none left
- */
-
-char *
-spcs_s_string(spcs_s_info_t ustatus, char *msg)
-{
- spcs_s_pinfo_t *p = (spcs_s_pinfo_t *)ustatus;
- int idx;
- int sup;
- int s;
- char *format;
- char *sp[SPCS_S_MAXSUPP];
- char mtemp[SPCS_S_MAXLINE];
-
- if (p->icount > 0) {
- idx = last_code_idx(p);
- strcpy(msg, module_names[p->idata[idx].f.module]);
- strcat(msg, ": ");
- sup = p->idata[idx].f.sup_count;
-
- if (p->idata[idx].f.module)
- /*
- * The gettext formal parameter is a const char*
- * I guess the gettext creator couldn't imagine
- * needing a variable string. If there is an underlying
- * routine that can be called it should be used.
- * otherwise there will be a compiler warning about this
- * line FOREVER (TS).
- */
- format = (char *)dgettext("unistat",
- SPCS_S_MSG[p->idata[idx].f.module]
- [p->idata[idx].f.code]);
-
- else
- format = strerror(p->idata[idx].f.code);
-
- /*
- * step across the status code to the first supplemental data
- * descriptor.
- */
-
- idx += 1;
-
- /*
- * Initialize the array with empty string pointers so we don't
- * seg fault if there are actually fewer values than "%s"
- * format descriptors.
- */
- for (s = 0; s < SPCS_S_MAXSUPP; s++)
- sp[s] = "";
-
- /*
- * Walk through the supplemental value descriptors and build
- * an array of string pointers.
- */
-
- for (s = 0; s < sup; s++) {
- sp[s] = (char *)(p->sdata + p->idata[idx+s].su.offset);
- }
-
- /*
- * Now format the message. The unused string pointers will be
- * ignored.
- * NOTE: Any change to SPCS_S_MAXSUPP requires a change to
- * this sprintf.
- */
-
- sprintf(mtemp, format, sp[0], sp[1], sp[2], sp[3], sp[4], sp[5],
- sp[6], sp[7]);
-
- /* remove the code and its supplemental info */
-
- p->icount -= (sup + 1);
-
- return (strcat(msg, mtemp));
- } else
- return (NULL);
-}
-
-/*
- * Write status info
- */
-
-void
-spcs_s_report(spcs_s_info_t ustatus, FILE *fd)
-{
- spcs_s_pinfo_t *p = (spcs_s_pinfo_t *)ustatus;
- short saved_count = p->icount;
- char msg[SPCS_S_MAXTEXT];
- char *sp;
- char *se;
- int first_time = 1;
-
- do {
- if (sp = spcs_s_string(ustatus, msg))
- fprintf(fd, "%s\n", sp);
- else if (first_time && (errno > 0)) {
- /*
- * This covers the case where Solaris aborted the
- * operation or the ioctl service code got an EFAULT
- * or something from copyin or couldn't allocate the
- * kernel status structure. If errno > 0 but not a
- * valid Solaris error code the extended error is
- * decoded and printed.
- */
- se = strerror(errno);
- if (se)
- fprintf(fd, "%s\n", se);
- else {
- spcs_s_udata_t spcs_errno;
-
- spcs_errno.i = errno;
- fprintf(fd, "%s: %s\n",
- module_names[spcs_errno.f.module],
- dgettext("unistat",
- SPCS_S_MSG[spcs_errno.f.module]
- [spcs_errno.f.code]));
-
- }
- }
- first_time = 0;
- } while (sp);
-
- p->icount = saved_count;
-}
-
-/*ARGSUSED*/
-void
-spcs_s_exception(spcs_s_info_t ustatus, void *env)
-{
-}
-
-/*
- * Release (free) ioctl status storage.
- */
-
-void
-spcs_s_ufree(spcs_s_info_t *ustatus_a)
-{
- free((void *)*ustatus_a);
- *ustatus_a = NULL;
-}
diff --git a/usr/src/lib/libunistat/common/sv/sv.err b/usr/src/lib/libunistat/common/sv/sv.err
deleted file mode 100644
index 87a782777c..0000000000
--- a/usr/src/lib/libunistat/common/sv/sv.err
+++ /dev/null
@@ -1,45 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-NOSLOTS = No more SVs available
-ARRBOUNDS = Array bounds check (min %s, max %s, got %s)
-DEVEXIST = Device already present in kernel
-NOSSTATE = Soft state alloc failed
-BADSSTATE = Soft state corrupted
-MKNOD = failed
-NODEV = Device not present in kernel configuration
-ENABLED = Device already enabled
-LOAD = Unable to load/hold underlying disk driver
-SDOPEN = Error from nsc_open()
-DISABLED = Device not enabled
-BUSY = Unable to disable device - device in use
-BADDEV = Bad dev_t in config structure
-STRATEGY = Recursive strategy functions
-GENERIC = Libspcs detected a nonspecific SV error
-STAT = Error from stat()
-KERNEL = User access to this device is not allowed by StorageTek kernel software
-AMODE = Illegal access mode
-GUARDVER = Incompatible guard magic or version number
-LOOKUP = Unable to translate pathname to major/minor number
-NOGCLIENT = Unable to match guard client module to internal module id
-GUSER = Unable to create kernel only guard, device already user enabled
-LYROPEN = Error from layered driver open
diff --git a/usr/src/lib/libunistat/i386/Makefile b/usr/src/lib/libunistat/i386/Makefile
deleted file mode 100644
index 0c2cdfaf46..0000000000
--- a/usr/src/lib/libunistat/i386/Makefile
+++ /dev/null
@@ -1,35 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# lib/libunistat/i386/Makefile
-
-include ../Makefile.com
-
-.KEEP_STATE:
-
-all: $(LIBS)
-
-install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTARLINK)
-
-lint:
-lintinter:
diff --git a/usr/src/lib/libunistat/sparc/Makefile b/usr/src/lib/libunistat/sparc/Makefile
deleted file mode 100644
index 50b8adbfd8..0000000000
--- a/usr/src/lib/libunistat/sparc/Makefile
+++ /dev/null
@@ -1,35 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# lib/libunistat/sparc/Makefile
-
-include ../Makefile.com
-
-.KEEP_STATE:
-
-all: $(LIBS)
-
-install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTARLINK)
-lint:
-lintinter:
-
diff --git a/usr/src/man/man1m/Makefile b/usr/src/man/man1m/Makefile
index f83b395683..625ae224d4 100644
--- a/usr/src/man/man1m/Makefile
+++ b/usr/src/man/man1m/Makefile
@@ -112,11 +112,6 @@ _MANFILES= 6to4relay.1m \
dns-sd.1m \
domainname.1m \
drvconfig.1m \
- dsbitmap.1m \
- dscfg.1m \
- dscfgadm.1m \
- dscfglockd.1m \
- dsstat.1m \
dtrace.1m \
dumpadm.1m \
editmap.1m \
@@ -180,9 +175,6 @@ _MANFILES= 6to4relay.1m \
if_mpadm.1m \
ifconfig.1m \
ifparse.1m \
- iiadm.1m \
- iicpbmp.1m \
- iicpshd.1m \
ikeadm.1m \
ikecert.1m \
in.chargend.1m \
@@ -336,7 +328,6 @@ _MANFILES= 6to4relay.1m \
nfsmapid.1m \
nfsstat.1m \
nlsadmin.1m \
- nscadm.1m \
nscd.1m \
nwamd.1m \
passmgmt.1m \
@@ -434,7 +425,6 @@ _MANFILES= 6to4relay.1m \
savecore.1m \
sbdadm.1m \
scadm.1m \
- scmadm.1m \
sdpadm.1m \
sendmail.1m \
setuname.1m \
@@ -452,9 +442,6 @@ _MANFILES= 6to4relay.1m \
smbios.1m \
smbstat.1m \
smrsh.1m \
- sndradm.1m \
- sndrd.1m \
- sndrsyncd.1m \
snoop.1m \
soconfig.1m \
sppptun.1m \
@@ -468,7 +455,6 @@ _MANFILES= 6to4relay.1m \
sttydefs.1m \
su.1m \
sulogin.1m \
- svadm.1m \
svc.configd.1m \
svc.ipfd.1m \
svc.startd.1m \
diff --git a/usr/src/man/man1m/dsbitmap.1m b/usr/src/man/man1m/dsbitmap.1m
deleted file mode 100644
index eac1e0d6a7..0000000000
--- a/usr/src/man/man1m/dsbitmap.1m
+++ /dev/null
@@ -1,178 +0,0 @@
-'\" te
-.\" Copyright (c) 2007, Sun Microsystems, Inc. All rights reserved.
-.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
-.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
-.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH DSBITMAP 1M "Oct 2, 2007"
-.SH NAME
-dsbitmap \- size Availability Suite bitmap volumes
-.SH SYNOPSIS
-.LP
-.nf
-\fBdsbitmap\fR \fB-h\fR
-.fi
-
-.LP
-.nf
-\fBdsbitmap\fR \fB-p\fR \fIdata_volume\fR [\fIbitmap_volume\fR]
-.fi
-
-.LP
-.nf
-\fBdsbitmap\fR \fB-r\fR \fIdata_volume\fR [\fIbitmap_volume\fR]
-.fi
-
-.SH DESCRIPTION
-.sp
-.LP
-The \fBdsbitmap\fR command calculates the size of the Availability Suite bitmap
-volume required for use with the specified data volume.
-.SH OPTIONS
-.sp
-.LP
-The following options are supported:
-.sp
-.ne 2
-.na
-\fB\fB-h\fR\fR
-.ad
-.sp .6
-.RS 4n
-Prints the usage message for the \fBdsbitmap\fR command
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-p\fR \fB\fIdata_volume\fR\fR \fB[\fIbitmap_volume\fR]\fR\fR
-.ad
-.sp .6
-.RS 4n
-For the given \fIdata_volume\fR, \fBdsbitmap\fR calculates and display the
-required size for the associated Availability Suite Point in Time bitmap
-volume. The bitmap volume sizes for all possible Availability Suite Point in
-Time set configurations are displayed. These configurations include Independent
-shadow, Full size dependent shadow, and Compact dependent shadow. If the
-optional \fIbitmap_volume\fR argument is supplied, \fBdsbitmap\fR determines if
-this volume is large enough to be used as the bitmap volume for
-\fIdata_volume\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-r\fR \fB\fIdata_volume\fR\fR \fB[\fIbitmap_volume\fR]\fR\fR
-.ad
-.sp .6
-.RS 4n
-For the given \fIdata_volume\fR, \fBdsbitmap\fR calculates and displays the
-required size for the associated Availability Suite Remote Mirror bitmap
-volume. The bitmap volume sizes for all possible Availability Suite Remote
-Mirror set configurations are displayed. These configurations include Sync
-replication, Async replication with memory queue, disk queue and 32 bit
-refcount. If the optional \fIbitmap_volume\fR argument is supplied,
-\fBdsbitmap\fR determines if this volume is large enough to be used as the
-bitmap volume for \fIdata_volume\fR.
-.RE
-
-.SH USAGE
-.sp
-.LP
-\fBdsbitmap\fR is typically used by the system administrator during the initial
-stages of configuring Sun StorageTek Availability Suite software in order to
-determine the required bitmap volume sizes, and then to check if the bitmap
-volumes that have been created are suitable.
-.SH EXIT STATUS
-.sp
-.LP
-The following exit values are returned:
-.sp
-.ne 2
-.na
-\fB\fB0\fR\fR
-.ad
-.RS 13n
-Successful completion. If the name of a bitmap volume was specified, that
-volume is sufficiently large for all potential uses.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB1\fR\fR
-.ad
-.RS 13n
-An error occurred.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB2\fR\fR
-.ad
-.RS 13n
-An invalid option was supplied on the command line.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB3\fR\fR
-.ad
-.RS 13n
-The specified bitmap volume is not large enough to be used as an Availability
-Suite Remote Mirror bitmap for an asynchronous set with a disk queue, but is
-large enough to be used for all other Remote Mirror set configurations.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB4\fR\fR
-.ad
-.RS 13n
-The specified bitmap volume is not large enough to be used as an Availability
-Suite Remote Mirror bitmap for any Remote Mirror set configuration.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB5\fR\fR
-.ad
-.RS 13n
-The specified bitmap volume is not large enough to be used as an Availability
-Suite Remote Mirror bitmap for any Remote Mirror set configuration.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB6\fR\fR
-.ad
-.RS 13n
-The specified bitmap volume is not large enough to be used as an Availability
-Suite Point in Time bitmap for a compact dependent shadow, but is large enough
-to be used for all other Point in Time set configurations.
-.RE
-
-.SH ATTRIBUTES
-.sp
-.LP
-See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
-.TS
-box;
-c | c
-l | l .
-ATTRIBUTE TYPE ATTRIBUTE VALUE
-_
-Interface Stability Evolving
-.TE
-
-.SH SEE ALSO
-.sp
-.LP
-\fBiiadm\fR(1M), \fBsndradm\fR(1M), \fBattributes\fR(5)
diff --git a/usr/src/man/man1m/dscfg.1m b/usr/src/man/man1m/dscfg.1m
deleted file mode 100644
index 1b7bc165d9..0000000000
--- a/usr/src/man/man1m/dscfg.1m
+++ /dev/null
@@ -1,310 +0,0 @@
-'\" te
-.\" Copyright (c) 2007, Sun Microsystems, Inc. All rights reserved.
-.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
-.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
-.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH DSCFG 1M "Oct 2, 2007"
-.SH NAME
-dscfg \- configuration tool for Sun StorageTek Availability Suite software
-.SH SYNOPSIS
-.LP
-.nf
-\fBdscfg\fR
-.fi
-
-.LP
-.nf
-\fBdscfg\fR \fB-L\fR
-.fi
-
-.LP
-.nf
-\fBdscfg\fR \fB-h\fR
-.fi
-
-.LP
-.nf
-\fBdscfg\fR [\fB-C\fR \fIgroup\fR]
-.fi
-
-.LP
-.nf
-\fBdscfg\fR [\fB-C\fR \fIgroup\fR] \fB-i\fR [\fB-p\fR \fIparser_config_file\fR]
-.fi
-
-.LP
-.nf
-\fBdscfg\fR [\fB-C\fR \fIgroup\fR] \fB-a\fR \fIconfig_file\fR
-.fi
-
-.LP
-.nf
-\fBdscfg\fR [\fB-C\fR \fIgroup\fR] [\fB-l\fR]
-.fi
-
-.LP
-.nf
-\fBdscfg\fR [\fB-C\fR \fIgroup\fR] [\fB-l\fR] \fB-s\fR \fIconfig_location\fR
-.fi
-
-.LP
-.nf
-\fBdscfg\fR \fB-D\fR \fIdgname\fR
-.fi
-
-.SH DESCRIPTION
-.sp
-.LP
-The \fBdscfg\fR command controls the Availability Suite configuration by
-providing facilities to initialize, list, format, restore the configuration
-database.
-.SH OPTIONS
-.sp
-.LP
-If no options are specified, \fBdscfg\fR displays the current local
-configuration location. The \fBdscfg\fR command supports the following options:
-.sp
-.ne 2
-.na
-\fB\fB-L\fR\fR
-.ad
-.sp .6
-.RS 4n
-Displays the status of the lock controlling access to the configuration
-database. If the configuration database is locked, the type of lock (read or
-write) is displayed along with the process id of the process that holds the
-lock.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-h\fR\fR
-.ad
-.sp .6
-.RS 4n
-Displays the usage message for the \fBdscfg\fR command.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-i\fR\fR
-.ad
-.sp .6
-.RS 4n
-Initializes the configuration database. As it deletes previous or current
-configuration information, this option prompts you to confirm the deletion
-before proceeding.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-p\fR \fIparser_config_file\fR\fR
-.ad
-.sp .6
-.RS 4n
-When used with the \fB-i\fR option, \fBdscfg\fR loads the parser configuration
-file into the persistent configuration, it reformats the configuration
-database.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-a\fR \fIconfig_file\fR\fR
-.ad
-.sp .6
-.RS 4n
-Restore the specified \fIconfig_file\fR into the configuration. This option
-does not do any error checking of the file. Use of this option invalidates the
-configuration file.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-l\fR\fR
-.ad
-.sp .6
-.RS 4n
-Lists the contents of current configuration database in a format that is
-suitable for the \fB-a\fR option. When used in combination with the \fB-s\fR
-option, it displays the contents stored in the location passed to the \fB-s\fR
-option, but does not set the configuration location.
-.RE
-
-.sp
-.LP
-The options below are for Sun Cluster-configured systems only. \fIgroup\fR can
-be either Sun Cluster device group or as '-' as local devices.
-.sp
-.ne 2
-.na
-\fB\fB-C\fR \fIgroup\fR\fR
-.ad
-.sp .6
-.RS 4n
-Display the location of cluster configuration database.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-C\fR\ \fIgroup\fR\ \fB-i\fR\fR
-.ad
-.sp .6
-.RS 4n
-Initializes the configuration database entries that only associated with group
-specified. As it deletes previous or current configuration information, this
-options prompts you to confirm the deletion before proceeding.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-C\fR\ \fIgroup\fR\ \fB-p\fR\ \fIparser_config_file\fR\fR
-.ad
-.sp .6
-.RS 4n
-When used with the \fB-i\fR option, \fBdscfg\fR loads the parser configuration
-file into the persistent configuration, it reformats the configuration database
-entries that only associated with group specified.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-C\fR \ \fIgroup\fR\ \fB-a\fR\ \fIconfig_file\fR\fR
-.ad
-.sp .6
-.RS 4n
-Restore the specified \fIconfig_file\fR into the configuration database entries
-that only associated with group specified. This option does not do any error
-checking of the file. Use of this option invalidates the configuration file.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-C\fR\ \fIgroup\fR\ \fB-l\fR\fR
-.ad
-.sp .6
-.RS 4n
-Lists the contents of current configuration database that is associated with
-resource group specified.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-C\fR \ \fIgroup\fR\ \fB-s\fR\ \fIconfig_file_location\fR\fR
-.ad
-.sp .6
-.RS 4n
-Specifies where the Sun Cluster configuration database resides, the location
-has to be DID device.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-D\fR \fIdevice_group\fR\fR
-.ad
-.sp .6
-.RS 4n
-Checks whether the specified \fIdevice_group\fR is known by Sun Cluster and
-whether it is available on this node. It displays a information that indicates
-the device group's status and return values are as follows,
-.sp
-(use echo $? to retrieve the return value):
-.sp
-.ne 2
-.na
-\fB\fB1\fR\fR
-.ad
-.RS 13n
-Device group is in Sun Cluster and is active on this node;
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB0\fR\fR
-.ad
-.RS 13n
-Device group is in Sun Cluster but active on another node;
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-1\fR\fR
-.ad
-.RS 13n
-Device group is not in Sun Cluster.
-.RE
-
-.RE
-
-.SH USAGE
-.sp
-.LP
-The \fBdscfg\fR command is typically run from other scripts, such as package
-installation scripts, and from \fBdscfgadm\fR(1M). It is not intended for
-general use. For uses of \fBdscfg\fR not covered by \fBdscfgadm\fR, please
-refer to the \fIAvailability Suite Troubleshooting Guide\fR.
-.SH FILES
-.sp
-.ne 2
-.na
-\fB\fB/etc/dscfg_format\fR\fR
-.ad
-.sp .6
-.RS 4n
-parser configuration file
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB/etc/dscfg_local\fR\fR
-.ad
-.sp .6
-.RS 4n
-configuration location for all entries with no cluster tags
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB/etc/dscfg_cluster\fR\fR
-.ad
-.sp .6
-.RS 4n
-reference file specifying the location of the Sun Cluster configuration
-database.
-.RE
-
-.SH ATTRIBUTES
-.sp
-.LP
-See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
-.TS
-box;
-c | c
-l | l .
-ATTRIBUTE TYPE ATTRIBUTE VALUE
-_
-Interface Stability Evolving
-.TE
-
-.SH SEE ALSO
-.sp
-.LP
-\fBdscfgadm\fR(1M), \fBiiadm\fR(1M), \fBscmadm\fR(1M), \fBsndradm\fR(1M),
-\fBsvadm\fR(1M), \fBds.log\fR(4), \fBattributes\fR(5)
diff --git a/usr/src/man/man1m/dscfgadm.1m b/usr/src/man/man1m/dscfgadm.1m
deleted file mode 100644
index 92b6df73a5..0000000000
--- a/usr/src/man/man1m/dscfgadm.1m
+++ /dev/null
@@ -1,159 +0,0 @@
-'\" te
-.\" Copyright (c) 2007, Sun Microsystems, Inc. All rights reserved.
-.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
-.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
-.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH DSCFGADM 1M "Oct 2, 2007"
-.SH NAME
-dscfgadm \- administration command for the Availability Suite configuration
-location and services
-.SH SYNOPSIS
-.LP
-.nf
-\fBdscfgadm\fR \fB-i\fR
-.fi
-
-.LP
-.nf
-\fBdscfgadm\fR \fB-e\fR [\fB-r\fR] [\fB-p\fR]
-.fi
-
-.LP
-.nf
-\fBdscfgadm\fR \fB-d\fR [\fB-r\fR]
-.fi
-
-.LP
-.nf
-\fBdscfgadm\fR \fB-s\fR
-.fi
-
-.SH DESCRIPTION
-.sp
-.LP
-The \fBdscfgadm\fR command controls the Availability Suite configuration
-location and services by providing facilities to set the configuration
-location, and to enable and disable the Availability Suite services.
-.SH OPTIONS
-.sp
-.LP
-If you do not specify any arguments to a \fBdscfgadm\fR command, the utility
-interactively steps you through setting the configuration location and starting
-the services. The configuration location is validated to ensure it meets
-criteria such as size and file type before it is initialized for use.
-.sp
-.LP
-The \fBdscfgadm\fR command supports the following options.
-.sp
-.ne 2
-.na
-\fB\fB-d\fR [\fB-r\fR ]\fR
-.ad
-.sp .6
-.RS 4n
-Disables the Availability Suite SMF services. This includes stopping daemons
-and suspending any Point-in-Time Copy or Remote Mirror sets that are currently
-enabled under the Availability Suite software. When executed with no additional
-options, the \fB-d\fR option disables all Availability Suite services. This
-setting is persistent across system boots.
-.sp
-.ne 2
-.na
-\fB\fB-r\fR\fR
-.ad
-.sp .6
-.RS 4n
-When passed to the \fB-d\fR or \fB-e\fR option, acts only on the Remote Mirror
-services.
-.RE
-
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-e\fR [\fB-r\fR ] [\fB-p\fR]\fR
-.ad
-.sp .6
-.RS 4n
-Enables the Availability Suite SMF services. This includes starting daemons and
-resuming any Point-in-Time Copy or Remote Mirror sets that have been previously
-configured under the Availability Suite software. When executed with no
-additional options, the \fB-e\fR option enables all Availability Suite
-services. This setting is persistent across system boots.
-.sp
-.ne 2
-.na
-\fB\fB-r\fR\fR
-.ad
-.sp .6
-.RS 4n
-When passed to the \fB-d\fR or \fB-e\fR option, acts only on the Remote Mirror
-services.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-p\fR\fR
-.ad
-.sp .6
-.RS 4n
-When passed to the \fB-e\fR option, enables only the Point-in-Time Copy
-service.
-.RE
-
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-i\fR\fR
-.ad
-.sp .6
-.RS 4n
-Displays information on the Availability Suite SMF services.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-s\fR\fR
-.ad
-.sp .6
-.RS 4n
-Allows you to set the location of the configuration database containing
-information specific to Sun Cluster configurations.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-x\fR\fR
-.ad
-.sp .6
-.RS 4n
-Displays verbose debugging information as the program is executing.
-.RE
-
-.SH ATTRIBUTES
-.sp
-.LP
-See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
-.TS
-box;
-c | c
-l | l .
-ATTRIBUTE TYPE ATTRIBUTE VALUE
-_
-Interface Stability Evolving
-.TE
-
-.SH SEE ALSO
-.sp
-.LP
-\fBdscfg\fR(1M), \fBiiadm\fR(1M), \fBscmadm\fR(1M), \fBsndradm\fR(1M),
-\fBsvadm\fR(1M), \fBattributes\fR(5)
diff --git a/usr/src/man/man1m/dscfglockd.1m b/usr/src/man/man1m/dscfglockd.1m
deleted file mode 100644
index e7830789aa..0000000000
--- a/usr/src/man/man1m/dscfglockd.1m
+++ /dev/null
@@ -1,100 +0,0 @@
-'\" te
-.\" Copyright (c) 2007, Sun Microsystems, Inc. All rights reserved.
-.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
-.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
-.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH DSCFGLOCKD 1M "Oct 2, 2007"
-.SH NAME
-dscfglockd \- Availability Suite Services lock daemon
-.SH SYNOPSIS
-.LP
-.nf
-\fB/usr/lib/dscfglockd\fR [\fB-e\fR \fIprogram\fR | \fB-f\fR \fIfile\fR]
-.fi
-
-.SH DESCRIPTION
-.sp
-.LP
-The \fBdscfglockd\fR daemon coordinates StorageTek configuration database lock
-requests between nodes within a cluster.
-.SH OPTIONS
-.sp
-.LP
-The \fBdscfglockd\fR supports the following options:
-.sp
-.ne 2
-.na
-\fB\fB-e\fR \fIprogram\fR\fR
-.ad
-.sp .6
-.RS 4n
-Executes the script and arguments in \fIprogram\fR. The executable and any
-arguments it needs must be supplied with suitable quoting as a single argument
-to this option. This argument is processed by \fBsh\fR(1).
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-f\fR \fIfile\fR\fR
-.ad
-.sp .6
-.RS 4n
-Reads the list of names for peer hosts from \fIfile\fR.
-.RE
-
-.sp
-.LP
-If no arguments are specified, \fBdscfglockd\fR acts as a local lock daemon,
-but coordinates lock requests with any other daemons that might contact the
-local host as part of their own configuration process.
-.SH EXIT STATUS
-.sp
-.ne 2
-.na
-\fB\fB0\fR\fR
-.ad
-.RS 13n
-Daemon started successfully.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB>0\fR\fR
-.ad
-.RS 13n
-Daemon failed to start.
-.RE
-
-.SH FILES
-.sp
-.ne 2
-.na
-\fB\fB/lib/svc/method/svc-scm\fR\fR
-.ad
-.sp .6
-.RS 4n
-Shell script for starting and stopping \fBdscfglockd\fR.
-.RE
-
-.SH ATTRIBUTES
-.sp
-.LP
-See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
-.TS
-box;
-c | c
-l | l .
-ATTRIBUTE TYPE ATTRIBUTE VALUE
-_
-Interface Stability Evolving
-.TE
-
-.SH SEE ALSO
-.sp
-.LP
-\fBsh\fR(1), \fBattributes\fR(5)
diff --git a/usr/src/man/man1m/dsstat.1m b/usr/src/man/man1m/dsstat.1m
deleted file mode 100644
index 16a8ba8ca9..0000000000
--- a/usr/src/man/man1m/dsstat.1m
+++ /dev/null
@@ -1,1127 +0,0 @@
-'\" te
-.\" Copyright (c) 2007, Sun Microsystems, Inc. All rights reserved.
-.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
-.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
-.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH DSSTAT 1M "Oct 2, 2007"
-.SH NAME
-dsstat \- report Sun StorageTek Availability Suite I/O statistics
-.SH SYNOPSIS
-.LP
-.nf
-\fBdsstat\fR \fB-m\fR \fImode\fR [\fB-r\fR \fIreport-options\fR] [\fB-d\fR \fIdisplay-options\fR]
- [\fB-s\fR \fIvolume-sets\fR] [\fB-f\fR | \fB-F\fR] [\fB-z\fR] [\fIinterval\fR [\fIcount\fR]]
-.fi
-
-.SH DESCRIPTION
-.sp
-.LP
-The \fBdsstat\fR command collects and reports I/O statistics for the Sun
-StorageTek Availability Suite products.
-.SH OPTIONS
-.sp
-.LP
-The \fBdsstat\fR supports the following options:
-.sp
-.ne 2
-.na
-\fB\fB-m\fR \fB\fImode\fR\fR\fR
-.ad
-.sp .6
-.RS 4n
-Specifies the mode(s) of operation. Valid modes are:
-.sp
-.ne 2
-.na
-\fB\fBcache\fR\fR
-.ad
-.sp .6
-.RS 4n
-Cache statistics
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBii\fR\fR
-.ad
-.sp .6
-.RS 4n
-Point-in-Time Copy statistics
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBsndr\fR\fR
-.ad
-.sp .6
-.RS 4n
-Remote Mirror statistics
-.RE
-
-To display statistics for multiple services simultaneously, use the \fB-m\fR
-switch to specify each of the modes required. For example:
-.sp
-.in +2
-.nf
-% \fBdsstat -m ii -m sndr\fR
-% \fBdsstat -m ii -m sndr -m cache\fR
-.fi
-.in -2
-.sp
-
-To determine which statistics are being reported from which service, use the
-\fIrole\fR field, described below. When cache statistics are requested as one
-of the multiple services, the \fBrkps\fR and \fBwkps\fR statistics is further
-divided into \fBcrkps\fR, \fBdrkps\fR, \fBcwkps\fR, and \fBdwkps\fR. If no
-\fB-m\fR switch is specified, then \fBdsstat\fR displays default statistics for
-all of the valid modes as described above. See "Field Descriptions," below for
-descriptions of these fields.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-r\fR \fB\fIreport-options\fR\fR\fR
-.ad
-.sp .6
-.RS 4n
-Specifies the volume components to be displayed. Each item is represented by a
-single character, and multiple items can be selected. The \fIreport-options\fR
-vary based on the mode(s) specified above. This option is not used for
-\fBcache\fR mode.
-.sp
-Valid \fIreport-options\fR for \fBii\fR mode are:
-.sp
-.ne 2
-.na
-\fB\fBm\fR\fR
-.ad
-.RS 13n
-Master volume statistics.
-.RS +4
-.TP
-.ie t \(bu
-.el o
-For the "report-options for ii mode": \fBm\fR, \fBs\fR, \fBb\fR, \fBo\fR
-.RE
-.RS +4
-.TP
-.ie t \(bu
-.el o
-For the "report-options for sndr mode": \fBb\fR, \fBn\fR
-.RE
-.RS +4
-.TP
-.ie t \(bu
-.el o
-For the "display-options for cache mode": \fBr\fR, \fBw\fR, \fBd\fR, \fBc\fR,
-\fBs\fR, \fBf\fR
-.RE
-.RS +4
-.TP
-.ie t \(bu
-.el o
-For the "display-options for ii mode": \fBr\fR, \fBw\fR, \fBt\fR, \fBs\fR,
-\fBp\fR, \fBf\fR
-.RE
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBs\fR\fR
-.ad
-.RS 13n
-Shadow volume statistics.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBb\fR\fR
-.ad
-.RS 13n
-Bitmap volume statistics.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBo\fR\fR
-.ad
-.RS 13n
-Overflow volume statistics, if attached.
-.RE
-
-Valid \fIreport-options\fR for \fBsndr\fR mode are:
-.sp
-.ne 2
-.na
-\fB\fBb\fR\fR
-.ad
-.RS 13n
-Bitmap volume statistics.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBn\fR\fR
-.ad
-.RS 13n
-Network volume statistics.
-.RE
-
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-d\fR \fIdisplay-options\fR\fR
-.ad
-.sp .6
-.RS 4n
-Specifies the statistics to be displayed. The types of statistics are
-represented by a single character; multiple types can be specified.
-.sp
-For \fBcache\fR mode, the valid \fIdisplay-options\fR are:
-.sp
-.ne 2
-.na
-\fB\fBr\fR\fR
-.ad
-.RS 13n
-Detailed read statistics.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBw\fR\fR
-.ad
-.RS 13n
-Detailed write statistics.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBs\fR\fR
-.ad
-.RS 13n
-Summary statistics.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBf\fR\fR
-.ad
-.RS 13n
-Cache behavior flags.
-.RE
-
-The following \fIdisplay-options\fR are available only for cache mode, they
-need to be combined with the mode options (\fB-m\fR)
-.sp
-.ne 2
-.na
-\fB\fBd\fR\fR
-.ad
-.RS 13n
-Destaged data statistics.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBc\fR\fR
-.ad
-.RS 13n
-Write cancellation statistics.
-.RE
-
-The default \fIdisplay-options\fR for \fBcache\fR are \fBsf\fR.
-.sp
-For \fBii\fR mode, the valid \fIdisplay-options\fR are:
-.sp
-.ne 2
-.na
-\fB\fBr\fR\fR
-.ad
-.sp .6
-.RS 4n
-Detailed read statistics.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBw\fR\fR
-.ad
-.sp .6
-.RS 4n
-Detailed write statistics.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBt\fR\fR
-.ad
-.sp .6
-.RS 4n
-Timing statistics.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBs\fR\fR
-.ad
-.sp .6
-.RS 4n
-Summary statistics.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBp\fR\fR
-.ad
-.sp .6
-.RS 4n
-Percentage of volume requiring sync.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBf\fR\fR
-.ad
-.sp .6
-.RS 4n
-Volume type/status flags.
-.RE
-
-The default \fIdisplay-options\fR for \fBii\fR are \fBspf\fR. For \fBsndr\fR
-mode, the valid \fIdisplay-options\fR are:
-.sp
-.ne 2
-.na
-\fB\fBr\fR\fR
-.ad
-.RS 13n
-Detailed read statistics.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBw\fR\fR
-.ad
-.RS 13n
-Detailed write statistics.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBt\fR\fR
-.ad
-.RS 13n
-Timing statistics.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBs\fR\fR
-.ad
-.RS 13n
-Summary statistics.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBp\fR\fR
-.ad
-.RS 13n
-Percentage of volume requiring sync.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBf\fR\fR
-.ad
-.RS 13n
-Volume type/status flags.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBq\fR\fR
-.ad
-.RS 13n
-Asynchronous queue statistics.
-.RE
-
-The following \fIdisplay-option\fR is only available for \fBsndr\fR mode, and
-needs to be combined with the mode options (\fB-m\fR).
-.sp
-.ne 2
-.na
-\fB\fBq\fR\fR
-.ad
-.RS 13n
-Asynchronous queue statistics.
-.RE
-
-The default \fIdisplay-options\fR for \fBsndr\fR are \fBspf\fR.
-.sp
-Specifying the summary \fIdisplay-option\fR causes \fBr\fR \fBw\fR \fBt\fR
-\fIdisplay-options\fR to be ignored.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-s\fR \fB\fIvolume-sets\fR\fR\fR
-.ad
-.RS 20n
-Filters the output to include only the specified \fIvolume-sets\fR, where
-\fIvolume-sets\fR is a comma-delimited list of volume names. When displaying
-Remote Mirror statistics, the name specified is compared to the Remote Mirror
-primary volume to determine if they match. Additionally, an Remote Mirror
-volume should be specified as \fI<host>\fR:\fI<volume>\fR where \fI<host>\fR is
-the primary or secondary host and \fI<volume>\fR is the volume name by which
-that host recognizes the volume set. When specifying multiple Remote Mirror
-volumes sets, be aware that each volume set specified is evaluated
-individually, using the rules above. When displaying Point-in-Time Copy
-statistics, the volume name specified is compared to the Point-in-Time Copy
-shadow volume to determine if they match.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-f\fR\fR
-.ad
-.RS 20n
-Output field headers at every reporting cycle.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-F\fR\fR
-.ad
-.RS 20n
-Output field headers once, when reporting begins.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-z\fR\fR
-.ad
-.RS 20n
-Suppress report lines that have zero values or no activity.
-.RE
-
-.SH OPERANDS
-.sp
-.LP
-The \fBdsstat\fR command line supports the following operands:
-.sp
-.ne 2
-.na
-\fB\fIinterval\fR\fR
-.ad
-.sp .6
-.RS 4n
-Specifies the \fIinterval\fR for each report, in seconds. If no \fIinterval\fR
-is specified, a single report with a one second \fIinterval\fR is output.
-.sp
-Due to the varying number of entries in a given set and the varying number of
-sets, header information might appear in the middle of a set being reported. To
-avoid this, use the \fB-f\fR or \fB-F\fR options to display the header
-information at the desired time.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fIcount\fR\fR
-.ad
-.sp .6
-.RS 4n
-Specifies the number of reports to generate. If no \fIcount\fR is specified,
-output continues until interrupted.
-.RE
-
-.SS "Field Descriptions"
-.sp
-.LP
-Unless otherwise specified, all fields are per-second averages based on the
-data collected during the specified \fIinterval\fR.
-.sp
-.ne 2
-.na
-\fB\fBname\fR\fR
-.ad
-.RS 13n
-Name of the entity being reported
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBt\fR\fR
-.ad
-.RS 13n
-Volume type
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBs\fR\fR
-.ad
-.RS 13n
-Volume status
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBr\fR\fR
-.ad
-.RS 13n
-Cache read behavior
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBw\fR\fR
-.ad
-.RS 13n
-Cache write behavior
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBpct\fR\fR
-.ad
-.RS 13n
-Percentage of volume requiring sync
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBrole\fR\fR
-.ad
-.RS 13n
-Role of the item being reported
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBtps\fR\fR
-.ad
-.RS 13n
-Total number of reads + writes
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBrtps\fR\fR
-.ad
-.RS 13n
-Number of reads
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBwtps\fR\fR
-.ad
-.RS 13n
-Number of writes
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBkps\fR\fR
-.ad
-.RS 13n
-Total kilobytes read + written
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBrkps\fR\fR
-.ad
-.RS 13n
-Kilobytes read
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBwkps\fR\fR
-.ad
-.RS 13n
-Kilobytes written
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBcrkps\fR\fR
-.ad
-.RS 13n
-Kilobytes read from cache
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBdrkps\fR\fR
-.ad
-.RS 13n
-Kilobytes read from disk
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBcwkps\fR\fR
-.ad
-.RS 13n
-Kilobytes written to cache
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBdwkps\fR\fR
-.ad
-.RS 13n
-Kilobytes written to disk
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBckps\fR\fR
-.ad
-.RS 13n
-Kilobytes transferred to or from cache
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBdkps\fR\fR
-.ad
-.RS 13n
-Kilobytes transferred to or from disk
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBsvt\fR\fR
-.ad
-.RS 13n
-Service time per operation
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBhit\fR\fR
-.ad
-.RS 13n
-Read hits during \fIinterval\fR
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBds/s\fR\fR
-.ad
-.RS 13n
-Kilobytes destaged from cache
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBcn/s\fR\fR
-.ad
-.RS 13n
-Number of write cancellations
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBq\fR\fR
-.ad
-.RS 13n
-Type of asynchronous queuing being used
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBqi\fR\fR
-.ad
-.RS 13n
-Number of items currently queued
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBqk\fR\fR
-.ad
-.RS 13n
-Kilobytes currently queued
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBqhwi\fR\fR
-.ad
-.RS 13n
-High water mark of queued items
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBqhwk\fR\fR
-.ad
-.RS 13n
-High water mark of queued kilobytes
-.RE
-
-.sp
-.LP
-The \fBname\fR field displays only the last 16 characters of the name.
-.sp
-.LP
-Valid cache behaviors for \fBcache\fR are:
-.sp
-.ne 2
-.na
-\fB\fBC\fR\fR
-.ad
-.RS 13n
-Cache reads/writes
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBD\fR\fR
-.ad
-.RS 13n
-Disk reads/writes
-.RE
-
-.sp
-.LP
-Valid volume types for \fBii\fR are:
-.sp
-.ne 2
-.na
-\fB\fBI\fR\fR
-.ad
-.RS 13n
-Independent shadow volume
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBD\fR\fR
-.ad
-.RS 13n
-Dependent shadow volume
-.RE
-
-.sp
-.LP
-Valid volume status for \fBii\fR is:
-.sp
-.ne 2
-.na
-\fB\fBC\fR\fR
-.ad
-.RS 13n
-Copy in progress
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-\fR\fR
-.ad
-.RS 13n
-No copy in progress
-.RE
-
-.sp
-.LP
-Valid volume types for \fBsndr\fR are:
-.sp
-.ne 2
-.na
-\fB\fBP\fR\fR
-.ad
-.RS 13n
-This is the primary host of this volume set
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBS\fR\fR
-.ad
-.RS 13n
-This is the secondary host of this volume set
-.RE
-
-.sp
-.LP
-Valid volume status for \fBsndr\fR is:
-.sp
-.ne 2
-.na
-\fB\fBL\fR\fR
-.ad
-.RS 13n
-Changes to this volume are being logged
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBQ\fR\fR
-.ad
-.RS 13n
-Volume are in queuing mode
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBR\fR\fR
-.ad
-.RS 13n
-Replicating changes to secondary
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBSY\fR\fR
-.ad
-.RS 13n
-Synchronization in progress. Sending data.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBRS\fR\fR
-.ad
-.RS 13n
-Reverse synchronization in progress. Receiving data.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBSN\fR\fR
-.ad
-.RS 13n
-Synchronization needed
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBRN\fR\fR
-.ad
-.RS 13n
-Reverse synchronization needed
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBVF\fR\fR
-.ad
-.RS 13n
-Volume failed
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBBF\fR\fR
-.ad
-.RS 13n
-Bitmap failed
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBQF\fR\fR
-.ad
-.RS 13n
-Queue failed
-.RE
-
-.sp
-.LP
-Valid queue types for \fBsndr\fR are:
-.sp
-.ne 2
-.na
-\fB\fBD\fR\fR
-.ad
-.RS 13n
-Disk-based queuing enabled
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBM\fR\fR
-.ad
-.RS 13n
-Memory-based queuing enabled
-.RE
-
-.sp
-.LP
-Volume roles for \fBsndr\fR are:
-.sp
-.ne 2
-.na
-\fB\fBnet\fR\fR
-.ad
-.RS 13n
-Network volume statistics
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBbmp\fR\fR
-.ad
-.RS 13n
-Bitmap volume statistics
-.RE
-
-.sp
-.LP
-Volume roles for \fBii\fR are:
-.sp
-.ne 2
-.na
-\fB\fBmst\fR\fR
-.ad
-.RS 13n
-Master volume statistics
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBshd\fR\fR
-.ad
-.RS 13n
-Shadow volume statistics
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBbmp\fR\fR
-.ad
-.RS 13n
-Bitmap volume statistics
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBovr\fR\fR
-.ad
-.RS 13n
-Overflow volume statistics
-.RE
-
-.SH EXAMPLES
-.LP
-\fBExample 1 \fRReport Cache Statistics
-.sp
-.LP
-The following example shows the display of Report Cache statistics, with
-detailed breakdowns of read and writes to cache/disk. Reports are generated at
-five second intervals. Reporting is limited to the set
-\fB/dev/rdsk/c1t1d0s0\fR.
-
-.sp
-.in +2
-.nf
- # dsstat -m cache -d rw -s /dev/rdsk/c1t1d0s0 5
-- read - - write -
-name ckps dkps hit ckps dkps hit
-dev/rdsk/c1t1d0s0 0 0 0.00 0 0 0.00
-dev/rdsk/c1t1d0s0 3 2396 0.13 983 763 100.00
-dev/rdsk/c1t1d0s0 2399 799 75.00 2815 2686 100.00
-dev/rdsk/c1t1d0s0 3200 800 80.00 2755 2908 100.00
-dev/rdsk/c1t1d0s0 3999 799 83.33 2809 2868 100.00
-dev/rdsk/c1t1d0s0 4800 800 85.71 2867 2931 100.00
-.fi
-.in -2
-
-.LP
-\fBExample 2 \fRReport Master, Shadow and Bitmap Statistics
-.sp
-.LP
-Report master, shadow and bitmap statistics for Point-in-Time Copy, using
-default output. Generate reports at two second intervals.
-
-.sp
-.in +2
-.nf
-# dsstat -m ii -r msb 2
-name t s pct role kps tps svt
-dev/rdsk/c0t1d0s5 I C 96.15 mst 19921 38 22
-dev/rdsk/c0t1d0s6 shd 9960 19 20
-dev/rdsk/c0t1d0s7 bmp 39 77 2
-dev/rdsk/c0t1d0s5 I C 94.24 mst 19623 38 22
-dev/rdsk/c0t1d0s6 shd 9939 19 20
-dev/rdsk/c0t1d0s7 bmp 39 77 2
-dev/rdsk/c0t1d0s5 I C 92.34 mst 19969 39 22
-dev/rdsk/c0t1d0s6 shd 9984 19 20
-dev/rdsk/c0t1d0s7 bmp 39 78 2
-.fi
-.in -2
-
-.LP
-\fBExample 3 \fRReport Network Statistics for Remote Mirror
-.sp
-.LP
-Report network statistics for Remote Mirror, using detailed read, write
-statistics. Report includes volume type/status flags and percentages. Generate
-reports at two second intervals. Limit reporting to the set
-\fB/dev/rdsk/c0t1d0s0\fR.
-
-.sp
-.in +2
-.nf
-# dsstat -m sndr -r n -d rwpf -s /dev/rdsk/c0t1d0s0 2
-name t s pct role rkps rtps wkps wtps
-dev/rdsk/c0t1d0s0 P L 100.00 sec 0 0 0 0
-dev/rdsk/c0t1d0s0 P SY 99.90 sec 0 0 288 9
-dev/rdsk/c0t1d0s0 P SY 97.90 sec 0 0 5296 165
-dev/rdsk/c0t1d0s0 P SY 95.81 sec 0 0 5184 161
-dev/rdsk/c0t1d0s0 P SY 93.81 sec 0 0 5280 164
-dev/rdsk/c0t1d0s0 P SY 91.71 sec 0 0 5198 162
-.fi
-.in -2
-
-.SH EXIT STATUS
-.sp
-.LP
-The following exit values are returned:
-.sp
-.ne 2
-.na
-\fB\fB0\fR\fR
-.ad
-.RS 13n
-Successful completion.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB1\fR\fR
-.ad
-.RS 13n
-Successful completion, no statistics to report.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB2\fR\fR
-.ad
-.RS 13n
-An invalid argument has been encountered.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB3\fR\fR
-.ad
-.RS 13n
-No memory is available to create \fBkstat\fR statistics.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB4\fR\fR
-.ad
-.RS 13n
-An unknown error has occurred.
-.RE
-
-.SH ATTRIBUTES
-.sp
-.LP
-See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
-.TS
-box;
-c | c
-l | l .
-ATTRIBUTE TYPE ATTRIBUTE VALUE
-_
-Interface Stability Evolving
-.TE
-
-.SH SEE ALSO
-.sp
-.LP
-\fBdscfg\fR(1M), \fBsvadm\fR(1M), \fBds.log\fR(4), \fBrdc.cf\fR(4),
-\fBattributes\fR(5)
diff --git a/usr/src/man/man1m/iiadm.1m b/usr/src/man/man1m/iiadm.1m
deleted file mode 100644
index 5f2fa3c015..0000000000
--- a/usr/src/man/man1m/iiadm.1m
+++ /dev/null
@@ -1,1016 +0,0 @@
-'\" te
-.\" Copyright (c) 2007, Sun Microsystems, Inc. All rights reserved.
-.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
-.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
-.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH IIADM 1M "Nov 26, 2017"
-.SH NAME
-iiadm \- command-line interface to control Sun StorageTek Availability Suite
-Point-in-Time Copy operations
-.SH SYNOPSIS
-.LP
-.nf
-\fBiiadm\fR \fB-e\fR {ind | shd} \fImaster_vol\fR \fIshadow_vol\fR \fIbitmap_vol\fR
-.fi
-
-.LP
-.nf
-\fBiiadm\fR \fB-ne\fR ind \fImaster_vol\fR \fIshadow_vol\fR \fIbitmap_vol\fR
-.fi
-
-.LP
-.nf
-\fBiiadm\fR [\fB-p\fR] [\fB-n\fR] {\fB-c\fR | \fB-u\fR} {s | m} \fIvolume_set\fR
-.fi
-
-.LP
-.nf
-\fBiiadm\fR [\fB-adDilR\fR] \fIvolume_set\fR
-.fi
-
-.LP
-.nf
-\fBiiadm\fR [\fB-p\fR] [\fB-n\fR] \fB-w\fR \fIvolume_set\fR
-.fi
-
-.LP
-.nf
-\fBiiadm\fR [\fB-hilLv\fR]
-.fi
-
-.LP
-.nf
-\fBiiadm\fR \fB-P\fR \fIdelay\fR \fIunits\fR \fIvolume_set\fR
-.fi
-
-.LP
-.nf
-\fBiiadm\fR \fB-P\fR \fIvolume_set\fR
-.fi
-
-.LP
-.nf
-\fBiiadm\fR \fB-A\fR \fIoverflow_vol\fR \fIvolume_set\fR
-.fi
-
-.LP
-.nf
-\fBiiadm\fR [\fB-OQ\fR] \fIoverflow_vol\fR
-.fi
-
-.LP
-.nf
-\fBiiadm\fR \fB-E\fR \fIvolume_set\fR
-.fi
-
-.LP
-.nf
-\fBiiadm\fR [\fB-IJ\fR] \fIvolume_set\fR \fIbitmap\fR
-.fi
-
-.LP
-.nf
-\fBiiadm\fR \fB-g\fR \fIgroup_name\fR [\fB-aAcdDeEilLmPRuw\fR]
-.fi
-
-.LP
-.nf
-\fBiiadm\fR [\fB-C\fR] \fIcluster_tag\fR [\fIoptions\fR]
-.fi
-
-.SH DESCRIPTION
-.LP
-Point-in-Time Copy software is a point-in-time snapshot feature of the Solaris
-operating system.
-.sp
-.LP
-A Point-in-Time Copy snapshot is an instantly-available, time-fixed, replicated
-view of a momentarily quiesced volume. Once a snapshot is taken, Point-in-Time
-Copy software allows immediate read/write access to both the master and shadow
-volume data.
-.sp
-.LP
-Point-in-Time Copy software tracks the differences between the master and
-shadow volumes (caused by writes) from the moment that the snapshot was
-established. This capability allows applications accessing the master volume's
-data to move forward in time independently of applications accessing the shadow
-volume's data, and vice-versa.
-.sp
-.LP
-The Point-in-Time Copy software's tracking of differences between the master
-and shadow volumes facilitates a fast resynchronization or a full copy at a
-later time. The volume resynchronization can occur from either shadow to master
-or master to shadow.
-.sp
-.LP
-Instantly after the point-in-time is (re-)established (either when the CLI
-prompt returns or the next shell script command is read), the master volume can
-be remounted or the applications using them can be resumed. Also, the shadow
-volume can be mounted and immediately accessed.
-.sp
-.LP
-The \fBiiadm\fR command line utility performs only one action per command
-invocation. Because of this, you cannot combine multiple options, except in
-combination with the following overall command modifiers:
-.RS +4
-.TP
-.ie t \(bu
-.el o
-If no action item is entered, \fBiiadm\fR displays the list of Point-in-Time
-Copy sets (non-suspended) currently configured. If more than one action item,
-or an incorrectly specified action item is entered, \fBiiadm\fR displays the
-specific error message to stderr, followed by a brief usage summary.
-.RE
-.RS +4
-.TP
-.ie t \(bu
-.el o
-For the Point-in-Time Copy options ENABLE (\fB-e\fR), COPY (\fB-c\fR) and
-UPDATE (\fB-u\fR), there are two associated shadow volume selection qualifiers,
-\fB{ind|dep}\fR, that are used to specify the type of Point-in-Time Copy volume
-set to create.
-.RE
-.sp
-.LP
-An independent (\fBind\fR) snapshot causes Point-in-Time Copy software to
-perform a full volume copy operation from the master to the shadow. When the
-copy completes, the shadow volume data is identical to the master volume data
-at the moment that it was established. Create an independent shadow if you
-require two physical copies of the data. An independent shadow volume must be
-the same size or greater than the size of the master volume. Sun recommends
-that the master and shadow volumes be the same size for environments where
-resynchronization from shadow to master is a consideration.
-.sp
-.LP
-A dependent (\fBdep\fR) snapshot causes Point-in-Time Copy software not to
-perform a full volume copy. The resulting shadow volume relies on the master
-volume for all unmodified data blocks, which are not copied until requested.
-Create a dependent shadow when you do not require two physical copies of the
-data. A dependent shadow volume can be either the same size or smaller than the
-master volume. A smaller shadow volume is called a \fBCompact Dependent Shadow
-Volume\fR, and is typically used when the amount of change that occurs to a
-Point-in-Time Copy volume set is small compared to the entire size of the
-master volume.
-.sp
-.LP
-The following syntax allows you to create an exportable independent shadow
-volume in a Sun Cluster environment:
-.sp
-.in +2
-.nf
-# iiadm -ne ind master shadow bitmap
-.fi
-.in -2
-.sp
-
-.sp
-.LP
-An issue arises when using a Compact Dependent Shadow Volume in that its size
-is established at the time that the Point-in-Time Copy volume set is enabled.
-If the amount of change to the entire volume set over the duration of its usage
-exceeds the space allocated for the shadow volume, the shadow volume is marked
-as out of space. It is possible to read from the shadow volume even after it is
-out of space, until a portion of the data for which there was no room is
-requested. Once that happens, the read fails and the shadow volume is marked
-offline.
-.sp
-.LP
-To address this issue, Point-in-Time Copy supports the ability to associate an
-\fBoverflow\fR volume to an existing Point-in-Time Copy dependent volume set.
-Thus, if the size of the Compact Dependent Shadow Volume is too small, or an
-unscheduled amount of change occurs to the volume set, changed data can be
-redirected to the associated overflow volume. To facilitate efficient usage of
-this overflow volume, it can be associated with multiple Point-in-Time Copy
-volume sets on an as-needed basis.
-.SS "Considerations"
-.LP
-Prior to invoking an Point-in-Time Copy \fBenable\fR, \fBcopy\fR or
-\fBupdate\fR operation, Point-in-Time Copy assures that the shadow volume is
-not mounted, to prevent a file system panic from occurring. Also, it is
-suggested that you either unmount or suspend (quiesce) all applications using
-the master volume, for only the instant when the point-in-time snapshot is
-taken. This assures that an atomically consistent point-in-time snapshot is
-taken.
-.sp
-.LP
-It is suggested that, if the master volume was suspended rather than unmounted,
-the new point-in-time shadow volume's integrity be validated using volume
-validation utilities, such as \fBfsck\fR(1M). The reason is that Point-in-Time
-Copy has made a point-in-time copy of a \fBmounted\fR master volume to an
-\fBunmounted\fR shadow volume. During the mounting of the shadow volume, the
-file system detects that it is in the \fBmounted\fR state. Typically this state
-occurs only when a system crashes, so the file system attempts to validate the
-integrity of the volume assuming a system failure occurred, not an
-Point-in-Time Copy.
-.SS "ENVIRONMENT OPTIONS"
-.LP
-The \fBii_bitmap\fR variable in the \fB/usr/kernel/drv/ii.conf\fR configuration
-file determines the bitmap volume operational semantics as follows:
-.sp
-.ne 2
-.na
-\fB\fB0\fR\fR
-.ad
-.RS 13n
-Indicates that the bitmap is maintained in memory only or resume operation.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB1\fR\fR
-.ad
-.RS 13n
-Indicates that the bitmap is maintained in memory and on disk. This is the
-default value.
-.RE
-
-.sp
-.LP
-If a system failure occurs while using \fBii_bitmap=0\fR, the shadow volume
-might be inconsistent and fast resynchronization would not be possible.
-.sp
-.LP
-If Point-in-Time Copy is used in conjunction with the Network Storage component
-Remote Mirror or in a Sun Cluster, set \fBii_bitmap=1\fR.
-.sp
-.LP
-The \fBii_debug\fR variable in the \fB/usr/kernel/drv/ii.conf\fR configuration
-file determines the amount of information logging that is output to the system
-console \fB/dev/console\fR during Point-in-Time Copy processing.
-.sp
-.ne 2
-.na
-\fB\fB0\fR\fR
-.ad
-.RS 13n
-Indicates that no logging is sent to the system console.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB1\fR\fR
-.ad
-.RS 13n
-Indicates that informational logging is sent to the system console.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB2\fR\fR
-.ad
-.RS 13n
-Indicates that developmental logging is sent to the system console.
-.RE
-
-.SH OPTIONS
-.LP
-The \fBiiadm\fR utility supports the following options.
-.sp
-.ne 2
-.na
-\fB\fB-e\fR\fB{ind|dep}\fR \fImaster_vol shadow_vol bitmap_vol\fR\fR
-.ad
-.sp .6
-.RS 4n
-Enable Point-in-Time Copy for the specified master, shadow, and bitmap volumes.
-.sp
-The enable shadow set processing assures that the specified volumes are
-accessible, that the \fIshadow_vol\fR is not mounted, and that the
-\fIbitmap_vol\fR is correctly sized for the type of shadow set being created.
-Additionally, it assures that the volumes are under control of the SV driver (
-if they are not, it puts them there), initializes the bitmap volume, and, if
-the volume set is an independent shadow set, a full copy operation is
-initiated.
-.sp
-On a successful enable, Point-in-Time Copy stores the specified
-\fImaster_vol\fR, \fIshadow_vol\fR and \fIbitmap_vol\fR names, plus the
-enabling type (\fBind\fR or \fBdep\fR), into the Point-in-Time Copy
-configuration store. The configuration store contains all currently configured
-Point-in-Time Copy Volume Sets and their associated configuration attributes.
-(See discussion above on independent and dependent shadow volume semantics.)
-.sp
-\fImaster_vol\fR is the volume from which a point-in-time snapshot is made.
-.sp
-\fIshadow_vol\fR is the volume that contains the point-in-time snapshot.
-.sp
-\fIbitmap_vol\fR is used for tracking differences between the shadow and master
-volumes. When Point-in-Time Copy shadow operations are suspended or resumed,
-the bitmap volume (maintained in kernel memory) can be stored in or retrieved
-from permanent storage. The storage associated with the bitmap volume should be
-as redundant as that of the shadow volume storage.
-.sp
-The \fIshadow_vol\fR name is the name that the Point-in-Time Copy Shadow Set is
-known by for all \fBiiadm\fR options requiring specification of a
-\fIvolume_set\fR name.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-d\fR \fIvolume_set\fR\fR
-.ad
-.sp .6
-.RS 4n
-Disable the Point-in-Time Copy volume set associated with the specified
-\fIvolume_set\fR.
-.sp
-If Point-in-Time Copy was running in \fBindependent\fR mode as specified in the
-\fB-e\fR \fBind\fR options, above, the shadow volume data contains the same
-data as it did before it was disabled (assuming no writes have occurred). Users
-can access the master and shadow volumes, as they are now standalone
-point-in-time copies.
-.sp
-During the time that the full copy is active, an \fBindependent\fR volume
-operates as though it is a \fBdependent\fR volume. To assure that the volume is
-no longer in full copy mode, issue the following command to wait for the full
-copy to complete:
-.sp
-.in +2
-.nf
-# iiadm -w \fIvolume_set\fR
-.fi
-.in -2
-.sp
-
-.RE
-
-.sp
-.ne 2
-.na
-\fB[\fB-p\fR] \fB-u\fR \fBs\fR \fIvolume_set\fR\fR
-.ad
-.sp .6
-.RS 4n
-Update the shadow volume from the master.
-.sp
-Updates a point-in-time copy of the master volume to the shadow volume.
-\fIvolume_set\fR is the Point-in-Time Copy shadow set containing the master and
-shadow volumes. This option provides a fast resynchronization of the shadow
-volume, creating an incremental copy of the master. This update copies all 32KB
-segments flagged as different between the master and shadow volumes. It does
-not copy all master volume data, only changed data. While the data is being
-copied, the shadow is dependent upon the master volume.
-.sp
-Before using this option, momentarily quiesce the workload to the volumes; stop
-the host application from writing to the volumes. This ensures that the
-point-in-time data is consistent. You can visually check the status of this
-copy or update operation with \fBiiadm\fR \fB-i\fR \fIvolume_set\fR, or
-interactively (by means of a shell or script) with \fBiiadm\fR \fB-w\fR
-\fIvolume_set\fR, before using the target volume for any other operations.
-.sp
-This command supports PID (Process IDentifier) locking, by using the option
-\fB-p\fR, \fBiiadm\fR \fB-p\fR \fB-u\fR \fBs\fR. Enabling this option prevents
-other processes from taking a new point-in-time snapshot, thus invalidating
-prior point-in-time data.
-.RE
-
-.sp
-.ne 2
-.na
-\fB[\fB-p\fR] [\fB-n\fR] \fB-u\fR \fBm\fR \fIvolume_set\fR\fR
-.ad
-.sp .6
-.RS 4n
-Updates a point-in-time copy of the master volume from the shadow.
-\fIvolume_set\fR is the Point-in-Time Copy volume set containing the master and
-shadow. This option provides a fast resynchronization of the master volume,
-creating an incremental copy of the shadow. This update copies all 32KB
-segments flagged as different between the master and shadow volumes. It does
-not copy all shadow volume data, only changed data. While the data is being
-copied, the master is dependent upon the shadow volume.
-.sp
-Before using this option, momentarily quiesce the workload to the volumes; stop
-the host application from writing to the volumes. This ensures that the
-point-in-time data is consistent. You can visually check the status of this
-copy or update operation with \fBiiadm\fR \fB-i\fR \fIvolume_set\fR, or
-interactively (by means of a shell or script) with \fBiiadm\fR \fB-w\fR
-\fIvolume_set\fR, before using the target volume for any other operations.
-.sp
-This command is query enabled to prevent accidentally overwriting the data on a
-master volume. When this command option is used in scripts, add the \fB-n\fR
-option to prevent the query from occurring.
-.sp
-This command supports PID (Process IDentifier) locking, by using the option
-\fB-p\fR, \fBiiadm\fR \fB-p\fR \fB-u\fR \fBm\fR. Enabling this option prevents
-other processes from taking a new point-in-time snapshot, thus invalidating
-prior point-in-time data.
-.RE
-
-.sp
-.ne 2
-.na
-\fB[\fB-p\fR] \fB-c\fR s \fIvolume_set\fR\fR
-.ad
-.sp .6
-.RS 4n
-Copy the master volume to the shadow.
-.sp
-Creates a point-in-time copy of the master volume to the shadow volume.
-\fIvolume_set\fR is the Point-in-Time Copy volume set containing the master and
-shadow. This option writes all data in the point-in-time copy of the master
-volume to the shadow volume. While the data is being copied from master to
-shadow, the shadow is dependent on the master volume.
-.sp
-This option performs a full volume copy. Use \fBiiadm\fR \fB-u\fR \fBs\fR
-unless the integrity of the data on the independent shadow volume is in doubt.
-Otherwise, use this option to synchronize the master and shadow volumes; that
-is, make the data on each volume match.
-.sp
-Before using this option, momentarily quiesce the workload to the volumes; stop
-the host application from writing to the volumes. This ensures that the
-point-in-time data is consistent. You can visually check the status of this
-copy or update operation with \fBiiadm\fR \fB-i\fR \fIvolume_set\fR, or
-interactively (by means of a shell or script) with \fBiiadm\fR \fB-w\fR
-\fIvolume_set\fR, before using the target volume for any other operations.
-.sp
-This command supports PID (Process IDentifier) locking, by using the \fB-p\fR
-option, \fBiiadm\fR \fB-p\fR \fB-c\fR \fBs\fR. Enabling this option prevents
-other processes from taking a new point-in-time snapshot, thus invalidating
-prior point-in-time data.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-c\fR \fBm\fR \fIvolume_set\fR\fR
-.ad
-.sp .6
-.RS 4n
-Copy the shadow volume to the master.
-.sp
-Creates a point-in-time copy of the shadow volume to the master volume.
-\fIvolume_set\fR is the Point-in-Time Copy volume set containing the master and
-shadow volumes. This option writes all data in the point-in-time copy of the
-shadow volume to the master volume. While the data is being copied from the
-shadow to the master, the master is dependent upon the shadow volume.
-.sp
-This option performs a full volume copy. Use \fBiiadm\fR \fB-u\fR \fBm\fR
-unless the integrity of the data on the independent master is in doubt.
-Otherwise, use this option to synchronize the master and shadow volumes; that
-is, make the data on each volume match.
-.sp
-Before using this option, momentarily quiesce the workload to the volumes; stop
-the host application from writing to the volumes. This ensures that the
-point-in-time data is consistent. You can visually check the status of this
-copy or update operation with \fBiiadm\fR \fB-i\fR \fIvolume_set\fR, or
-interactively (by means of a shell or script) with \fBiiadm\fR \fB-w\fR
-\fIvolume_set\fR, before using the target volume for any other operations.
-.sp
-This command is query-enabled to prevent accidentally overwriting the data on a
-master volume. When this command option is used in scripts, add the \fB-n\fR
-option to prevent the query from occurring.
-.sp
-This command supports PID (Process IDentifier) locking, by using the \fB-p\fR
-option, \fBiiadm\fR \fB-p\fR \fB-c\fR \fBm\fR. Enabling this option prevents
-other processes from taking a new point-in-time snapshot, thus invalidating
-prior point-in-time data.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-a\fR \fIvolume_set\fR\fR
-.ad
-.sp .6
-.RS 4n
-Abort any current copy operation that might be active between the master and
-shadow volumes. \fIvolume_set\fR is the Point-in-Time Copy volume set
-containing the master and shadow volumes. After executing \fBiiadm\fR \fB-a\fR,
-the update or copy to the target (master or shadow) volume is incomplete. The
-target volume is now a dependent copy of the source volume. Reissue the update
-or copy command option to resynchronize the volumes.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB[\fR\fB-p\fR\fB] [\fR\fB-n\fR\fB] \fR\fB-w\fR \fIvolume_set\fR\fR
-.ad
-.sp .6
-.RS 4n
-Wait until any in-progress copy or update operation completes or is aborted.
-\fIvolume_set\fR is the Point-in-Time Copy volume set containing the master and
-shadow volumes.
-.sp
-This option waits until the current Point-in-Time Copy operation is complete,
-thus preventing a subsequent \fBiiadm\fR command (from a shell or script) from
-executing. Use this command option when you need to be sure the copy or update
-operation has completed.
-.sp
-This command supports PID (Process IDentifier) unlocking. If a prior copy or
-update, using a command \fBiiadm\fR \fB-p\fR \fB{\fR\fB-c\fR\fB|\fR\fB-u\fR\fB}
-{m|s}\fR, was invoked with the \fB-p\fR option, upon completion of the wait
-processing, if the current PID was the PID that locked the point-in-time data,
-this option unlocks the data.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-i\fR \fIvolume_set\fR\fR
-.ad
-.sp .6
-.RS 4n
-Display status for the Point-in-Time Copy currently-enabled or -suspended
-volume set. \fIvolume_set\fR is the Point-in-Time Copy volume set containing
-the master and shadow volumes. If no \fIvolume_set\fR is specified, status is
-displayed for all Point-in-Time Copy volume sets that are configured.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-l\fR\fR
-.ad
-.sp .6
-.RS 4n
-List all currently configured Point-in-Time Copy volumes.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-O\fR \fIoverflow_vol\fR\fR
-.ad
-.sp .6
-.RS 4n
-This option causes Point-in-Time Copy to initialize the specified
-\fIoverflow_vol\fR for subsequent use as an overflow volume in conjunction with
-Compact Dependent Shadow Volumes. To facilitate efficient, shared usage of this
-overflow volume, it can be associated with multiple Point-in-Time Copy volume
-sets on an as-needed basis.
-.sp
-During initialization of the \fIoverflow_vol\fR, the initiator of this option,
-must answer the following question: "Initialize this overflow volume? yes/no" A
-response of either "yes/no" is required before proceeding.
-.sp
-This option supports the \fB-n\fR option, so that the requested action is
-performed without prompting. This option is useful for inclusion in a script.
-The \fB-n\fR option must be specified first. For example, "\fBiiadm\fR
-\fB-nO\fR \fBvol\fR" is valid; "\fBiiadm\fR \fB-On\fR \fBvol\fR" is not.
-.sp
-Make sure you want to initialize the data on the specified \fIoverflow_vol\fR,
-especially when using the \fB-n\fR option.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-A\fR \fIoverflow_vol\fR \fIvolume_set\fR\fR
-.ad
-.sp .6
-.RS 4n
-This option enables the specified \fIoverflow_vol\fR, for subsequent use as an
-overflow volume in a situation where the size of the Compact Dependent Shadow
-Volume is too small, or an unscheduled amount of change occurs to the volume
-set. Overflow changed data would be redirected to the associated overflow
-volume. \fIvolume_set\fR is the Point-in-Time Copy volume set containing the
-master and shadow volumes.
-.sp
-If the \fIoverflow_vol\fR has not been initialized, this option initializes the
-\fIoverflow_vol\fR (see \fB-O\fR option), then attaches the \fIoverflow_vol\fR
-to the \fIvolume_set\fR.
-.sp
-If \fIoverflow_vol\fR was previously initialized, this option attaches the
-\fIoverflow_vol\fR to the \fIvolume_set\fR.
-.sp
-This option supports the \fB-n\fR option, so that the requested action is
-performed without prompting. This option is useful for inclusion in a script.
-The \fB-n\fR option must be specified first. For example, "\fBiiadm\fR
-\fB-nA\fR \fBvol\fR" is valid; "\fBiiadm\fR \fB-An\fR \fBvol\fR" is not.
-.sp
-Make sure you want to initialize the data on the specified \fIoverflow_vol\fR,
-especially when using the \fB-n\fR option.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-D\fR \fIvolume_set\fR\fR
-.ad
-.sp .6
-.RS 4n
-This option removes the overflow volume currently associated with the specified
-\fIvolume_set\fR. If the overflow volume is currently in use by the
-\fIvolume_set\fR, this operation fails with an "Overflow volume still in use"
-error message. To resolve this situation, perform one of the operations
-described below on the \fIvolume_set\fR. These operations momentarily clear out
-all overflow writes that are associated with this volume set.
-.sp
-.ne 2
-.na
-\fB\fBabort\fR(\fB-a\fR)\fR
-.ad
-.sp .6
-.RS 4n
-Abort copy operation.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBdisable\fR(\fB-d\fR)\fR
-.ad
-.sp .6
-.RS 4n
-Dissolve the volume set.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBupdate\fR(\fB-u\fR)\fR
-.ad
-.sp .6
-.RS 4n
-Update the volume set.
-.RE
-
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-L\fR\fR
-.ad
-.sp .6
-.RS 4n
-This option lists all overflow volumes which are associated with one or more
-volume sets.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-Q\fR \fIoverflow_vol\fR\fR
-.ad
-.sp .6
-.RS 4n
-This option displays the current status of the \fIoverflow_vol\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-E\fR \fIvolume_set\fR\fR
-.ad
-.sp .6
-.RS 4n
-Export the independent shadow volume of the Point-in-Time Copy volume set
-specified by \fIvolume_set\fR. The shadow volume is to be made available to
-another host for read/write access, by means of an enabling technology, such as
-multi-ported devices. This other host is responsible for maintaining a bitmap
-of differences that is used to merge with locally recorded differences to the
-master when the shadow volume is rejoined to its master volume. While a shadow
-volume is exported it must not be subject to an update or copy operation.
-Perform an \fBiiadm\fR \fB-w\fR \fIvolume_set\fR command prior to invoking an
-export command.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-I\fR \fIvolume_set\fR \fIbitmap_vol\fR\fR
-.ad
-.sp .6
-.RS 4n
-Import the independent shadow volume of the Point-in-Time Copy volume set
-specified by \fIvolume_set\fR. The shadow volume must have been previously
-exported from a host by means of an enabling technology, such as multi-ported
-devices. The import operation causes this host to start maintaining a bitmap of
-differences as the volume is modified. The \fIbitmap_vol\fR should not be the
-same as that used when the shadow volume was originally formed into a shadow
-group.
-.sp
-After the exported/imported independent shadow volume is no longer needed by
-the other node, you must enter a disable command so that the \fIbitmap_vol\fR
-and its associated \fIshadow_vol\fR are consistent, prior to performing a join
-operation. For example,
-.sp
-.in +2
-.nf
-# iiadm -d \fIvolume_set\fR
-.fi
-.in -2
-.sp
-
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-J\fR \fIvolume_set\fR \fIbitmap_vol\fR\fR
-.ad
-.sp .6
-.RS 4n
-Join the \fIvolume_set\fR, using the \fIbitmap_vol\fR, with the master volume
-set of the Point-in-Time Copy volume set. The bitmap volume supplied is read
-and merged with the original volume to reconstruct the original volume set
-consisting of the master, shadow, and bitmap volumes. The \fIbitmap_vol\fR to
-be merged is the one obtained on the node that had imported the independent
-shadow volume. There must be no write activity to the shadow volume on the
-importing machine from the time the bitmap is copied over until the shadow is
-once again imported.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-g\fR \fIgroup_name\fR \fB-m\fR \fIvolume_set [volume_set2 ...]\fR\fR
-.ad
-.sp .6
-.RS 4n
-Add one or more existing Point-in-Time Copy \fIvolume_set(s)\fR into a user
-specified \fIgroup_name\fR. This association of one or more Point-in-Time Copy
-volume sets in a group allows the list of \fBiiadm\fR options shown below to be
-performed on all volume sets within the \fIgroup_name\fR as a whole.
-.sp
-Only the commands \fBCOPY\fR (\fB-c\fR) and \fBUPDATE\fR (\fB-u\fR) are
-performed atomically across all Point-in-Time Copy sets within the group. All
-other grouped, \fBiiadm\fR commands are performed sequentially on each member
-of the group.
-.sp
-The syntax of an \fBiiadm\fR group command is as follows:
-.sp
-.in +2
-.nf
-iiadm -g \fIgroup_name\fR [\fIoptions\fR]
-.fi
-.in -2
-.sp
-
-The \fIoptions\fR are as follows:
-.sp
-.ne 2
-.na
-\fB\fB-a\fR\fR
-.ad
-.sp .6
-.RS 4n
-Abort copy operation on all sets within \fIgroup_name\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-A\fR\fR
-.ad
-.sp .6
-.RS 4n
-Attach \fIoverflow_vol\fR to all sets within \fIgroup_name\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-c\fR \fB{s | m}\fR\fR
-.ad
-.sp .6
-.RS 4n
-Copy shadow/master for all sets within \fIgroup_name\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-D\fR\fR
-.ad
-.sp .6
-.RS 4n
-Detach \fIoverflow_vol\fR from all sets within \fIgroup_name\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-d\fR\fR
-.ad
-.sp .6
-.RS 4n
-Disable all sets within \fIgroup_name\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-E\fR\fR
-.ad
-.sp .6
-.RS 4n
-Export all volume sets within \fIgroup_name\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-i\fR\fR
-.ad
-.sp .6
-.RS 4n
-Status of all volume sets within \fIgroup_name\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-l\fR\fR
-.ad
-.sp .6
-.RS 4n
-List all volume sets within \fIgroup_name\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-L\fR\fR
-.ad
-.sp .6
-.RS 4n
-List all groups.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-n\fR\fR
-.ad
-.sp .6
-.RS 4n
-Do not ask if an update of the master volume is what the user really intended.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-P\fR\fR
-.ad
-.sp .6
-.RS 4n
-Set parameters on all volume sets within \fIgroup_name\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-R\fR\fR
-.ad
-.sp .6
-.RS 4n
-Reset all volume sets within \fIgroup_name\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-u\fR \fB{s | m}\fR\fR
-.ad
-.sp .6
-.RS 4n
-Update shadow/master for all sets within \fIgroup_name\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-w\fR\fR
-.ad
-.sp .6
-.RS 4n
-Wait for all volume sets within \fIgroup_name\fR.
-.RE
-
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-g\fR \fB""\fR \fB-m\fR \fIvolume_set\fR [\fIvolume_set2 ...\fR]\fR
-.ad
-.sp .6
-.RS 4n
-Remove one or more existing Point-in-Time Copy \fIvolume_set(s)\fR from their
-currently associated \fIgroup_name\fR. By default, or until moved into a user
-specified \fIgroup_name\fR, all Point-in-Time Copy \fIvolume_set(s)\fR are in
-the blank (\fB" "\fR) group. This association allows all the previously
-documented \fBiiadm\fR group commands to be performed against the blank (\fB"
-"\fR) \fBiiadm\fR \fIgroup_name\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-C\fR \fIcluster_tag\fR\fR
-.ad
-.sp .6
-.RS 4n
-This Point-in-Time Copy option is a modifier that limits configuration
-operations to only those volumes belonging to a Sun Cluster Resource Group, or
-Disk Group.
-.sp
-In a Sun Cluster where the volume manager is Sun Cluster-aware, \fBiiadm\fR
-automatically obtains the correct Disk Group information, therefore this option
-is typically not required unless the volumes are part of an encompassing
-Resource Group.
-.sp
-In a Sun Cluster where the volumes are accessible on the local node only, the
-special \fIcluster_tag\fR of \fBlocal\fR is used to indicate volumes that are
-not part of a Sun Cluster Resource Group or Disk Group.
-.sp
-If "\fB-L\fR" is given as a the \fIcluster_tag\fR argument, then \fBiiadm\fR
-lists all cluster tags associated with Point-in-Time Copy.
-.sp
-This option is invalid when used on a Solaris system on which the Sun Cluster
-package has not been installed or configured.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-h\fR\fR
-.ad
-.sp .6
-.RS 4n
-Prints the \fBiiadm\fR usage summary.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-v\fR\fR
-.ad
-.sp .6
-.RS 4n
-Display the current version of the Point-in-Time Copy software components.
-.RE
-
-.sp
-.LP
-Contact Sun Enterprise Services for assistance in using the remaining commands
-in this section.
-.sp
-.ne 2
-.na
-\fB\fB-P\fR \fIdelay\fR \fIunit\fR \fIvolume_set\fR\fR
-.ad
-.sp .6
-.RS 4n
-Alter the Point-in-Time Copy volume set tuning parameters for the specified
-\fIvolume_set\fR to \fIdelay\fR ticks, every \fIunit\fR I/O's. Delay ranges
-from 2 to 10000 inclusive; unit ranges from 100 to 60000 inclusive.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-R\fR \fIvolume\fR\fR
-.ad
-.sp .6
-.RS 4n
-After a volume has failed, Point-in-Time Copy places it offline. After
-replacing the volume, place it back online using this option. Associated
-dependent volumes in the Point-in-Time Copy volume set are also placed online.
-After the volume is placed online, this command also starts any necessary
-point-in-time volume updates.
-.RE
-
-.SH EXIT STATUS
-.ne 2
-.na
-\fB\fB0\fR\fR
-.ad
-.RS 13n
-Command completed successfully.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB>0\fR\fR
-.ad
-.RS 13n
-An error occurred.
-.RE
-
-.SH ATTRIBUTES
-.LP
-See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
-.TS
-box;
-c | c
-l | l .
-ATTRIBUTE TYPE ATTRIBUTE VALUE
-_
-Interface Stability Evolving
-.TE
-
-.SH SEE ALSO
-.LP
-\fBdscfg\fR(1M), \fBsvadm\fR(1M), \fBds.log\fR(4), \fBrdc.cf\fR(4),
-\fBattributes\fR(5), \fBii\fR(7D), \fBsv\fR(7D)
diff --git a/usr/src/man/man1m/iicpbmp.1m b/usr/src/man/man1m/iicpbmp.1m
deleted file mode 100644
index bd867af67c..0000000000
--- a/usr/src/man/man1m/iicpbmp.1m
+++ /dev/null
@@ -1,77 +0,0 @@
-'\" te
-.\" Copyright (c) 2007, Sun Microsystems, Inc. All rights reserved.
-.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
-.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
-.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH IICPBMP 1M "Oct 2, 2007"
-.SH NAME
-iicpbmp \- copy Availability Suite Point-In-Time bitmap volumes
-.SH SYNOPSIS
-.LP
-.nf
-\fBiicpbmp\fR [\fB-c\fR] \fIold_bitmap\fR \fInew_bitmap\fR...
-.fi
-
-.SH DESCRIPTION
-.sp
-.LP
-The \fBiicpbmp\fR command copies an Availability Suite Point-in-Time bitmap
-volume, rewriting the bitmap header so that it is consistent with the new
-bitmap volume name. The configuration entry for the shadow set is rewritten to
-reflect the location of the new bitmap.
-.sp
-.LP
-No checks on the current use of either the old or new bitmap volumes are made.
-The \fBiicpbmp\fR command should only be run when the Point-In-Time Copy shadow
-set using the old bitmap is suspended.
-.SH OPTIONS
-.sp
-.ne 2
-.na
-\fB\fB-c\fR\fR
-.ad
-.RS 13n
-Do not attempt to update the Availability Suite configuration for the
-Point-in-Time shadow set that uses the bitmap. This option produces a duplicate
-of the bitmap but does not affect the shadow set using the old bitmap volume.
-.RE
-
-.SH OPERANDS
-.sp
-.ne 2
-.na
-\fB\fIold_bitmap\fR \fInew_bitmap\fR\fR
-.ad
-.sp .6
-.RS 4n
-The old and new Point-In-Time bitmap volumes.
-.RE
-
-.SH WARNINGS
-.sp
-.LP
-The \fBiicpbmp\fR should be run only when a system is in single-user mode.
-\fBiicpbmp\fR makes no attempt to check if an Point-In-Time Copy set is in use
-at the time the copy is made. Running \fBiicpbmp\fR without the \fB-c\fR flag
-while Point-In-Time Copy is using the shadow set results in inconsistencies in
-the shadow set the next time Point-In-Time Copy is started.
-.SH ATTRIBUTES
-.sp
-.LP
-See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
-.TS
-box;
-c | c
-l | l .
-ATTRIBUTE TYPE ATTRIBUTE VALUE
-_
-Interface Stability Evolving
-.TE
-
-.SH SEE ALSO
-.sp
-.LP
-\fBiiadm\fR(1M), \fBiicpshd\fR(1M), \fBattributes\fR(5)
diff --git a/usr/src/man/man1m/iicpshd.1m b/usr/src/man/man1m/iicpshd.1m
deleted file mode 100644
index ebf853db1d..0000000000
--- a/usr/src/man/man1m/iicpshd.1m
+++ /dev/null
@@ -1,85 +0,0 @@
-'\" te
-.\" Copyright (c) 2007, Sun Microsystems, Inc. All rights reserved.
-.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
-.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
-.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH IICPSHD 1M "Oct 2, 2007"
-.SH NAME
-iicpshd \- copy Availability Suite Point-in-Time shadow volume
-.SH SYNOPSIS
-.LP
-.nf
-\fBiicpshd\fR [\fB-s\fR] \fIold_shadow\fR \fInew_shadow\fR...
-.fi
-
-.SH DESCRIPTION
-.sp
-.LP
-The \fBiicpshd\fR command copies an Availability Suite Instant Image shadow
-volume, updating the bit map header and Availability Suite configuration to
-reflect the new shadow volume.
-.sp
-.LP
-No checks on the current use of either the old or new shadow volumes are made.
-The \fBiicpshd\fR command should only be run when the Instant Image shadow set
-using the old shadow volume is suspended.
-.SH OPTIONS
-.sp
-.LP
-The \fBiicpshd\fR command supports the following option:
-.sp
-.ne 2
-.na
-\fB\fB-s\fR\fR
-.ad
-.RS 13n
-Update the StorageTek configuration information for the Point-in-Time shadow
-set, but do \fBnot\fR copy data from the old shadow volume to the new shadow
-volume.
-.RE
-
-.SH OPERANDS
-.sp
-.LP
-A \fBiicpshd\fR command line has the following operands:
-.sp
-.ne 2
-.na
-\fB\fIold_shadow\fR \fInew_shadow\fR\fR
-.ad
-.sp .6
-.RS 4n
-\fBiicpshd\fR copies the data of the old Availability Suite Instant Image
-shadow volume to the new shadow volume and updates the bit map header and
-configuration data.
-.RE
-
-.SH ATTRIBUTES
-.sp
-.LP
-See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
-.TS
-box;
-c | c
-l | l .
-ATTRIBUTE TYPE ATTRIBUTE VALUE
-_
-Interface Stability Evolving
-.TE
-
-.SH SEE ALSO
-.sp
-.LP
-\fBiiadm\fR(1M), \fBiicpbmp\fR(1M), \fBattributes\fR(5)
-.SH WARNINGS
-.sp
-.LP
-\fBiicpshd\fR should be run only when the system is in single-user mode. When
-you run \fBiicpshd\fR, the command makes no attempt to check if a Point-in-Time
-set is in use. Running \fBiicpshd\fR with the \fB-s\fR flag while Point-in-Time
-is using the old shadow volume can result in shadow volume data loss. If you
-use the \fB-s\fR option, you must manually copy the data on the old shadow
-volume to the new shadow volume.
diff --git a/usr/src/man/man1m/nscadm.1m b/usr/src/man/man1m/nscadm.1m
deleted file mode 100644
index ab7b28f59a..0000000000
--- a/usr/src/man/man1m/nscadm.1m
+++ /dev/null
@@ -1,143 +0,0 @@
-'\" te
-.\" Copyright (c) 2007, Sun Microsystems, Inc. All rights reserved.
-.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
-.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
-.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH NSCADM 1M "Oct 2, 2007"
-.SH NAME
-nscadm \- network storage control utility
-.SH SYNOPSIS
-.LP
-.nf
-\fBnscadm\fR freeze \fIdevice\fR
-.fi
-
-.LP
-.nf
-\fBnscadm\fR unfreeze \fIdevice\fR
-.fi
-
-.LP
-.nf
-\fBnscadm\fR isfrozen \fIdevice\fR
-.fi
-
-.SH DESCRIPTION
-.sp
-.LP
-The \fBnscadm\fR command performs several network storage control functions.
-.sp
-.LP
-The \fBnscadm\fR \fBfreeze\fR command closes existing references to the
-specified device, and blocks future accesses. This allows maintenance of
-virtual volume device drivers (for example, RAID 0, RAID 1, RAID 5) to be
-performed without shutting down the system.
-.sp
-.LP
-The \fBnscadm\fR \fBunfreeze\fR command reverses the effects of \fBnscadm\fR
-\fBfreeze\fR for the specified device.
-.sp
-.LP
-The \fBnscadm\fR \fBisfrozen\fR command returns the current status of the
-specified device.
-.SH OPTIONS
-.sp
-.LP
-The \fBnscadm\fR command supports the following option.
-.sp
-.ne 2
-.na
-\fB\fB-h\fR\fR
-.ad
-.RS 13n
-Display the usage menu.
-.RE
-
-.SH OPERANDS
-.sp
-.LP
-The \fBnscadm\fR command line supports the following operand.
-.sp
-.ne 2
-.na
-\fB\fIdevice\fR\fR
-.ad
-.sp .6
-.RS 4n
-Specifies the storage device to be acted upon by \fBnscadm\fR.
-.RE
-
-.SH EXIT STATUS
-.sp
-.LP
-For the \fBfreeze\fR and \fBunfreeze\fR, subcommands \fBnscadm\fR returns the
-following exit values:
-.sp
-.ne 2
-.na
-\fB\fB0\fR\fR
-.ad
-.RS 13n
-Success
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB255\fR\fR
-.ad
-.RS 13n
-Error
-.RE
-
-.sp
-.LP
-For the \fBisfrozen\fR subcommand, \fBnscadm\fR returns the following exit
-values:
-.sp
-.ne 2
-.na
-\fB\fB0\fR\fR
-.ad
-.RS 13n
-Device is currently frozen.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB1\fR\fR
-.ad
-.RS 13n
-Device is not currently frozen.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB255\fR\fR
-.ad
-.RS 13n
-Error
-.RE
-
-.SH ATTRIBUTES
-.sp
-.LP
-See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
-.TS
-box;
-c | c
-l | l .
-ATTRIBUTE TYPE ATTRIBUTE VALUE
-_
-Interface Stability Evolving
-.TE
-
-.SH SEE ALSO
-.sp
-.LP
-\fBscmadm\fR(1M), \fBattributes\fR(5)
diff --git a/usr/src/man/man1m/scmadm.1m b/usr/src/man/man1m/scmadm.1m
deleted file mode 100644
index 82e49af38b..0000000000
--- a/usr/src/man/man1m/scmadm.1m
+++ /dev/null
@@ -1,203 +0,0 @@
-'\" te
-.\" Copyright (c) 2007, Sun Microsystems, Inc. All rights reserved.
-.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
-.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
-.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH SCMADM 1M "Aug 3, 2006"
-.SH NAME
-scmadm \- storage cache manager administration utility
-.SH SYNOPSIS
-.LP
-.nf
-\fBscmadm\fR
-.fi
-
-.LP
-.nf
-\fBscmadm\fR \fB-h\fR
-.fi
-
-.LP
-.nf
-\fBscmadm\fR \fB-e\fR
-.fi
-
-.LP
-.nf
-\fBscmadm\fR \fB-d\fR
-.fi
-
-.LP
-.nf
-\fBscmadm\fR \fB-v\fR
-.fi
-
-.LP
-.nf
-\fBscmadm\fR \fB-C\fR [\fIparameter\fR [= [\fIvalue\fR]]...]
-.fi
-
-.LP
-.nf
-\fBscmadm\fR \fB-o\fR {system | \fIcd\fR | \fIdevice\fR} [\fIoption\fR]
-.fi
-
-.LP
-.nf
-\fBscmadm\fR \fB-m\fR {\fIcd\fR | \fIdiskname\fR | all}
-.fi
-
-.SH DESCRIPTION
-.sp
-.LP
-The \fBscmadm\fR command provides various options for controlling and gathering
-information about a storage device cache.
-.SH OPTIONS
-.sp
-.LP
-If no options are specified, \fBscmadm\fR displays a list of configured cache
-descriptors with disknames, options, and global options. The \fBscmadm\fR
-command supports the following options:
-.sp
-.ne 2
-.na
-\fB\fB-h\fR\fR
-.ad
-.sp .6
-.RS 4n
-Displays usage information for the \fBscmadm\fR command.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-e\fR\fR
-.ad
-.sp .6
-.RS 4n
-Reads the configuration and enables the storage device cache with those
-parameters. See \fBdscfg\fR(1M).
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-d\fR\fR
-.ad
-.sp .6
-.RS 4n
-Shuts down the storage device cache.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-v\fR\fR
-.ad
-.sp .6
-.RS 4n
-Displays the cache version number.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-C\fR [\fIparameter\fR[=[\fIvalue\fR]] ...]\fR
-.ad
-.sp .6
-.RS 4n
-Sets or displays the configuration parameters. If the \fB-C\fR option is
-specified with no arguments the current cache configuration parameters are
-displayed. If \fIparameter\fR is specified, the current value of
-\fIparameter\fR is displayed. If \fIparameter=value\fR is specified, the
-current value of \fIparameter\fR is displayed and the parameter is changed to
-\fIvalue\fR. If \fIvalue\fR is omitted, or if \fIvalue\fR is specified as the
-null string, " ", or as "-", the parameter is deleted from the configuration
-and the system uses the default value. Multiple parameters can be specified in
-a single invocation of the \fBscmadm\fR command. A change in a configuration
-parameter takes effect only when the cache is next restarted.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-o\fR { \fBsystem\fR | \fBcd\fR | \fIdiskname\fR } [\fIoption\fR]\fR
-.ad
-.sp .6
-.RS 4n
-Sets or displays the options for the system or for the cache device specified
-by \fBcd\fR or \fIdiskname\fR. If the \fIoption\fR \fBrdcache\fR or
-\fBnordcache\fR is specified, the system or specified cache device is set to
-that option. The option is saved as part of the configuration so that the
-option persists. See \fBdscfg\fR(1M). To notify the system to "forget" about a
-saved option, use the \fBforget\fR option. This does not change the option; it
-just removes the option from the saved configuration. If no option is
-specified, current options are displayed. The \fBrdcache\fR option is set as
-the default. The \fIoption\fRs are defined as follows:
-.sp
-.ne 2
-.na
-\fB\fBrdcache\fR\fR
-.ad
-.sp .6
-.RS 4n
-Data blocks are likely to be referenced again and should remain in cache.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBnordcache\fR\fR
-.ad
-.sp .6
-.RS 4n
-Data blocks are unlikely to be referenced again and should be treated as least
-recently used, so that other blocks can remain in the cache longer.
-.RE
-
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-m\fR { \fBcd\fR | \fIdiskname\fR | \fBall\fR }\fR
-.ad
-.sp .6
-.RS 4n
-Displays the cache descriptor and diskname map for the device specified by
-\fBcd\fR or \fIdiskname\fR or, if you specify \fBall\fR, displays the cache
-descriptors and diskname map for all storage devices on the system.
-.RE
-
-.SH EXIT STATUS
-.sp
-.LP
-The \fBscmadm\fR command returns 0 for success, non-zero for error.
-.SH FILES
-.sp
-.LP
-\fB/dev/sdbc\fR
-.SH ATTRIBUTES
-.sp
-.LP
-See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
-.TS
-box;
-c | c
-l | l .
-ATTRIBUTE TYPE ATTRIBUTE VALUE
-_
-Interface Stability Evolving
-.TE
-
-.SH SEE ALSO
-.sp
-.LP
-\fBdscfg\fR(1M), \fBattributes\fR(5)
-.SH DIAGNOSTICS
-.sp
-.LP
-\fBscmadm\fR fails if there is insufficient contiguous memory.
diff --git a/usr/src/man/man1m/sndradm.1m b/usr/src/man/man1m/sndradm.1m
deleted file mode 100644
index eddd56c052..0000000000
--- a/usr/src/man/man1m/sndradm.1m
+++ /dev/null
@@ -1,1043 +0,0 @@
-'\" te
-.\" Copyright (c) 2007, Sun Microsystems, Inc. All rights reserved.
-.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
-.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
-.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH SNDRADM 1M "Oct 2, 2007"
-.SH NAME
-sndradm \- control Sun StorageTek Availability Suite Remote Mirror operations
-.SH SYNOPSIS
-.LP
-.nf
-\fBsndradm\fR \fB-I\fR a \fImaster\fR \fIshadow\fR \fIbitmap\fR
-.fi
-
-.LP
-.nf
-\fBsndradm\fR \fB-I\fR d \fImaster\fR \fIshadow\fR \fIbitmap\fR
-.fi
-
-.LP
-.nf
-\fBsndradm\fR \fB-h\fR \fIusage message\fR
-.fi
-
-.LP
-.nf
-\fBsndradm\fR \fB-v\fR \fIversion information\fR
-.fi
-
-.LP
-.nf
-\fBsndradm\fR [\fIoptions\fR] \fB-e\fR [\fIsndr_set\fR]
-.fi
-
-.LP
-.nf
-\fBsndradm\fR [\fIoptions\fR] \fB-E\fR [\fIsndr_set\fR]
-.fi
-
-.LP
-.nf
-\fBsndradm\fR [\fIoptions\fR] \fB-d\fR [\fIsndr_set\fR]
-.fi
-
-.LP
-.nf
-\fBsndradm\fR [\fIoptions\fR] \fB-D\fR block [\fIsndr_set\fR]
-.fi
-
-.LP
-.nf
-\fBsndradm\fR [\fIoptions\fR] \fB-D\fR noblock [\fIsndr_set\fR]
-.fi
-
-.LP
-.nf
-\fBsndradm\fR [\fIoptions\fR] \fB-l\fR [\fIsndr_set\fR]
-.fi
-
-.LP
-.nf
-\fBsndradm\fR [\fIoptions\fR] \fB-m\fR [\fIsndr_set\fR]
-.fi
-
-.LP
-.nf
-\fBsndradm\fR [\fIoptions\fR] \fB-m\fR \fB-r\fR [\fIsndr_set\fR]
-.fi
-
-.LP
-.nf
-\fBsndradm\fR [\fIoptions\fR] \fB-u\fR [\fIsndr_set\fR]
-.fi
-
-.LP
-.nf
-\fBsndradm\fR [\fIoptions\fR] \fB-u\fR \fB-r\fR [\fIsndr_set\fR]
-.fi
-
-.LP
-.nf
-\fBsndradm\fR [\fIoptions\fR] \fB-w\fR [\fIsndr_set\fR]
-.fi
-
-.LP
-.nf
-\fBsndradm\fR [\fIoptions\fR] \fB-H\fR [\fIsndr_set\fR]
-.fi
-
-.LP
-.nf
-\fBsndradm\fR [\fIoptions\fR] \fB-p\fR [\fIsndr_set\fR]
-.fi
-
-.LP
-.nf
-\fBsndradm\fR [\fIoptions\fR] \fB-P\fR [\fIsndr_set\fR]
-.fi
-
-.LP
-.nf
-\fBsndradm\fR [\fIoptions\fR] \fB-q\fR a \fIvolume\fR [\fIsndr_set\fR]
-.fi
-
-.LP
-.nf
-\fBsndradm\fR [\fIoptions\fR] \fB-q\fR d [\fIsndr_set\fR]
-.fi
-
-.LP
-.nf
-\fBsndradm\fR [\fIoptions\fR] \fB-q\fR r \fIvolume\fR [\fIsndr_set\fR]
-.fi
-
-.LP
-.nf
-\fBsndradm\fR [\fIoptions\fR] \fB-i\fR [\fIsndr_set\fR]
-.fi
-
-.LP
-.nf
-\fBsndradm\fR [\fIoptions\fR] \fB-a\fR \fIvalue\fR [\fIsndr_set\fR]
-.fi
-
-.LP
-.nf
-\fBsndradm\fR [\fIoptions\fR] \fB-A\fR \fIvalue\fR [\fIsndr_set\fR]
-.fi
-
-.LP
-.nf
-\fBsndradm\fR [\fIoptions\fR] \fB-F\fR \fIvalue\fR [\fIsndr_set\fR]
-.fi
-
-.LP
-.nf
-\fBsndradm\fR [\fIoptions\fR] \fB-W\fR \fIvalue\fR [\fIsndr_set\fR]
-.fi
-
-.LP
-.nf
-\fBsndradm\fR [\fIoptions\fR] \fB-R\fR
-.fi
-
-.LP
-.nf
-\fBsndradm\fR [\fIoptions\fR] \fB-R\fR b p \fIbitmap\fR [\fIsndr_set\fR]
-.fi
-
-.LP
-.nf
-\fBsndradm\fR [\fIoptions\fR] \fB-R\fR b s \fIbitmap\fR [\fIsndr_set\fR]
-.fi
-
-.LP
-.nf
-\fBsndradm\fR [\fIoptions\fR] \fB-R\fR C \fItag\fR [\fIsndr_set\fR]
-.fi
-
-.LP
-.nf
-\fBsndradm\fR [\fIoptions\fR] \fB-R\fR g \fIio_groupname\fR [\fIsndr_set\fR]
-.fi
-
-.LP
-.nf
-\fBsndradm\fR [\fIoptions\fR] \fB-R\fR m sync [\fIsndr_set\fR]
-.fi
-
-.LP
-.nf
-\fBsndradm\fR [\fIoptions\fR] \fB-R\fR m async [\fIsndr_set\fR]
-.fi
-
-.LP
-.nf
-\fBsndradm\fR [\fIoptions\fR] \fB-R\fR \fB-f\fR \fIvolset-file\fR
-.fi
-
-.LP
-.nf
-\fBsndradm\fR [\fIoptions\fR] \fB-R\fR r [\fIsndr_set\fR] *
-.fi
-
-.SH DESCRIPTION
-.sp
-.LP
-The \fB/usr/sbin/sndradm\fR command is the administrative command line
-interface for the Sun StorageTek Availability Suite Remote Mirror software.
-Remote Mirror enables you to replicate disks between different
-physically-separate Sun servers in real time. Remote Mirror is conceptually
-similar to the local disk mirroring scheme of RAID 1 but it performs its
-replication operations over longer distances.
-.sp
-.LP
-If you do not specify a Remote Mirror set (\fIsndr_set\fR) on the command line,
-\fBsndradm\fR operates on all configured Remote Mirror sets.
-.sp
-.LP
-The \fBsndradm\fR command generates an entry in the Availability Suite log
-file, \fB/var/adm/ds.log\fR (see \fBds.log\fR(4)), for all operations except
-print (\fB-p\fR, \fB-P\fR and \fB-i\fR), help (\fB-h\fR), and version
-(\fB-v\fR).
-.SH OPTIONS
-.sp
-.LP
-The \fBsndradm\fR utility supports the following options:
-.sp
-.ne 2
-.na
-\fB\fB-f\fR \fIvolset-file\fR\fR
-.ad
-.sp .6
-.RS 4n
-Specifies a file containing the \fIsndr_set\fR information for one or more
-Remote Mirror sets in the same format as the fully specified command line
-\fIsndr_set\fR documented below.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-g\fR \fIio_groupname\fR\fR
-.ad
-.sp .6
-.RS 4n
-Limits operations to only those Remote Mirror sets belonging to
-\fIio_groupname\fR.
-.sp
-The \fIio_groupname\fR for a given set must be consistent across both the
-primary and the secondary hosts.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-C\fR \fItag\fR\fR
-.ad
-.sp .6
-.RS 4n
-On a clustered node, limits operations to only those Remote Mirror sets
-belonging to the cluster resource group or disk group name specified by
-\fItag\fR. This option is not valid on a system that is not clustered.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-n\fR\fR
-.ad
-.sp .6
-.RS 4n
-Does not prompt the user after starting a Remote Mirror operation using
-\fBsndradm\fR. For all but the printing, help, and version options, the default
-behavior is to prompt for a response. For example, after starting a full
-synchronization from the primary to the secondary volume, Remote Mirror
-prompts: \fB"Overwrite secondary with primary? (Y/N) [N]"\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fIsndr_set\fR\fR
-.ad
-.sp .6
-.RS 4n
-Specifies the Remote Mirror set. For a set that has already been enabled, this
-can be a \fBset_name\fR in the format \fIshost\fR:\fIsdev\fR. You can supply a
-fully specified Remote Mirror set in the same format as a configuration file:
-.sp
-.in +2
-.nf
-\fIphost pdev pbitmap shost sdev sbitmap\fR \fBip\fR {\fBsync | async\fR} \e
-[g \fIio_groupname\fR] [C \fItag\fR]
-.fi
-.in -2
-
-These parameters are described as follows:
-.sp
-.ne 2
-.na
-\fB\fIphost\fR\fR
-.ad
-.sp .6
-.RS 4n
-Specifies the server on which the primary volume resides.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fIpdev\fR\fR
-.ad
-.sp .6
-.RS 4n
-Specifies the primary volume partition to be replicated. Specify full pathnames
-only (for example, \fB/dev/rdsk/c0t1d0s2\fR).
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fIpbitmap\fR\fR
-.ad
-.sp .6
-.RS 4n
-Specifies the volume partition on which the bitmap (scoreboard log) of the
-primary partition is stored. Specify full pathnames only (for example,
-\fB/dev/rdsk/c0t1d0s3\fR).
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fIshost\fR\fR
-.ad
-.sp .6
-.RS 4n
-Specifies the server on which the secondary volume resides.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fIsdev\fR\fR
-.ad
-.sp .6
-.RS 4n
-Specifies the secondary volume partition. Specify full path names only (for
-example, \fB/dev/rdsk/c0t1d0s4\fR).
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fIsbitmap\fR\fR
-.ad
-.sp .6
-.RS 4n
-Specifies the volume partition on which the bitmap (scoreboard log) of the
-secondary partition is stored. Specify full path names only (for example,
-\fB/dev/rdsk/c0t1d0s5\fR).
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBip\fR\fR
-.ad
-.sp .6
-.RS 4n
-Specifies the network transfer protocol.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBsync | async\fR\fR
-.ad
-.sp .6
-.RS 4n
-Specifies the Remote Mirror operating mode. \fBsync\fR is the Remote Mirror
-mode where the I/O operation is not confirmed as complete until the remote
-volume has been updated. \fBasync\fR is the Remote Mirror mode where the
-primary host I/O operation is confirmed as complete before updating the remote
-volume.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fIio_groupname\fR\fR
-.ad
-.sp .6
-.RS 4n
-Specifies the name of the Remote Mirror consistency group to which the Remote
-Mirror set belongs. In asynchronous mode, write ordering must be preserved
-across all replicating volumes in a Remote Mirror consistency group. This
-ensures that the secondary volumes belonging to the group contains a valid
-point-in-time copy of the corresponding primary volumes.
-.sp
-When adding an existing set to a consistency group or when enabling a set to be
-in a group, the set must be configured with the same group name on both the
-primary and the secondary hosts.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fItag\fR\fR
-.ad
-.sp .6
-.RS 4n
-For operation within a cluster, this specifies the disk group name or resource
-tag of the local data and bitmap volumes in cases where this is not implied by
-the name of the volume (for example, \fB/dev/rdsk/md/dg/vol\fR and
-\fB/dev/vx/rdsk/dg/vol\fR both indicate a disk group name of \fBdg\fR). It is
-the responsibility of the user to ensure that the cluster tag specified to the
-Remote Mirror matches the appropriate cluster resource group tag, and to keep
-all the Availability Suite services up to date in the event of cluster resource
-group reconfigurations. It is illegal to specify the cluster resource tag on a
-system that is not clustered.
-.RE
-
-.RE
-
-.SH PARAMETERS
-.sp
-.LP
-A valid \fBsndradm\fR command must specify one of the parameters listed below.
-.sp
-.ne 2
-.na
-\fB\fB-I\fR \fBa\fR \fImaster\fR \fIshadow\fR \fIbitmap\fR\fR
-.ad
-.sp .6
-.RS 4n
-Add an \fBndr_ii\fR entry with the specified master, shadow, and bitmap to the
-Availability Suite configuration file. See \fBsndrsyncd\fR(1M). If the
-corresponding Point-in-Time Copy set does not exist, it is enabled when the
-next \fBsync\fR command is issued on the related volume(s). When no longer
-required, this Point-in-Time Copy set can be disabled by \fBiiadm\fR \fB-d\fR.
-See \fBiiadm\fR(1M)
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-I\fR \fBd\fR \fImaster\fR \fB\fIshadow\fR\fR \fB\fIbitmap\fR\fR\fR
-.ad
-.sp .6
-.RS 4n
-Delete the \fBndr_ii\fR entry with the specified master, shadow, and bitmap
-from the Availability Suite configuration file. Use the \fBdscfg\fR command to
-list \fBndr_ii\fR configuration entries.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-a\fR \fIvalue\fR\fR
-.ad
-.sp .6
-.RS 4n
-Specifies the value, on or off, of the automatic sync variable for the set.
-Once \fBautosync\fR has been requested for a set, the functionality is active
-from the time a sync operation is requested until the set is manually put into
-logging mode. Once the set is manually put into logging mode, the
-\fBautosync\fR functionality is not active and remains inactive until the next
-time a \fBsync\fR request is made. To check whether \fBautosync\fR is active,
-use \fBsndradm\fR \fB-P\fR. To check whether autosync has been requested for a
-set, look for the"\fBauto=on;\fR" tag for the set in the output of \fBdscfg\fR
-\fB-l\fR. See \fBsndrsyncd\fR(1M).
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-A\fR \fIvalue\fR\fR
-.ad
-.sp .6
-.RS 4n
-Specifies the maximum number of threads that can be created to process the
-asynchronous queue when a set is replicating in asynchronous mode. The default
-is \fB2\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-W\fR \fIvalue\fR\fR
-.ad
-.sp .6
-.RS 4n
-Specifies the maximum number of writes that can be queued to a set replicating
-in asynchronous mode. The default is \fB4096\fR. For example, set this value to
-1 to ensure that the secondary volume is never more than one write operation
-behind the primary volume.
-.sp
-Tuning the maximum number of writes is only valid for sets using memory-based
-async I/O queues. This value is ignored when disk based I/O queues are used.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-D\fR \fB{block\fR \fB|\fR \fBnoblock}\fR\fR
-.ad
-.sp .6
-.RS 4n
-Toggles the \fBblock\fR|\fBnoblock\fR attribute of a disk-based queue. The
-default setting is \fBblock\fR. If the I/O fill rate is larger than the drain
-rate for enough time for the queue to fill, incoming I/O is blocked until there
-is adequate space on the queue for it. This is to preserve write ordering
-whether it is one volume or across many volumes in the same consistency group.
-If \fBnoblock\fR is set, and incoming I/O fills the queue, the I/O is not
-blocked. Instead, the set is put into logging and the disk queue contents are
-disregarded. An ensuing update sync synchronizes the latest data to the
-secondary site.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-F\fR \fIvalue\fR\fR
-.ad
-.sp .6
-.RS 4n
-Specifies the maximum number of 512-byte FBAs that can be queued in kernel
-memory to a set replicating in asynchronous mode. The default is \fB16384\fR.
-.sp
-Tuning the maximum number of FBAs is valid only for sets using memory-based
-async I/O queues. This value isignored when disk-based I/O queues are used.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-h\fR\fR
-.ad
-.sp .6
-.RS 4n
-Prints the \fBsndradm\fR usage summary.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-v\fR\fR
-.ad
-.sp .6
-.RS 4n
-Prints the Remote Mirror version number.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-e\fR\fR
-.ad
-.sp .6
-.RS 4n
-Enables Remote Mirror for the set and enables scoreboard logging. The
-scoreboard is set to indicate that a full synchronization is required. Details
-of the set are saved in the current configuration. See \fBdscfg\fR(1M). The
-local volume and the bitmap volume are enabled for the Storage Volume driver
-(see \fBsv\fR(7D)).
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-E\fR\fR
-.ad
-.sp .6
-.RS 4n
-Enables Remote Mirror for the set and enables scoreboard logging. The
-scoreboard is cleared to indicate that the primary and secondary volumes are
-already guaranteed to be fully synchronized. Details of the set are saved in
-the current configuration. See \fBdscfg\fR(1M). The local volume and the bitmap
-volume are enabled for the Storage Volume driver (see \fBsv\fR(7D)).
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-d\fR\fR
-.ad
-.sp .6
-.RS 4n
-Disables Remote Mirror for the set and halts any current synchronization
-operations. \fBsndradm\fR \fB-d\fR also discards any active scoreboards that
-track temporary differences between primary and secondary volumes.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-l\fR\fR
-.ad
-.sp .6
-.RS 4n
-Stops Remote Mirror replication and copy operations between primary and
-secondary volumes and starts independent Remote Mirror scoreboard logging on
-these volumes. When all the sets in a consistency group are replicating, it
-means that the secondary volumes contain a valid point-in-time copy of the
-corresponding primary volumes. Under this condition, as soon as one Remote
-Mirror set drops into logging mode, the \fBrdc\fR kernel module drops all the
-other sets in the group into logging mode automatically. This ensures that the
-secondary volumes still contains a valid point-in-time copy. To resume the
-Remote Mirror after using the \fB-l\fR parameter, use the \fB-m\fR parameter to
-perform a full resynchronization or the \fB-u\fR parameter to perform an update
-resynchronization (based on the scoreboard).
-.sp
-This option does not work on the secondary for any volumes that are currently
-synchronizing.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-w\fR\fR
-.ad
-.sp .6
-.RS 4n
-Waits for a synchronization copy to complete or abort, or returns immediately
-if invoked on the secondary system.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-H\fR\fR
-.ad
-.sp .6
-.RS 4n
-Reports on the health of the network link used by the specified volume set. The
-health of the link is reported as active or inactive. Active means that the
-network link is actively being used for replicating or resynchronizing data,
-and is therefore in good health. Inactive means that the network link is not
-actively being used for replicating or resynchronizing data, which might
-indicate a problem with the link.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-p\fR\fR
-.ad
-.sp .6
-.RS 4n
-Displays a list of configured Remote Mirror volumes or sets.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-P\fR\fR
-.ad
-.sp .6
-.RS 4n
-Displays a list of configured Remote Mirror volumes or sets with extra details.
-(See state descriptions, below.)
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-q\fR \fBa\fR \fIvolume\fR\fR
-.ad
-.sp .6
-.RS 4n
-Add a disk queue to a set or group. This operation is valid when the set or
-group is in logging mode.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-q\fR \fBd\fR\fR
-.ad
-.sp .6
-.RS 4n
-Remove a disk queue from a set or group. This operation is valid when the set
-or group is in logging mode.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-q\fR \fBr\fR \fIvolume\fR\fR
-.ad
-.sp .6
-.RS 4n
-Replace a disk queue for a group or set. The queue is removed from the set or
-group as in the queue-disable operation and the new disk queue is added as in
-the queue-add operation. This operation is valid when the set or group is in
-logging mode.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-i\fR\fR
-.ad
-.sp .6
-.RS 4n
-Displays a list of configured Remote Mirror volumes or sets in the same format
-as the \fIvolset-file\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-R\fR\fR
-.ad
-.sp .6
-.RS 4n
-Attempt to reset a Remote Mirror set's error condition such as failed bitmaps.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-R\fR \fBb\fR \fBp\fR \fIbitmap\fR\fR
-.ad
-.sp .6
-.RS 4n
-Reconfigure a Remote Mirror set's primary bitmap. This command should be
-entered on both primary and secondary servers. It is only possible to
-reconfigure the primary bitmap for one set at a time.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-R\fR \fBb\fR \fBs\fR \fIbitmap\fR\fR
-.ad
-.sp .6
-.RS 4n
-Reconfigure a Remote Mirror set's secondary bitmap. This command should be
-entered on both primary and secondary servers. It is only possible to
-reconfigure the secondary bitmap for one set at a time.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-R\fR \fBC\fR \fItag\fR\fR
-.ad
-.sp .6
-.RS 4n
-Reconfigure the cluster tag, or disk group name, of a Remote Mirror set's local
-volumes, in those cases where this is not indicated by the pathname. This does
-not affect the remote volumes. This parameter cannot be used on a system that
-is not clustered.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-R\fR \fBm\fR \fB{sync\fR \fB|\fR \fBasync}\fR\fR
-.ad
-.sp .6
-.RS 4n
-Reconfigure the replication mode of a Remote Mirror set. The sets belonging to
-a consistency group must be either all synchronous or all asynchronous. It is
-not possible to mix modes within a group.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-R\fR \fBg\fR \fIgroup\fR\fR
-.ad
-.sp .6
-.RS 4n
-Reconfigure the consistency group of a Remote Mirror set. This command should
-be entered with the same group name on both primary and secondary servers.
-.sp
-To remove a set from a consistency group, specify the null string (" ") when
-reconfiguring the consistency group.
-.RE
-
-.sp
-.LP
-The following parameters can be issued only from the primary server:
-.sp
-.ne 2
-.na
-\fB\fB-m\fR\fR
-.ad
-.sp .6
-.RS 4n
-Starts a full volume copy from the primary volume to the secondary volume, and
-concurrently enables Remote Mirror replication of new updates from the primary
-volume to the secondary volume. Use this parameter when the primary and
-secondary volumes might be different and no logging information exists to
-incrementally resynchronize the volumes. See EXIT STATUS.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-r\fR\fR
-.ad
-.sp .6
-.RS 4n
-Reverses the direction of the synchronization so the primary volume is
-synchronized from the secondary volume. Use this parameter with the \fB-m\fR or
-\fB-u\fR parameter. \fB-m\fR \fB-r\fR starts a full volume copy from the
-secondary (source) volume to the primary (target) volume but concurrently
-enables Remote Mirror replication of new updates from the primary (source)
-volume to the secondary (target) volume, ensuring the volume sets remain
-synchronized. Use \fB-m\fR \fB-r\fR when the primary and secondary volume
-content might differ and the secondary has the desired contents, yet no logging
-information exists to incrementally resynchronize the volumes (using \fB-u\fR).
-\fB-u\fR \fB-r\fR resynchronizes the primary (target) volume from the secondary
-(source) volume, using the Remote Mirror scoreboard logs maintained while
-replication was suspended. It then resumes Remote Mirror replication of new
-updates from the primary volume to the secondary volume so that the volume sets
-remain synchronized. Quiesce the workload to the volume sets during the
-restore/refresh operation. This action ensures that the primary and secondary
-volumes match before replication of new updates resumes.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-u\fR\fR
-.ad
-.sp .6
-.RS 4n
-Updates a Remote Mirror volume set. This parameter resynchronizes a Remote
-Mirror volume set. Only the blocks logged as changed in the Remote Mirror
-scoreboards are updated. Enables Remote Mirror replication for the primary
-volume and also uses the Remote Mirror scoreboard logs to start the
-resynchronization process so that the corresponding secondary volume matches
-the primary volume.
-.RE
-
-.SS "States Returned from \fBsndradm\fR \fB-P\fR"
-.sp
-.LP
-The following are the states that can be returned from \fBsndradm\fR \fB-P\fR.
-.sp
-.ne 2
-.na
-\fB\fBvolume\fR \fBfailed\fR\fR
-.ad
-.sp .6
-.RS 4n
-An I/O operation to the local data volume has failed
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBbitmap\fR \fBfailed\fR\fR
-.ad
-.sp .6
-.RS 4n
-An I/O operation to the local bitmap volume has failed
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBdisk\fR \fBqueue\fR \fBfailed\fR\fR
-.ad
-.sp .6
-.RS 4n
-An I/O operation to disk queue volume has failed
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBneed\fR \fBsync\fR\fR
-.ad
-.sp .6
-.RS 4n
-A sync to this volume has been interrupted. It needs to be completed (or
-restored via Point-in-Time Copy). The direction of the data flow must not be
-changed until one or the other is done.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBneed\fR \fBreverse\fR \fBsync\fR\fR
-.ad
-.sp .6
-.RS 4n
-A reverse sync to this volume has been interrupted. It needs to be completed
-(or restored via Point-in-Time Copy). The direction of the data flow must not
-be changed until one or the other is done.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBlogging\fR\fR
-.ad
-.sp .6
-.RS 4n
-Incoming writes are logged in the bitmap only. Data is not replicated to the
-remote site. \fBneed sync\fR, \fBneed reverse sync\fR, and \fBqueuing\fR are
-all substates of logging such that writes are logged in the bitmap, but not
-replicated. Queuing mode (described below) logs the writes to the bitmap, and
-queues the request for later replication by the async flushers.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBreverse\fR \fBsyncing\fR\fR
-.ad
-.sp .6
-.RS 4n
-A secondary to primary copy is in progress.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBsyncing\fR\fR
-.ad
-.sp .6
-.RS 4n
-A primary to secondary copy is in progress.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBqueuing\fR\fR
-.ad
-.sp .6
-.RS 4n
-During normal async replication using disk queues, i/o is placed on the disk
-queue to be replicated by the async flusher threads. In the event of a
-temporary link failure, the set transitions to queuing mode. The queue is not
-discarded, as it would be with memory based queues. Instead, data is logged in
-the bitmap and placed on the queue. When the link comes up, and \fBsndradm\fR
-\fB-u\fR is issued, (automated by turning autosync on for the set) the flushers
-restarts. This preserves write ordering through a temporary link outage. If
-write ordering is not necessary, and only the latest data is needed, the set
-can be put into logging manually (\fBsndradm\fR \fB-l\fR) and an update sync
-issued (\fBsndradm\fR \fB-u\fR). This action discards the data on the queue,
-and fast resyncs using the bitmap. If the queue fills before the link comes
-back and the update sync is issued, the queue is discarded and the set put into
-logging mode to avoid application hangs.
-.RE
-
-.SH EXAMPLES
-.LP
-\fBExample 1 \fREnabling a Remote Mirror Set
-.sp
-.LP
-The following command enables a Remote Mirror asynchronous set on host
-\fBexample\fR, where \fBexample\fR is the primary host and \fBexample-remote\fR
-is the secondary host.
-
-.sp
-.in +2
-.nf
-example% \fBsndradm -e example /dev/rdsk/c1t0d0s1 /dev/rdsk/c1t1d0s3 \e
-example-remote /dev/rdsk/c2t3d0s5 /dev/rdsk/c2t4d0s5 ip async\fR
-.fi
-.in -2
-.sp
-
-.LP
-\fBExample 2 \fRAdding a Disk Queue to an Asynchronous Set
-.sp
-.LP
-The following command adds a disk queue volume to an asynchronous set.
-
-.sp
-.in +2
-.nf
-example% \fBsndradm -q a /dev/rdsk/c1t2d0s3 \e
-example-remote:/dev/rdsk/c2t3d0s5\fR
-.fi
-.in -2
-.sp
-
-.LP
-\fBExample 3 \fRRemoving a Disk Queue from an Asynchronous Set
-.sp
-.LP
-The following command removes the disk queue volume from a set with a disk
-queue volume attatched to it.
-
-.sp
-.in +2
-.nf
-example% \fBsndradm -q d example-remote:/dev/rdsk/c2t3d0s5\fR
-.fi
-.in -2
-.sp
-
-.LP
-\fBExample 4 \fRDisabling a Remote Mirror Set
-.sp
-.LP
-The following command disables a Remote Mirror set enabled on host
-\fBexample\fR.
-
-.sp
-.in +2
-.nf
-example% \fBsndradm -d example-remote:/dev/rdsk/c2t3d0s5\fR
-.fi
-.in -2
-.sp
-
-.SH EXIT STATUS
-.sp
-.ne 2
-.na
-\fB\fB0\fR\fR
-.ad
-.RS 13n
-Command completed successfully.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB>0\fR\fR
-.ad
-.RS 13n
-An error occurred.
-.RE
-
-.sp
-.LP
-When the \fB-m\fR or \fB-u\fR option is executed in a script, the exit status
-following one of these options always returns success, regardless of the
-current status of the Remote Mirror set.
-.SH ATTRIBUTES
-.sp
-.LP
-See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
-.TS
-box;
-c | c
-l | l .
-ATTRIBUTE TYPE ATTRIBUTE VALUE
-_
-Interface Stability Evolving
-.TE
-
-.SH SEE ALSO
-.sp
-.LP
-\fBdscfg\fR(1M), \fBsndrd\fR(1M), \fBsndrsyncd\fR(1M), \fBds.log\fR(4),
-\fBrdc.cf\fR(4), \fBattributes\fR(5), \fBsv\fR(7D)
diff --git a/usr/src/man/man1m/sndrd.1m b/usr/src/man/man1m/sndrd.1m
deleted file mode 100644
index 0a44a95e97..0000000000
--- a/usr/src/man/man1m/sndrd.1m
+++ /dev/null
@@ -1,150 +0,0 @@
-'\" te
-.\" Copyright (c) 2007, Sun Microsystems, Inc. All rights reserved.
-.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
-.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
-.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH SNDRD 1M "Dec 11, 2015"
-.SH NAME
-sndrd \- Remote Mirror daemon
-.SH SYNOPSIS
-.LP
-.nf
-\fB/usr/lib/sndrd\fR [\fB-c\fR \fImax_connections\fR] [\fB-l\fR \fIlisten_backlog\fR]
-.fi
-
-.SH DESCRIPTION
-.LP
-The \fBsndrd\fR daemon processes client Remote Mirror requests. Only the root
-user or a user with equivalent privileges can run this daemon. The daemon is
-automatically invoked in run level 2. \fBsndrd\fR restarts the TCP transport
-layers.
-.sp
-.LP
-Administrators wanting to change startup parameters for \fBsndrd\fR should, as
-root or equivalent, make changes in the \fB/etc/default/sndr\fR file rather
-than editing the \fB/lib/svc/method/svc-rdcsyncd\fR file. See \fBsndr\fR(4).
-.SH OPTIONS
-.LP
-The \fBsndrd\fR daemon supports the following options:
-.sp
-.ne 2
-.na
-\fB\fB-c\fR \fImax_connections\fR\fR
-.ad
-.sp .6
-.RS 4n
-Sets the maximum number of connections allowed to the server over
-connection-oriented transports. By default, the number of connections is 16.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-l\fR \fIlisten_backlog\fR\fR
-.ad
-.sp .6
-.RS 4n
-Sets connection queue length for the RDC TCP over a connection-oriented
-transport. The default value is 10 entries.
-.RE
-
-.SH EXIT STATUS
-.ne 2
-.na
-\fB\fB0\fR\fR
-.ad
-.RS 13n
-Daemon started successfully.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB>0\fR\fR
-.ad
-.RS 13n
-Daemon failed to start.
-.RE
-
-.sp
-.LP
-Error information is reported to \fBsyslog\fR at level \fBLOG_ERR\fR.
-.SH FILES
-.ne 2
-.na
-\fB\fB/lib/svc/method/svc-rdcsyncd\fR\fR
-.ad
-.sp .6
-.RS 4n
-Shell script for starting \fBsndrd\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB/lib/svc/method/svc-rdc\fR\fR
-.ad
-.sp .6
-.RS 4n
-Shell script for stopping \fBsndrd\fR.
-.RE
-
-.SH ATTRIBUTES
-.LP
-See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
-.TS
-box;
-c | c
-l | l .
-ATTRIBUTE TYPE ATTRIBUTE VALUE
-_
-Interface Stability Evolving
-.TE
-
-.SH SEE ALSO
-.LP
-\fBsvcadm\fR(1M), \fBsyslogd\fR(1M), \fBds.log\fR(4), \fBattributes\fR(5)
-.SH NOTES
-.LP
-Do not manually stop the sndrd daemon. If you need to manually stop sndrd
-perform these steps. This stops both the \fBsndrd\fR and \fBsndrsyncd\fR
-daemons.
-.sp
-.in +2
-.nf
-# svcadm disable svc:/system/nws_rdc
-.fi
-.in -2
-
-.sp
-.in +2
-.nf
-# svcadm disable svc:/system/nws_rdcsyncd
-.fi
-.in -2
-
-.sp
-.LP
-Do not manually start or restart the sndrd daemon. If you need to manually
-start sndrd perform these steps. This starts both the sndrd and sndrsyncd
-daemons.
-.sp
-.in +2
-.nf
-# svcadm enable svc:/system/nws_rdc
-.fi
-.in -2
-
-.sp
-.in +2
-.nf
-# svcadm enable svc:/system/nws_rdcsyncd
-.fi
-.in -2
-
-.sp
-.LP
-See \fBsvcadm\fR(1M) for additional information.
diff --git a/usr/src/man/man1m/sndrsyncd.1m b/usr/src/man/man1m/sndrsyncd.1m
deleted file mode 100644
index ea7b081933..0000000000
--- a/usr/src/man/man1m/sndrsyncd.1m
+++ /dev/null
@@ -1,132 +0,0 @@
-'\" te
-.\" Copyright (c) 2007, Sun Microsystems, Inc. All rights reserved.
-.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
-.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
-.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH SNDRSYNCD 1M "Dec 11, 2015"
-.SH NAME
-sndrsyncd \- Availability Suite Remote Mirror update resynchronization daemon
-.SH SYNOPSIS
-.LP
-.nf
-\fB/usr/lib/sndrsyncd\fR
-.fi
-
-.SH DESCRIPTION
-.LP
-The \fBsndrsyncd\fR daemon automates update resynchronization after a network
-or machine failure and invokes Point-in-Time Copy copies when needed to protect
-the data volumes being updated during a resynchronization.
-.sp
-.LP
-The daemon is notified by the kernel when a network link being used by Remote
-Mirror goes down and invokes the \fBsndradm\fR(1M) command with the \fB-u\fR
-option to resynchronize all Remote Mirror sets which have autosync switched on
-and are using the network link. See \fBsndradm\fR(1M) for details on how to
-configure autosync for a Remote Mirror set.
-.sp
-.LP
-The daemon is also notified when any Remote Mirror resynchronization starts or
-completes. The daemon takes Point-in-Time Copy snapshots, if configured in the
-Availability Suite configuration file. On a secondary server, the daemon checks
-if a file system is currently mounted on the secondary volume and informs the
-kernel not to allow the synchronization to start if the file system is
-currently mounted.
-.SH EXIT STATUS
-.ne 2
-.na
-\fB\fB0\fR\fR
-.ad
-.RS 13n
-Daemon started successfully.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB>0\fR\fR
-.ad
-.RS 13n
-Daemon failed to start.
-.RE
-
-.SH FILES
-.ne 2
-.na
-\fB\fB/lib/svc/method/svc-rdcsyncd\fR\fR
-.ad
-.sp .6
-.RS 4n
-Shell script for starting \fBsndrsyncd\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB/lib/svc/method/svc-rdc\fR\fR
-.ad
-.sp .6
-.RS 4n
-Shell script for stopping \fBsndrsyncd\fR.
-.RE
-
-.SH ATTRIBUTES
-.LP
-See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
-.TS
-box;
-c | c
-l | l .
-ATTRIBUTE TYPE ATTRIBUTE VALUE
-_
-Interface Stability Evolving
-.TE
-
-.SH SEE ALSO
-.LP
-\fBiiadm\fR(1M), \fBsndradm\fR(1M), \fBsndrd\fR(1M), \fBsvcadm\fR(1M),
-\fBds.log\fR(4), \fBrdc.cf\fR(4), \fBattributes\fR(5)
-.SH NOTES
-.LP
-Do not manually stop the sndrsyncd daemon. If you need to manually stop
-sndrsyncd perform these steps. This stops both the \fBsndrd\fR and
-\fBsndrsyncd\fR daemons.
-.sp
-.in +2
-.nf
-# svcadm disable svc:/system/nws_rdc
-.fi
-.in -2
-
-.sp
-.in +2
-.nf
-# svcadm disable svc:/system/nws_rdcsyncd
-.fi
-.in -2
-
-.sp
-.LP
-Do not manually start or restart the \fBsndrsyncd\fR daemon. If you need to
-manually start \fBsndrsyncd\fR perform these steps. This starts both the
-\fBsndrd\fR and \fBsndrsyncd\fR daemons.
-.sp
-.in +2
-.nf
-# svcadm enable svc:/system/nws_rdc
-.fi
-.in -2
-
-.sp
-.in +2
-.nf
-# svcadm enable svc:/system/nws_rdcsyncd
-.fi
-.in -2
-
-.sp
-.LP
-See \fBsvcadm\fR(1M) for additional information.
diff --git a/usr/src/man/man1m/svadm.1m b/usr/src/man/man1m/svadm.1m
deleted file mode 100644
index 82ba35ba94..0000000000
--- a/usr/src/man/man1m/svadm.1m
+++ /dev/null
@@ -1,181 +0,0 @@
-'\" te
-.\" Copyright (c) 2007, Sun Microsystems, Inc. All rights reserved.
-.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
-.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
-.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH SVADM 1M "Oct 2, 2007"
-.SH NAME
-svadm \- command line interface to control Availability Suite Storage Volume
-operations
-.SH SYNOPSIS
-.LP
-.nf
-\fBsvadm\fR \fB-h\fR
-.fi
-
-.LP
-.nf
-\fBsvadm\fR \fB-v\fR
-.fi
-
-.LP
-.nf
-\fBsvadm\fR [\fB-C\fR \fItag\fR]
-.fi
-
-.LP
-.nf
-\fBsvadm\fR [\fB-C\fR \fItag\fR] \fB-i\fR
-.fi
-
-.LP
-.nf
-\fBsvadm\fR [\fB-C\fR \fItag\fR] \fB-e\fR {\fB-f\fR \fIconfig_file\fR | volume}
-.fi
-
-.LP
-.nf
-\fBsvadm\fR [\fB-C\fR \fItag\fR] \fB-d\fR {\fB-f\fR \fIconfig_file\fR | volume}
-.fi
-
-.LP
-.nf
-\fBsvadm\fR [\fB-C\fR \fItag\fR] \fB-r\fR {\fB-f\fR \fIconfig_file\fR | volume}
-.fi
-
-.SH DESCRIPTION
-.LP
-The \fBsvadm\fR command controls the Storage Volume (SV) driver by providing
-facilities to enable and disable the SV driver for specified volumes, and to
-dynamically reconfigure the system.
-.SH OPTIONS
-.LP
-If you specify no arguments to an \fBsvadm\fR command, the utility displays the
-list of volumes currently under SV control. \fBsvadm\fR supports the following
-options:
-.sp
-.ne 2
-.na
-\fB\fB-C\fR \fItag\fR\fR
-.ad
-.sp .6
-.RS 4n
-On a clustered node, limits operations to only those volumes belonging to the
-cluster resource group, or disk group name, specified by tag. This option is
-illegal on a system that is not clustered. The special \fItag\fR, \fBlocal\fR,
-can be used to limit operations to only those volumes that cannot switch over
-to other nodes in the cluster.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-d\fR\fR
-.ad
-.sp .6
-.RS 4n
-Disables the SV devices specified on the command line or in the configuration
-file. If \fB-C\fR tag is specified with this option, then the volume should be
-in this cluster disk group.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-e\fR\fR
-.ad
-.sp .6
-.RS 4n
-Enables the SV devices specified on the command line or in the configuration
-file. Details of the volume are saved in the current configuration. See
-\fBdscfg\fR(1M). If \fB-C\fR tag is specified with this option, then the volume
-should be in this cluster disk group.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-f\fR \fIconfig_file\fR\fR
-.ad
-.sp .6
-.RS 4n
-Specifies a configuration file that contains a list of volumes. A command reads
-this volume list and then perform the operation. The format of the
-\fIconfig_file\fR is a simple list of volume pathnames, one per line. Blank
-lines and lines starting with the comment character (#) are ignored.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-h\fR\fR
-.ad
-.sp .6
-.RS 4n
-Displays the \fBsvadm\fR usage summary.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-i\fR\fR
-.ad
-.sp .6
-.RS 4n
-Displays extended status for the volumes currently under SV control.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-r\fR\fR
-.ad
-.sp .6
-.RS 4n
-When a \fIconfig_file\fR is specified, reconfigure the running system to match
-the configuration specified in the \fIconfig_file\fR. When the \fB-C\fR option
-is specified, compare the cluster tag for each volume and change it to
-\fIcluster_tag\fR. If a volume is specified with this option, it is valid only
-to reconfigure the cluster tag associated with the volume. The \fB-e\fR or
-\fB-d\fR options should be used to enable or disable single volumes.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-v\fR\fR
-.ad
-.sp .6
-.RS 4n
-Displays the SV version number.
-.RE
-
-.SH USAGE
-.LP
-When an SV volume is enabled, normal system call access to the device (see
-\fBIntro\fR(2)) is redirected into the StoreEdge architecture software. This
-allows standard applications to use StorageTek features such as Sun StorageTek
-Point-in-Time Copy and Remote Mirror Software.
-.sp
-.LP
-The \fBsvadm\fR command generates an entry in the Availability Suite log file,
-\fB/var/adm/ds.log\fR (see \fBds.log\fR(4)), when performing enable (\fB-e\fR)
-and disable (\fB-d\fR) operations.
-.SH ATTRIBUTES
-.LP
-See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
-.TS
-box;
-c | c
-l | l .
-ATTRIBUTE TYPE ATTRIBUTE VALUE
-_
-Interface Stability Evolving
-.TE
-
-.SH SEE ALSO
-.LP
-\fBdscfg\fR(1M), \fBds.log\fR(4), \fBattributes\fR(5), \fBsv\fR(7D)
diff --git a/usr/src/man/man4/Makefile b/usr/src/man/man4/Makefile
index fd60281537..2008cfee3b 100644
--- a/usr/src/man/man4/Makefile
+++ b/usr/src/man/man4/Makefile
@@ -12,7 +12,7 @@
#
# Copyright 2011, Richard Lowe
# Copyright 2015, Joyent, Inc.
-# Copyright 2016 Nexenta Systems, Inc.
+# Copyright 2018 Nexenta Systems, Inc.
# Copyright 2018 Gary Mills
#
@@ -60,7 +60,6 @@ _MANFILES= Intro.4 \
dialups.4 \
dir_ufs.4 \
driver.conf.4 \
- ds.log.4 \
ethers.4 \
exec_attr.4 \
fdi.4 \
@@ -157,7 +156,6 @@ _MANFILES= Intro.4 \
publickey.4 \
queuedefs.4 \
rcmscript.4 \
- rdc.cf.4 \
remote.4 \
resolv.conf.4 \
rmtab.4 \
@@ -178,7 +176,6 @@ _MANFILES= Intro.4 \
smb.4 \
smbautohome.4 \
smhba.conf.4 \
- sndr.4 \
sock2path.d.4 \
space.4 \
sulog.4 \
diff --git a/usr/src/man/man4/ds.log.4 b/usr/src/man/man4/ds.log.4
deleted file mode 100644
index 41d85fe865..0000000000
--- a/usr/src/man/man4/ds.log.4
+++ /dev/null
@@ -1,112 +0,0 @@
-'\" te
-.\" Copyright (C) 2007 Sun Microsystems, Inc. All Rights Reserved
-.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
-.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
-.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH DS.LOG 4 "Jun 08, 2007"
-.SH NAME
-ds.log \- Availability Suite data services log file
-.SH DESCRIPTION
-.sp
-.LP
-The \fB/var/adm/ds.log\fR file contains the Availability Suite data services
-command log. The administration commands log activities to the file in the
-format:
-.sp
-.in +2
-.nf
-date time product: message
-.fi
-.in -2
-
-.sp
-.LP
-Note that when the size of the log file exceeds 10 Mbytes, ds.log is renamed
-\fB/var/adm/ds.log.bak\fR and a new \fB/var/adm/ds.log\fR file is created.
-.sp
-.LP
-The \fBds.log\fR fields are:
-.sp
-.ne 2
-.na
-\fBdate\fR
-.ad
-.sp .6
-.RS 4n
-The date format is \fImmm nn\fR, where \fImmm\fR is the local three-character
-abbreviation for the month and \fInn\fR is the day of the month on which the
-event occurred.
-.RE
-
-.sp
-.ne 2
-.na
-\fBtime\fR
-.ad
-.sp .6
-.RS 4n
-The time of the event, in \fIhh:mm:ss\fR format.
-.RE
-
-.sp
-.ne 2
-.na
-\fBproduct\fR
-.ad
-.sp .6
-.RS 4n
-A product code that identifies which component of the data services produced
-the event. The code is separated from the message that follows by a colon (:)
-and a space.
-.RE
-
-.sp
-.ne 2
-.na
-\fBmessage\fR
-.ad
-.sp .6
-.RS 4n
-A message that can extend over more than one line describing the event that
-occurred. The second or following lines are not prefixed by the date, time,
-and product code strings.
-.RE
-
-.SH EXAMPLES
-.sp
-.LP
-The example below shows sample \fBds.log\fR file content:
-.sp
-.in +2
-.nf
-Jan 25 05:26:17 ii: iiboot suspend cluster tag <none>
-Jan 25 05:32:02 ii: iiboot resume cluster tag <none>
-Jan 25 05:32:04 sv: svboot: resume /dev/vx/rdsk/bigmaster
-Jan 25 05:32:04 sv: svboot: resume /dev/vx/rdsk/bigshadow
-Jan 25 05:32:04 sv: svboot: resume /dev/vx/rdsk/mstvxfs
-Jan 25 05:32:04 sv: svboot: resume /dev/vx/rdsk/master01
-.fi
-.in -2
-
-.SH ATTRIBUTES
-.sp
-.LP
-See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
-.TS
-box;
-c | c
-l | l .
-ATTRIBUTE TYPE ATTRIBUTE VALUE
-_
-Architecture x86
-_
-Interface Stability Committed
-.TE
-
-.SH SEE ALSO
-.sp
-.LP
-\fBiiadm\fR(1M), \fBsndradm\fR(1M), \fBsvadm\fR(1M), \fBattributes\fR(5)
diff --git a/usr/src/man/man4/rdc.cf.4 b/usr/src/man/man4/rdc.cf.4
deleted file mode 100644
index 10c8e4be8a..0000000000
--- a/usr/src/man/man4/rdc.cf.4
+++ /dev/null
@@ -1,166 +0,0 @@
-'\" te
-.\" Copyright (C) 2007 Sun Microsystems, Inc. All Rights Reserved
-.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
-.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
-.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH RDC.CF 4 "Jun 08, 2007"
-.SH NAME
-rdc.cf \- Availability Suite Remote Mirror software configuration file
-.SH DESCRIPTION
-.sp
-.LP
-The \fBrdc.cf\fR is an optional configuration file that supplies the
-\fBsndradm\fR(1M) command with details of the volume sets to be operated on.
-Inrdc.cf, the volume sets and their host locations are defined in the
-following format:
-.sp
-.in +2
-.nf
-post pdevice pbitmap shost sdevice sbitmap protocol mode options
-.fi
-.in -2
-
-.sp
-.LP
-The \fBrdc.cf\fR fields are:
-.sp
-.ne 2
-.na
-\fBphost (primary host)\fR
-.ad
-.sp .6
-.RS 4n
-Server on which the primary volume resides.
-.RE
-
-.sp
-.ne 2
-.na
-\fBpdevice (primary device)\fR
-.ad
-.sp .6
-.RS 4n
-Primary volume partition to be copied. Specify only full path names (for
-example, /dev/rdsk/c0t1d0s2).
-.RE
-
-.sp
-.ne 2
-.na
-\fBpbitmap (primary bitmap)\fR
-.ad
-.sp .6
-.RS 4n
-Volume partition in which the bitmap (scoreboard logs) of the primary
-partition is stored. Specify only full path names (for example,
-/dev/rdsk/c0t1d0s3).
-.RE
-
-.sp
-.ne 2
-.na
-\fBshost (secondary host)\fR
-.ad
-.sp .6
-.RS 4n
-Server on which the secondary volume resides.
-.RE
-
-.sp
-.ne 2
-.na
-\fBsdevice (secondary device)\fR
-.ad
-.sp .6
-.RS 4n
-Secondary volume partition. Specify only full path names (for
-example,\fB/dev/rdsk/c0t1d0s4\fR).
-.RE
-
-.sp
-.ne 2
-.na
-\fBsbitmap (secondary bitmap)\fR
-.ad
-.sp .6
-.RS 4n
-Volume partition in which the bitmap (scoreboard logs) of the secondary file
-is stored. Specify only full path names (for example,
-\fB/dev/rdsk/c0t1d0s5\fR).
-.RE
-
-.sp
-.ne 2
-.na
-\fBprotocol\fR
-.ad
-.sp .6
-.RS 4n
-Network transfer protocol. Specify IP.
-.RE
-
-.sp
-.ne 2
-.na
-\fBmode\fR
-.ad
-.sp .6
-.RS 4n
-Remote Mirror operating mode. Sync is the Remote Mirror mode where the I/O
-operation is not confirmed as complete until the remote volume has been
-updated. Async is the other Remote Mirror mode, in which the primary host I/O
-operation is confirmed as complete before updating the remote volume.
-.RE
-
-.sp
-.ne 2
-.na
-\fBoptions\fR
-.ad
-.sp .6
-.RS 4n
-A consistency group name can be specified using the g character. A disk queue
-volume partition can be specified using the q character, using full path name
-only (/dev/rdsk/c0t1d0s5). Without the q character set will default to memory
-base queue. When running on a clustered system, a cluster resource group tag
-can be specified using the C character.
-.sp
-These options have the following syntax:
-.sp
-.in +2
-.nf
-[g io_groupname] [q queue_volume][C ctag]
-.fi
-.in -2
-
-.LP
-Note -
-.sp
-.RS 2
-When running on a cluster configuration, the cluster resource group tag is
-appended to the Remote Mirror set by default.
-.RE
-.RE
-
-.SH ATTRIBUTES
-.sp
-.LP
-See \fBattributes\fR(5) for a description of the following attributes:
-.sp
-
-.sp
-.TS
-box;
-c | c
-l | l .
-ATTRIBUTE TYPE ATTRIBUTE VALUE
-_
-Architecture x86
-_
-Interface Stability Committed
-.TE
-
-.SH SEE ALSO
-.sp
-.LP
-\fBsndradm\fR(1M), \fBsndrd\fR(1M), \fBattributes\fR(5)
diff --git a/usr/src/man/man4/sndr.4 b/usr/src/man/man4/sndr.4
deleted file mode 100644
index df709d12d0..0000000000
--- a/usr/src/man/man4/sndr.4
+++ /dev/null
@@ -1,89 +0,0 @@
-'\" te
-.\" Copyright (C) 2007 Sun Microsystems, Inc. All Rights Reserved
-.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
-.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
-.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH SNDR 4 "Jun 08, 2007"
-.SH NAME
-sndr \- SNDR parameter values
-.SH SYNOPSIS
-.LP
-.nf
-\fB/etc/default/sndr\fR
-.fi
-
-.SH DESCRIPTION
-.sp
-.LP
-The \fBsndr\fR file resides in \fB/etc/default\fR and provides startup
-parameters for the \fBsndrd\fR(1M) and \fBsndrsyncd\fR(1M) daemons.
-.sp
-.LP
-The \fBsndr\fR file format is ASCII and comment lines begin with the crosshatch
-(#) character. Parameters consist of a keyword followed by an equal (=) sign
-followed by the parameter value of the form:
-.sp
-.in +2
-.nf
-keyword=value
-.fi
-.in -2
-
-.sp
-.LP
-The following parameters are currently supported in the \fBsndr\fR file:
-.sp
-.ne 2
-.na
-\fBSNDR_THREADS=num\fR
-.ad
-.sp .6
-.RS 4n
-Sets the maximum number of connections allowed to the server over
-connection-oriented transports. By default, the number of connections is 16.
-.RE
-
-.sp
-.ne 2
-.na
-\fBSNDR_LISTEN_BACKLOG=num\fR
-.ad
-.sp .6
-.RS 4n
-Sets connection queue length for the RDC TCP over a connection-oriented
-transport. The default value is 10 entries.
-.RE
-
-.sp
-.ne 2
-.na
-\fBSNDR_TRANSPORT=string\fR
-.ad
-.sp .6
-.RS 4n
-Sets the transport used for the RDC connection. If IPv6 is installed, the
-default value is "\fB/dev/tcp\fR" or "\fB/dev/tcp6\fR."
-.RE
-
-.SH ATTRIBUTES
-.sp
-.LP
-See \fBattributes\fR(5) for a description of the following attributes:
-.sp
-
-.sp
-.TS
-box;
-c | c
-l | l .
-ATTRIBUTE TYPE ATTRIBUTE VALUE
-_
-Architecture x86
-_
-Interface Stability Committed
-.TE
-
-.SH SEE ALSO
-.sp
-.LP
-\fBsndrd\fR(1M), \fBsndrsyncd\fR(1M)
diff --git a/usr/src/man/man7d/Makefile b/usr/src/man/man7d/Makefile
index e74632b315..f27ddf6131 100644
--- a/usr/src/man/man7d/Makefile
+++ b/usr/src/man/man7d/Makefile
@@ -14,7 +14,7 @@
# Copyright 2016 Garrett D'Amore <garrett@damore.org>
# Copyright (c) 2017, Joyent, Inc.
# Copyright 2016 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
-# Copyright 2017 Nexenta Systems, Inc.
+# Copyright 2018 Nexenta Systems, Inc.
#
include $(SRC)/Makefile.master
@@ -70,7 +70,6 @@ _MANFILES= aac.7d \
ibtl.7d \
ieee1394.7d \
igb.7d \
- ii.7d \
ipnet.7d \
iscsi.7d \
iser.7d \
@@ -121,7 +120,6 @@ _MANFILES= aac.7d \
sgen.7d \
srpt.7d \
st.7d \
- sv.7d \
sysmsg.7d \
systrace.7d \
ticlts.7d \
diff --git a/usr/src/man/man7d/ii.7d b/usr/src/man/man7d/ii.7d
deleted file mode 100644
index cb6ad9dfed..0000000000
--- a/usr/src/man/man7d/ii.7d
+++ /dev/null
@@ -1,104 +0,0 @@
-'\" te
-.\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved
-.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
-.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
-.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH II 7D "Jun 8, 2007"
-.SH NAME
-ii \- Instant Image control device
-.SH DESCRIPTION
-.sp
-.LP
-The \fBii\fR device is a control interface for Instant Image devices and
-controls the Instant Image module through the \fBioctl\fR(2) interface.
-.sp
-.LP
-Instant Image is a point-in-time volume copy facility for the Solaris operating
-environment that is administered through the \fBiiadm\fR(1M) command. With
-Instant Image, you can create an independent point-in-time copy of a volume or
-a master volume-dependent point-in-time view. You can also independently
-access the master and shadow volume for read and write operations. Instant
-Image also lets you update the shadow volume from the master volume or restore
-the master volume from the shadow. (Restore operations to volumes can be full
-or incremental). Instant Image supports fast volume re-synchronization, letting
-you create a new point-in-time volume copy by updating the specified volume
-with only changed data.
-.sp
-.LP
-To create a shadow volume you need a:
-.RS +4
-.TP
-1.
-Master volume to be shadowed.
-.RE
-.RS +4
-.TP
-2.
-Shadow volume where the copy will reside. This volume must be equal to or
-larger than the master volume.
-.RE
-.RS +4
-.TP
-3.
-Administrative bitmap volume or file for tracking differences between the
-shadow and master volumes. The administrative bitmap volume or file must be at
-least 24Kbytes in size and requires 8KBytes for each GByte (or part thereof) of
-master volume size, plus an additional 8KBytes overhead. For example, to shadow
-a 3GByte master volume, the administration volume must be 8KBytes + (3 *
-8KBytes) =32KBytes in size.
-.RE
-.sp
-.LP
-The Instant Image module uses services provided by the SDBC and SD_GEN modules.
-The SV module is required to present a conventional block device interface to
-the storage product interface of the Instant Image, SDBC and SD_GEN modules.
-.sp
-.LP
-When a shadow operation is suspended or resumed, the administration volumes may
-be stored in permanent SDBC storage or loaded and saved to and from kernel
-memory. The ii_bitmap variable in the \fB/kernel/drv/ii.conf\fR configuration
-file determines the administration volume storage type. A value of 0 indicates
-kernel memory, while a value of 1 indicates permanent SDBC storage. If the
-system is part of a storage products cluster, use the 1 value (permanent
-storage), otherwise use kernel memory (0 value).
-.SH FILES
-.sp
-.ne 2
-.na
-\fB\fBkernel/drv/ii\fR\fR
-.ad
-.RS 23n
-32- bit ELF kernel module (x86).
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB/kernel/drv/ii.conf\fR\fR
-.ad
-.RS 23n
-Configuration file.
-.RE
-
-.SH ATTRIBUTES
-.sp
-.LP
-See \fBattributes\fR(5) for a description of the following attributes:
-.sp
-
-.sp
-.TS
-box;
-c | c
-l | l .
-ATTRIBUTE TYPE ATTRIBUTE VALUE
-_
-Architecture x86
-_
-Interface Stability Committed
-.TE
-
-.SH SEE ALSO
-.sp
-.LP
-\fBiiadm\fR(1M), \fBioctl\fR(2), \fBattributes\fR(5), \fBsv\fR(7D)
diff --git a/usr/src/man/man7d/sv.7d b/usr/src/man/man7d/sv.7d
deleted file mode 100644
index 9872538986..0000000000
--- a/usr/src/man/man7d/sv.7d
+++ /dev/null
@@ -1,47 +0,0 @@
-'\" te
-.\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved
-.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
-.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
-.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH SV 7D "Jun 8, 2007"
-.SH NAME
-sv \- Storage Volume system call device
-.SH DESCRIPTION
-.sp
-.LP
-The \fBsv\fR driver allows standard system call access (see \fBIntro\fR(2)) to
-a disk device to be redirected into the StorageTek architecture software. This
-enables standard applications to use Sun StorageTek Availability Suite
-components such as Point-in-Time Copy and Remote Mirror software.
-.SH FILES
-.sp
-.ne 2
-.na
-\fB\fBkernel/drv/sv\fR\fR
-.ad
-.RS 17n
-SV control and administration driver.
-.RE
-
-.SH ATTRIBUTES
-.sp
-.LP
-See \fBattributes\fR(5) for a description of the following attributes:
-.sp
-
-.sp
-.TS
-box;
-c | c
-l | l .
-ATTRIBUTE TYPE ATTRIBUTE VALUE
-_
-Architecture x86
-_
-Interface Stability Committed
-.TE
-
-.SH SEE ALSO
-.sp
-.LP
-\fBiiadm\fR(1M)
diff --git a/usr/src/pkg/manifests/driver-storage-sv.mf b/usr/src/pkg/manifests/driver-storage-sv.mf
index a30d0b8777..d5711099e8 100644
--- a/usr/src/pkg/manifests/driver-storage-sv.mf
+++ b/usr/src/pkg/manifests/driver-storage-sv.mf
@@ -23,70 +23,6 @@
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
#
-#
-# The default for payload-bearing actions in this package is to appear in the
-# global zone only. See the include file for greater detail, as well as
-# information about overriding the defaults.
-#
-<include global_zone_only_component>
set name=pkg.fmri value=pkg:/driver/storage/sv@$(PKGVERS)
-set name=pkg.description \
- value="Raw/Block Device Interface to Storage Volumes (SV)"
-set name=pkg.summary value="Sun StorageTek Availability Suite Volume Driver"
-set name=info.classification \
- value=org.opensolaris.category.2008:Drivers/Storage
+set name=pkg.obsolete value=true
set name=variant.arch value=$(ARCH)
-dir path=etc group=sys
-dir path=etc/init.d group=sys
-dir path=kernel group=sys
-dir path=kernel/kmdb group=sys
-dir path=kernel/kmdb/$(ARCH64) group=sys
-dir path=lib
-dir path=lib/svc
-dir path=lib/svc/manifest group=sys
-dir path=lib/svc/manifest/system group=sys
-dir path=lib/svc/method
-dir path=usr group=sys
-dir path=usr/bin
-dir path=usr/cluster group=sys
-dir path=usr/cluster/lib
-dir path=usr/cluster/lib/dscfg
-dir path=usr/cluster/lib/dscfg/start
-dir path=usr/cluster/lib/dscfg/stop
-dir path=usr/cluster/sbin group=other
-dir path=usr/kernel group=sys
-dir path=usr/kernel/drv group=sys
-dir path=usr/kernel/drv/$(ARCH64) group=sys
-dir path=usr/lib
-dir path=usr/lib/mdb group=sys
-dir path=usr/lib/mdb/kvm group=sys
-dir path=usr/lib/mdb/kvm/$(ARCH64) group=sys
-dir path=usr/sbin
-dir path=usr/share/man
-dir path=usr/share/man/man1m
-dir path=usr/share/man/man7d
-driver name=sv devlink=type=ddi_pseudo;name=sv\t\D perms="* 0666 root sys" \
- privs=sys_config privs=sys_devices
-file path=etc/init.d/sv mode=0744
-file path=etc/init.d/sv.cluster mode=0744
-file path=kernel/kmdb/$(ARCH64)/sv group=sys mode=0555
-file path=lib/svc/manifest/system/nws_sv.xml group=sys mode=0444
-file path=usr/bin/svadm mode=0555
-file path=usr/bin/svboot mode=0555
-file path=usr/cluster/sbin/sv mode=0744
-file path=usr/kernel/drv/$(ARCH64)/sv group=sys
-file path=usr/kernel/drv/sv.conf group=sys
-file path=usr/lib/mdb/kvm/$(ARCH64)/sv.so group=sys mode=0555
-file path=usr/share/man/man1m/svadm.1m
-file path=usr/share/man/man7d/sv.7d
-hardlink path=lib/svc/method/svc-sv target=../../../etc/init.d/sv
-hardlink path=usr/sbin/svadm target=../bin/svadm
-hardlink path=usr/sbin/svboot target=../bin/svboot
-legacy pkg=SUNWspsvr desc="Raw/Block Device Interface to Storage Volumes (SV)" \
- name="Sun StorageTek Availability Suite Volume Driver (root)"
-legacy pkg=SUNWspsvu desc="Raw/Block Device Interface to Storage Volumes (SV)" \
- name="Sun StorageTek Availability Suite Volume Driver (usr)"
-license cr_Sun license=cr_Sun
-license lic_CDDL license=lic_CDDL
-link path=usr/cluster/lib/dscfg/start/15sv target=../../../sbin/sv
-link path=usr/cluster/lib/dscfg/stop/10sv target=../../../sbin/sv
diff --git a/usr/src/pkg/manifests/service-storage-avs-cache-management.mf b/usr/src/pkg/manifests/service-storage-avs-cache-management.mf
index c92b461a39..6800ba2fca 100644
--- a/usr/src/pkg/manifests/service-storage-avs-cache-management.mf
+++ b/usr/src/pkg/manifests/service-storage-avs-cache-management.mf
@@ -23,112 +23,6 @@
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
#
-#
-# The default for payload-bearing actions in this package is to appear in the
-# global zone only. See the include file for greater detail, as well as
-# information about overriding the defaults.
-#
-<include global_zone_only_component>
set name=pkg.fmri value=pkg:/service/storage/avs/cache-management@$(PKGVERS)
-set name=pkg.description \
- value="Storage Cache Management of read-only bitmap volumes"
-set name=pkg.summary \
- value="Sun StorageTek Availability Suite Cache Management"
-set name=info.classification \
- value="org.opensolaris.category.2008:System/Enterprise Management"
+set name=pkg.obsolete value=true
set name=variant.arch value=$(ARCH)
-dir path=etc group=sys
-dir path=etc/init.d group=sys
-dir path=kernel group=sys
-dir path=kernel/kmdb group=sys
-dir path=kernel/kmdb/$(ARCH64) group=sys
-dir path=lib
-dir path=lib/svc
-dir path=lib/svc/manifest group=sys
-dir path=lib/svc/manifest/system group=sys
-dir path=lib/svc/method
-dir path=usr group=sys
-dir path=usr/bin
-dir path=usr/cluster group=sys
-dir path=usr/cluster/lib
-dir path=usr/cluster/lib/start
-dir path=usr/cluster/lib/stop
-dir path=usr/cluster/sbin group=other
-dir path=usr/kernel group=sys
-dir path=usr/kernel/drv group=sys
-dir path=usr/kernel/drv/$(ARCH64) group=sys
-dir path=usr/kernel/misc group=sys
-dir path=usr/kernel/misc/$(ARCH64) group=sys
-dir path=usr/lib
-dir path=usr/lib/mdb group=sys
-dir path=usr/lib/mdb/kvm group=sys
-dir path=usr/lib/mdb/kvm/$(ARCH64) group=sys
-dir path=usr/sbin
-dir path=usr/share/man
-dir path=usr/share/man/man1m
-dir path=usr/share/man/man4
-driver name=ncall devlink=type=ddi_pseudo;name=ncall\t\D \
- perms="* 0666 root sys" privs=sys_config privs=sys_devices
-driver name=nsctl devlink=type=ddi_pseudo;name=nsctl\t\D \
- perms="* 0666 root sys" privs=sys_config privs=sys_devices
-driver name=nskern devlink=type=ddi_pseudo;name=nskern\t\D \
- perms="* 0666 root sys" privs=sys_config privs=sys_devices
-driver name=sdbc devlink=type=ddi_pseudo;name=sdbc\t\D perms="* 0666 root sys" \
- privs=sys_config privs=sys_devices
-file path=etc/dscfg_format group=sys mode=0744
-file path=etc/init.d/scm mode=0744
-file path=kernel/kmdb/$(ARCH64)/nsctl group=sys mode=0555
-file path=kernel/kmdb/$(ARCH64)/sdbc group=sys mode=0555
-file path=lib/svc/manifest/system/nws_scm.xml group=sys mode=0444
-file path=usr/bin/dsbitmap mode=0555
-file path=usr/bin/dscfg mode=0555
-file path=usr/bin/dscfg_reconfigure.cluster mode=0555
-file path=usr/bin/dscfgadm mode=0555
-file path=usr/bin/dscfglockd mode=0555
-file path=usr/bin/dsstat mode=0555
-file path=usr/bin/ncalladm mode=0555
-file path=usr/bin/nscadm mode=0555
-file path=usr/bin/nskernd mode=0555
-file path=usr/bin/scmadm mode=0555
-file path=usr/kernel/drv/$(ARCH64)/ncall group=sys
-file path=usr/kernel/drv/$(ARCH64)/nsctl group=sys
-file path=usr/kernel/drv/$(ARCH64)/nskern group=sys
-file path=usr/kernel/drv/$(ARCH64)/sdbc group=sys
-file path=usr/kernel/drv/ncall.conf group=sys
-file path=usr/kernel/drv/nsctl.conf group=sys
-file path=usr/kernel/drv/nskern.conf group=sys
-file path=usr/kernel/drv/sdbc.conf group=sys
-file path=usr/kernel/misc/$(ARCH64)/spuni group=sys mode=0755
-file path=usr/lib/libdscfg.so.1
-file path=usr/lib/libnsctl.so.1
-file path=usr/lib/libunistat.so.1
-file path=usr/lib/mdb/kvm/$(ARCH64)/nsctl.so group=sys mode=0555
-file path=usr/lib/mdb/kvm/$(ARCH64)/sdbc.so group=sys mode=0555
-file path=usr/share/man/man1m/dsbitmap.1m
-file path=usr/share/man/man1m/dscfg.1m
-file path=usr/share/man/man1m/dscfgadm.1m
-file path=usr/share/man/man1m/dscfglockd.1m
-file path=usr/share/man/man1m/dsstat.1m
-file path=usr/share/man/man1m/nscadm.1m
-file path=usr/share/man/man1m/scmadm.1m
-file path=usr/share/man/man4/ds.log.4
-hardlink path=lib/svc/method/svc-scm target=../../../etc/init.d/scm
-hardlink path=usr/cluster/sbin/dscfg_reconfigure \
- target=../../bin/dscfg_reconfigure.cluster
-hardlink path=usr/lib/dscfglockd target=../bin/dscfglockd
-hardlink path=usr/lib/ncalladm target=../bin/ncalladm
-hardlink path=usr/lib/nskernd target=../bin/nskernd
-hardlink path=usr/sbin/dsbitmap target=../bin/dsbitmap
-hardlink path=usr/sbin/dscfg target=../bin/dscfg
-hardlink path=usr/sbin/dscfgadm target=../bin/dscfgadm
-hardlink path=usr/sbin/dsstat target=../bin/dsstat
-hardlink path=usr/sbin/nscadm target=../bin/nscadm
-hardlink path=usr/sbin/scmadm target=../bin/scmadm
-legacy pkg=SUNWscmr \
- desc="Storage Cache Management of read-only bitmap volumes" \
- name="Sun StorageTek Availability Suite Cache Management (root)"
-legacy pkg=SUNWscmu \
- desc="Storage Cache Management of read-only bitmap volumes" \
- name="Sun StorageTek Availability Suite Cache Management (usr)"
-license cr_Sun license=cr_Sun
-license lic_CDDL license=lic_CDDL
diff --git a/usr/src/pkg/manifests/storage-avs-point-in-time-copy.mf b/usr/src/pkg/manifests/storage-avs-point-in-time-copy.mf
index a1c40ee323..20ba7c235a 100644
--- a/usr/src/pkg/manifests/storage-avs-point-in-time-copy.mf
+++ b/usr/src/pkg/manifests/storage-avs-point-in-time-copy.mf
@@ -23,77 +23,6 @@
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
#
-#
-# The default for payload-bearing actions in this package is to appear in the
-# global zone only. See the include file for greater detail, as well as
-# information about overriding the defaults.
-#
-<include global_zone_only_component>
set name=pkg.fmri value=pkg:/storage/avs/point-in-time-copy@$(PKGVERS)
-set name=pkg.description value="Point-In-Time Copy and snapshot facility"
-set name=pkg.summary \
- value="Sun StorageTek Availability Suite Point-In-Time Copy"
-set name=info.classification \
- value="org.opensolaris.category.2008:System/Enterprise Management"
+set name=pkg.obsolete value=true
set name=variant.arch value=$(ARCH)
-dir path=etc group=sys
-dir path=etc/init.d group=sys
-dir path=kernel group=sys
-dir path=kernel/kmdb group=sys
-dir path=kernel/kmdb/$(ARCH64) group=sys
-dir path=lib
-dir path=lib/svc
-dir path=lib/svc/manifest group=sys
-dir path=lib/svc/manifest/system group=sys
-dir path=lib/svc/method
-dir path=usr group=sys
-dir path=usr/bin
-dir path=usr/cluster group=sys
-dir path=usr/cluster/lib
-dir path=usr/cluster/lib/dscfg
-dir path=usr/cluster/lib/dscfg/start
-dir path=usr/cluster/lib/dscfg/stop
-dir path=usr/cluster/sbin group=other
-dir path=usr/kernel group=sys
-dir path=usr/kernel/drv group=sys
-dir path=usr/kernel/drv/$(ARCH64) group=sys
-dir path=usr/lib
-dir path=usr/lib/mdb group=sys
-dir path=usr/lib/mdb/kvm group=sys
-dir path=usr/lib/mdb/kvm/$(ARCH64) group=sys
-dir path=usr/sbin
-dir path=usr/share/man
-dir path=usr/share/man/man1m
-dir path=usr/share/man/man7d
-driver name=ii devlink=type=ddi_pseudo;name=ii\t\D perms="* 0666 root sys" \
- privs=sys_config privs=sys_devices
-file path=etc/init.d/ii mode=0744
-file path=etc/init.d/ii.cluster mode=0744
-file path=kernel/kmdb/$(ARCH64)/ii group=sys mode=0555
-file path=lib/svc/manifest/system/nws_ii.xml group=sys mode=0444
-file path=usr/bin/iiadm mode=0555
-file path=usr/bin/iiboot mode=0555
-file path=usr/bin/iicpbmp mode=0555
-file path=usr/bin/iicpshd mode=0555
-file path=usr/cluster/sbin/ii mode=0744
-file path=usr/kernel/drv/$(ARCH64)/ii group=sys
-file path=usr/kernel/drv/ii.conf group=sys \
- original_name=SUNWii:usr/kernel/drv/ii.conf preserve=true
-file path=usr/lib/mdb/kvm/$(ARCH64)/ii.so group=sys mode=0555
-file path=usr/share/man/man1m/iiadm.1m
-file path=usr/share/man/man1m/iicpbmp.1m
-file path=usr/share/man/man1m/iicpshd.1m
-file path=usr/share/man/man7d/ii.7d
-hardlink path=lib/svc/method/svc-ii target=../../../etc/init.d/ii
-legacy pkg=SUNWiir desc="Point-In-Time Copy and snapshot facility" \
- name="Sun StorageTek Availability Suite Point-In-Time Copy (root)"
-legacy pkg=SUNWiiu desc="Point-In-Time Copy and snapshot facility" \
- name="Sun StorageTek Availability Suite Point-In-Time Copy (usr)"
-license cr_Sun license=cr_Sun
-license lic_CDDL license=lic_CDDL
-link path=usr/cluster/lib/dscfg/start/05ii target=../../../sbin/ii
-link path=usr/cluster/lib/dscfg/stop/20ii target=../../../sbin/ii
-link path=usr/sbin/iiadm target=../bin/iiadm
-link path=usr/sbin/iiboot target=../bin/iiboot
-link path=usr/sbin/iicpbmp target=../bin/iicpbmp
-link path=usr/sbin/iicpshd target=../bin/iicpshd
diff --git a/usr/src/pkg/manifests/storage-avs-remote-mirror.mf b/usr/src/pkg/manifests/storage-avs-remote-mirror.mf
index adbf53c0bf..c710709388 100644
--- a/usr/src/pkg/manifests/storage-avs-remote-mirror.mf
+++ b/usr/src/pkg/manifests/storage-avs-remote-mirror.mf
@@ -23,92 +23,6 @@
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
#
-#
-# The default for payload-bearing actions in this package is to appear in the
-# global zone only. See the include file for greater detail, as well as
-# information about overriding the defaults.
-#
-<include global_zone_only_component>
set name=pkg.fmri value=pkg:/storage/avs/remote-mirror@$(PKGVERS)
-set name=pkg.description \
- value="Remote Mirror copy software provides replication across IP networks"
-set name=pkg.summary value="Sun StorageTek Availability Suite Remote Mirror"
-set name=info.classification \
- value=org.opensolaris.category.2008:System/Hardware
+set name=pkg.obsolete value=true
set name=variant.arch value=$(ARCH)
-dir path=etc group=sys
-dir path=etc/init.d group=sys
-dir path=kernel group=sys
-dir path=kernel/kmdb group=sys
-dir path=kernel/kmdb/$(ARCH64) group=sys
-dir path=lib
-dir path=lib/svc
-dir path=lib/svc/manifest group=sys
-dir path=lib/svc/manifest/system group=sys
-dir path=lib/svc/method
-dir path=usr group=sys
-dir path=usr/bin
-dir path=usr/cluster group=sys
-dir path=usr/cluster/lib
-dir path=usr/cluster/lib/dscfg
-dir path=usr/cluster/lib/dscfg/start
-dir path=usr/cluster/lib/dscfg/stop
-dir path=usr/cluster/sbin group=other
-dir path=usr/kernel group=sys
-dir path=usr/kernel/drv group=sys
-dir path=usr/kernel/drv/$(ARCH64) group=sys
-dir path=usr/kernel/misc group=sys
-dir path=usr/kernel/misc/$(ARCH64) group=sys
-dir path=usr/lib
-dir path=usr/lib/mdb group=sys
-dir path=usr/lib/mdb/kvm group=sys
-dir path=usr/lib/mdb/kvm/$(ARCH64) group=sys
-dir path=usr/sbin
-dir path=usr/share/man
-dir path=usr/share/man/man1m
-dir path=usr/share/man/man4
-driver name=rdc devlink=type=ddi_pseudo;name=rdc\t\D perms="* 0666 root sys" \
- privs=sys_config privs=sys_devices
-file path=etc/init.d/rdc mode=0744
-file path=etc/init.d/rdc.cluster mode=0744
-file path=etc/init.d/rdcfinish mode=0744
-file path=kernel/kmdb/$(ARCH64)/rdc group=sys mode=0555
-file path=lib/svc/manifest/system/nws_rdc.xml group=sys mode=0444
-file path=lib/svc/manifest/system/nws_rdcsyncd.xml group=sys mode=0444
-file path=usr/bin/sndradm mode=0555
-file path=usr/bin/sndrboot mode=0555
-file path=usr/bin/sndrd mode=0555
-file path=usr/bin/sndrsyncd mode=0555
-file path=usr/cluster/sbin/rdc mode=0744
-file path=usr/kernel/drv/$(ARCH64)/rdc group=sys
-file path=usr/kernel/drv/$(ARCH64)/rdcsrv group=sys
-file path=usr/kernel/drv/$(ARCH64)/rdcstub group=sys
-file path=usr/kernel/drv/rdc.conf group=sys \
- original_name=SUNWrdc:usr/kernel/drv/rdc.conf preserve=true
-file path=usr/lib/librdc.so.1
-file path=usr/lib/mdb/kvm/$(ARCH64)/rdc.so group=sys mode=0555
-file path=usr/share/man/man1m/sndradm.1m
-file path=usr/share/man/man1m/sndrd.1m
-file path=usr/share/man/man1m/sndrsyncd.1m
-file path=usr/share/man/man4/rdc.cf.4
-file path=usr/share/man/man4/sndr.4
-hardlink path=lib/svc/method/svc-rdc target=../../../etc/init.d/rdc
-hardlink path=lib/svc/method/svc-rdcsyncd target=../../../etc/init.d/rdcfinish
-hardlink path=usr/kernel/misc/$(ARCH64)/rdcsrv \
- target=../../drv/$(ARCH64)/rdcsrv
-hardlink path=usr/kernel/misc/$(ARCH64)/rdcstub \
- target=../../drv/$(ARCH64)/rdcstub
-hardlink path=usr/lib/sndrd target=../bin/sndrd
-hardlink path=usr/lib/sndrsyncd target=../bin/sndrsyncd
-hardlink path=usr/sbin/sndradm target=../bin/sndradm
-hardlink path=usr/sbin/sndrboot target=../bin/sndrboot
-legacy pkg=SUNWrdcr \
- desc="Remote Mirror copy software provides replication across IP networks" \
- name="Sun StorageTek Availability Suite Remote Mirror (root)"
-legacy pkg=SUNWrdcu \
- desc="Remote Mirror copy software provides replication across IP networks" \
- name="Sun StorageTek Availability Suite Remote Mirror (usr)"
-license cr_Sun license=cr_Sun
-license lic_CDDL license=lic_CDDL
-link path=usr/cluster/lib/dscfg/start/10rdc target=../../../sbin/rdc
-link path=usr/cluster/lib/dscfg/stop/15rdc target=../../../sbin/rdc
diff --git a/usr/src/pkg/manifests/storage-avs.mf b/usr/src/pkg/manifests/storage-avs.mf
index b8a0ecf915..ecc9686a93 100644
--- a/usr/src/pkg/manifests/storage-avs.mf
+++ b/usr/src/pkg/manifests/storage-avs.mf
@@ -23,13 +23,6 @@
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
#
-set name=pkg.fmri \
- value=pkg:/storage/avs@0.1,$(PKGVERS_BUILTON)-$(PKGVERS_BRANCH)
-set name=pkg.summary value="Availability Suite"
-set name=info.classification \
- value=org.opensolaris.category.2008:Drivers/Storage
+set name=pkg.fmri value=pkg:/storage/avs@$(PKGVERS)
+set name=pkg.obsolete value=true
set name=variant.arch value=$(ARCH)
-depend fmri=driver/storage/sv type=require
-depend fmri=service/storage/avs/cache-management type=require
-depend fmri=storage/avs/point-in-time-copy type=require
-depend fmri=storage/avs/remote-mirror type=require
diff --git a/usr/src/uts/Makefile b/usr/src/uts/Makefile
index dbd7eeb94a..d03de46952 100644
--- a/usr/src/uts/Makefile
+++ b/usr/src/uts/Makefile
@@ -18,11 +18,12 @@
#
# CDDL HEADER END
#
+
#
# Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
-# Copyright 2012 Nexenta Systems, Inc. All rights reserved.
+# Copyright 2018 Nexenta Systems, Inc.
#
-# include global definitions
+
include ../Makefile.master
#
@@ -131,8 +132,7 @@ $(PMTMO_FILE) pmtmo_file: $(PATCH_MAKEUP_TABLE)
# the architecture/machine dependent subdirectories are in completely
# isomorphic locations.
#
-COMMON_HDRDIRS= common/avs \
- common/c2 \
+COMMON_HDRDIRS= common/c2 \
common/des \
common/fs \
common/gssapi \
@@ -163,10 +163,9 @@ COMMON_HDRDIRS= common/avs \
# Subset of COMMON_HDRDIRS in which at least one header is generated
# at runtime (e.g., rpcgen), and in which "make clean" should run.
# Other directories should be included here, but do not yet have the
-# necessary Makefile support (make clean). See 6414855.
+# necessary Makefile support (make clean).
#
-DYNHDRDIRS = common/avs \
- common/gssapi \
+DYNHDRDIRS = common/gssapi \
common/idmap \
common/io/fibre-channel/fca/qlc \
common/klm \
diff --git a/usr/src/uts/common/Makefile.files b/usr/src/uts/common/Makefile.files
index f06d10c527..43f3aacb75 100644
--- a/usr/src/uts/common/Makefile.files
+++ b/usr/src/uts/common/Makefile.files
@@ -23,7 +23,7 @@
# Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2011, 2014 by Delphix. All rights reserved.
# Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
-# Copyright 2015 Nexenta Systems, Inc. All rights reserved.
+# Copyright 2018 Nexenta Systems, Inc.
# Copyright 2016 Garrett D'Amore <garrett@damore.org>
# Copyright (c) 2017, Joyent, Inc.
# Copyright 2016 OmniTI Computer Consulting, Inc. All rights reserved.
@@ -865,72 +865,6 @@ SBP2_OBJS += cfgrom.o sbp2.o
PMODEM_OBJS += pmodem.o pmodem_cis.o cis.o cis_callout.o cis_handlers.o cis_params.o
-DSW_OBJS += dsw.o dsw_dev.o ii_tree.o
-
-NCALL_OBJS += ncall.o \
- ncall_stub.o
-
-RDC_OBJS += rdc.o \
- rdc_dev.o \
- rdc_io.o \
- rdc_clnt.o \
- rdc_prot_xdr.o \
- rdc_svc.o \
- rdc_bitmap.o \
- rdc_health.o \
- rdc_subr.o \
- rdc_diskq.o
-
-RDCSRV_OBJS += rdcsrv.o
-
-RDCSTUB_OBJS += rdc_stub.o
-
-SDBC_OBJS += sd_bcache.o \
- sd_bio.o \
- sd_conf.o \
- sd_ft.o \
- sd_hash.o \
- sd_io.o \
- sd_misc.o \
- sd_pcu.o \
- sd_tdaemon.o \
- sd_trace.o \
- sd_iob_impl0.o \
- sd_iob_impl1.o \
- sd_iob_impl2.o \
- sd_iob_impl3.o \
- sd_iob_impl4.o \
- sd_iob_impl5.o \
- sd_iob_impl6.o \
- sd_iob_impl7.o \
- safestore.o \
- safestore_ram.o
-
-NSCTL_OBJS += nsctl.o \
- nsc_cache.o \
- nsc_disk.o \
- nsc_dev.o \
- nsc_freeze.o \
- nsc_gen.o \
- nsc_mem.o \
- nsc_ncallio.o \
- nsc_power.o \
- nsc_resv.o \
- nsc_rmspin.o \
- nsc_solaris.o \
- nsc_trap.o \
- nsc_list.o
-UNISTAT_OBJS += spuni.o \
- spcs_s_k.o
-
-NSKERN_OBJS += nsc_ddi.o \
- nsc_proc.o \
- nsc_raw.o \
- nsc_thread.o \
- nskernd.o
-
-SV_OBJS += sv.o
-
PMCS_OBJS += pmcs_attach.o pmcs_ds.o pmcs_intr.o pmcs_nvram.o pmcs_sata.o \
pmcs_scsa.o pmcs_smhba.o pmcs_subr.o pmcs_fwlog.o
diff --git a/usr/src/uts/common/Makefile.rules b/usr/src/uts/common/Makefile.rules
index b4f66cc991..9bf6f18a26 100644
--- a/usr/src/uts/common/Makefile.rules
+++ b/usr/src/uts/common/Makefile.rules
@@ -24,7 +24,7 @@
# Copyright 2016 Garrett D'Amore <garrett@damore.org>
# Copyright 2013 Saso Kiselkov. All rights reserved.
# Copyright 2016 Joyent, Inc.
-# Copyright 2016 Nexenta Systems, Inc.
+# Copyright 2018 Nexenta Systems, Inc.
# Copyright (c) 2016 by Delphix. All rights reserved.
#
@@ -454,38 +454,6 @@ $(OBJS_DIR)/%.o: $(KMECHKRB5_BASE)/profile/%.c
$(COMPILE.c) $(KGSSDFLAGS) -o $@ $<
$(CTFCONVERT_O)
-$(OBJS_DIR)/%.o: $(UTSBASE)/common/avs/ncall/%.c
- $(COMPILE.c) -o $@ $<
- $(CTFCONVERT_O)
-
-$(OBJS_DIR)/%.o: $(UTSBASE)/common/avs/ns/dsw/%.c
- $(COMPILE.c) -o $@ $<
- $(CTFCONVERT_O)
-
-$(OBJS_DIR)/%.o: $(UTSBASE)/common/avs/ns/nsctl/%.c
- $(COMPILE.c) -o $@ $<
- $(CTFCONVERT_O)
-
-$(OBJS_DIR)/%.o: $(UTSBASE)/common/avs/ns/rdc/%.c
- $(COMPILE.c) -o $@ $<
- $(CTFCONVERT_O)
-
-$(OBJS_DIR)/%.o: $(UTSBASE)/common/avs/ns/sdbc/%.c
- $(COMPILE.c) -o $@ $<
- $(CTFCONVERT_O)
-
-$(OBJS_DIR)/%.o: $(UTSBASE)/common/avs/ns/solaris/%.c
- $(COMPILE.c) -o $@ $<
- $(CTFCONVERT_O)
-
-$(OBJS_DIR)/%.o: $(UTSBASE)/common/avs/ns/sv/%.c
- $(COMPILE.c) -o $@ $<
- $(CTFCONVERT_O)
-
-$(OBJS_DIR)/%.o: $(UTSBASE)/common/avs/ns/unistat/%.c
- $(COMPILE.c) -o $@ $<
- $(CTFCONVERT_O)
-
$(OBJS_DIR)/%.o: $(UTSBASE)/common/idmap/%.c
$(COMPILE.c) -o $@ $<
$(CTFCONVERT_O)
@@ -1729,30 +1697,6 @@ $(LINTS_DIR)/%.ln: $(COMMONBASE)/secflags/%.c
$(LINTS_DIR)/%.ln: $(COMMONBASE)/smbios/%.c
@($(LHEAD) $(LINT.c) $< $(LTAIL))
-$(LINTS_DIR)/%.ln: $(UTSBASE)/common/avs/ncall/%.c
- @($(LHEAD) $(LINT.c) $< $(LTAIL))
-
-$(LINTS_DIR)/%.ln: $(UTSBASE)/common/avs/ns/dsw/%.c
- @($(LHEAD) $(LINT.c) $< $(LTAIL))
-
-$(LINTS_DIR)/%.ln: $(UTSBASE)/common/avs/ns/nsctl/%.c
- @($(LHEAD) $(LINT.c) $< $(LTAIL))
-
-$(LINTS_DIR)/%.ln: $(UTSBASE)/common/avs/ns/rdc/%.c
- @($(LHEAD) $(LINT.c) $< $(LTAIL))
-
-$(LINTS_DIR)/%.ln: $(UTSBASE)/common/avs/ns/sdbc/%.c
- @($(LHEAD) $(LINT.c) $< $(LTAIL))
-
-$(LINTS_DIR)/%.ln: $(UTSBASE)/common/avs/ns/solaris/%.c
- @($(LHEAD) $(LINT.c) $< $(LTAIL))
-
-$(LINTS_DIR)/%.ln: $(UTSBASE)/common/avs/ns/sv/%.c
- @($(LHEAD) $(LINT.c) $< $(LTAIL))
-
-$(LINTS_DIR)/%.ln: $(UTSBASE)/common/avs/ns/unistat/%.c
- @($(LHEAD) $(LINT.c) $< $(LTAIL))
-
$(LINTS_DIR)/%.ln: $(UTSBASE)/common/des/%.c
@($(LHEAD) $(LINT.c) $< $(LTAIL))
diff --git a/usr/src/uts/common/avs/Makefile b/usr/src/uts/common/avs/Makefile
deleted file mode 100644
index 84258beae6..0000000000
--- a/usr/src/uts/common/avs/Makefile
+++ /dev/null
@@ -1,51 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# include global definitions
-
-AVS_SUBDIRS = ncall \
- ns \
- ns/dsw \
- ns/nsctl \
- ns/rdc \
- ns/sdbc \
- ns/solaris \
- ns/sv \
- ns/unistat
-
-# install rules
-install_h:= TARGET= install_h
-check:= TARGET= check
-clean:= TARGET= clean
-clobber:= TARGET= clobber
-
-# standards checking rules
-
-install_h check: $(AVS_SUBDIRS)
-
-clean clobber: ns/rdc
-
-$(AVS_SUBDIRS): FRC
- @cd $@; pwd; $(MAKE) $(TARGET)
-
-FRC:
diff --git a/usr/src/uts/common/avs/Makefile.com b/usr/src/uts/common/avs/Makefile.com
deleted file mode 100644
index 130bab096a..0000000000
--- a/usr/src/uts/common/avs/Makefile.com
+++ /dev/null
@@ -1,28 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# uts/common/avs/Makefile.com
-#
-CFLAGS += -DNSC_MULTI_TERABYTE
-
-LINTFLAGS += -DNSC_MULTI_TERABYTE
diff --git a/usr/src/uts/common/avs/ncall/Makefile b/usr/src/uts/common/avs/ncall/Makefile
deleted file mode 100644
index db7613ebc1..0000000000
--- a/usr/src/uts/common/avs/ncall/Makefile
+++ /dev/null
@@ -1,51 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# include global definitions
-include ../../../../Makefile.master
-
-HDRS= ncall.h ncall_module.h
-
-ROOTDIRS= $(ROOT)/usr/include/sys/ncall
-
-ROOTHDRS= $(HDRS:%=$(ROOTDIRS)/%)
-
-CHECKHDRS= $(HDRS:%.h=%.check)
-
-# install rule
-$(ROOTDIRS)/%: %
- $(INS.file)
-
-install_h := TARGET= install_h
-check := TARGET= check
-
-.KEEP_STATE:
-
-.PARALLEL: $(CHECKHDRS)
-
-install_h: $(SUBDIRS) $(ROOTDIRS) $(ROOTHDRS)
-
-$(ROOTDIRS):
- $(INS.dir)
-
-check: $(CHECKHDRS)
diff --git a/usr/src/uts/common/avs/ncall/ncall.c b/usr/src/uts/common/avs/ncall/ncall.c
deleted file mode 100644
index ccf6648bc3..0000000000
--- a/usr/src/uts/common/avs/ncall/ncall.c
+++ /dev/null
@@ -1,769 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- * Copyright (c) 2016 by Delphix. All rights reserved.
- */
-
-/*
- * Media independent RPC-like comms
- */
-
-#include <sys/types.h>
-#include <sys/conf.h>
-#include <sys/stat.h>
-#include <sys/errno.h>
-#include <sys/cmn_err.h>
-#include <sys/ksynch.h>
-#include <sys/kmem.h>
-#include <sys/modctl.h>
-#include <sys/ddi.h>
-#include <sys/sunddi.h>
-
-#include <sys/varargs.h>
-#ifdef DS_DDICT
-#include <sys/nsctl/contract.h>
-#endif
-#include "ncall.h"
-#include "ncall_module.h"
-
-#include <sys/nsctl/nsvers.h>
-
-/*
- * cb_ops functions.
- */
-
-static int ncallioctl(dev_t, int, intptr_t, int, cred_t *, int *);
-static int ncallprint(dev_t, char *);
-
-
-static struct cb_ops ncall_cb_ops = {
- nulldev, /* open */
- nulldev, /* close */
- nulldev, /* strategy */
- ncallprint,
- nodev, /* dump */
- nodev, /* read */
- nodev, /* write */
- ncallioctl,
- nodev, /* devmap */
- nodev, /* mmap */
- nodev, /* segmap */
- nochpoll, /* poll */
- ddi_prop_op,
- NULL, /* NOT a stream */
- D_NEW | D_MP | D_64BIT,
- CB_REV,
- nodev, /* aread */
- nodev, /* awrite */
-};
-
-
-/*
- * dev_ops functions.
- */
-
-static int ncall_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
-static int ncall_attach(dev_info_t *, ddi_attach_cmd_t);
-static int ncall_detach(dev_info_t *, ddi_detach_cmd_t);
-
-static struct dev_ops ncall_ops = {
- DEVO_REV,
- 0,
- ncall_getinfo,
- nulldev, /* identify */
- nulldev, /* probe */
- ncall_attach,
- ncall_detach,
- nodev, /* reset */
- &ncall_cb_ops,
- (struct bus_ops *)0,
- NULL /* power */
-};
-
-/*
- * Module linkage.
- */
-
-extern struct mod_ops mod_driverops;
-
-static struct modldrv modldrv = {
- &mod_driverops,
- "nws:Kernel Call:" ISS_VERSION_STR,
- &ncall_ops
-};
-
-static struct modlinkage modlinkage = {
- MODREV_1,
- &modldrv,
- 0
-};
-
-typedef struct ncall_modinfo_s {
- struct ncall_modinfo_s *next;
- ncall_module_t *module;
-} ncall_modinfo_t;
-
-static dev_info_t *ncall_dip; /* Single DIP for driver */
-static kmutex_t ncall_mutex;
-
-static ncall_modinfo_t *ncall_modules;
-static int ncall_active;
-
-static ncall_node_t ncall_nodeinfo;
-
-static int ncallgetnodes(intptr_t, int, int *);
-extern void ncall_init_stub(void);
-
-int
-_init(void)
-{
- int error;
-
- mutex_init(&ncall_mutex, NULL, MUTEX_DRIVER, NULL);
-
- if ((error = mod_install(&modlinkage)) != 0) {
- mutex_destroy(&ncall_mutex);
- return (error);
- }
-
- return (0);
-}
-
-
-int
-_fini(void)
-{
- int error;
-
- if ((error = mod_remove(&modlinkage)) != 0)
- return (error);
-
- mutex_destroy(&ncall_mutex);
- return (error);
-}
-
-
-int
-_info(struct modinfo *modinfop)
-{
- return (mod_info(&modlinkage, modinfop));
-}
-
-static int
-ncall_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
-{
- switch (cmd) {
-
- case DDI_ATTACH:
- ncall_dip = dip;
-
- if (ddi_create_minor_node(dip, "c,ncall", S_IFCHR,
- 0, DDI_PSEUDO, 0) != DDI_SUCCESS)
- goto failed;
-
- ddi_report_dev(dip);
-
- return (DDI_SUCCESS);
-
- default:
- return (DDI_FAILURE);
- }
-
-failed:
- (void) ncall_detach(dip, DDI_DETACH);
- return (DDI_FAILURE);
-}
-
-
-static int
-ncall_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
-{
- switch (cmd) {
-
- case DDI_DETACH:
-
- /*
- * If still active, then refuse to detach.
- */
-
- if (ncall_modules != NULL || ncall_active)
- return (DDI_FAILURE);
-
- /*
- * Remove all minor nodes.
- */
-
- ddi_remove_minor_node(dip, NULL);
- ncall_dip = NULL;
-
- return (DDI_SUCCESS);
-
- default:
- return (DDI_FAILURE);
- }
-}
-
-
-/* ARGSUSED */
-
-static int
-ncall_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
-{
- int rc = DDI_FAILURE;
-
- switch (infocmd) {
-
- case DDI_INFO_DEVT2DEVINFO:
- *result = ncall_dip;
- rc = DDI_SUCCESS;
- break;
-
- case DDI_INFO_DEVT2INSTANCE:
- /*
- * We only have a single instance.
- */
- *result = 0;
- rc = DDI_SUCCESS;
- break;
-
- default:
- break;
- }
-
- return (rc);
-}
-
-
-/* ARGSUSED */
-static int
-ncallprint(dev_t dev, char *str)
-{
- cmn_err(CE_WARN, "%s%d: %s", ddi_get_name(ncall_dip),
- ddi_get_instance(ncall_dip), str);
-
- return (0);
-}
-
-
-int
-ncall_register_module(ncall_module_t *mp, ncall_node_t *nodep)
-{
- ncall_modinfo_t *new;
- int rc = 0;
-
- if (mp == NULL || mp->ncall_version != NCALL_MODULE_VER)
- return (EINVAL);
-
- new = kmem_alloc(sizeof (*new), KM_SLEEP);
-
- if (new != NULL) {
- new->module = mp;
-
- mutex_enter(&ncall_mutex);
-
- new->next = ncall_modules;
- ncall_modules = new;
-
- mutex_exit(&ncall_mutex);
- } else {
- rc = ENOMEM;
- }
-
- *nodep = ncall_nodeinfo; /* structure copy */
- return (rc);
-}
-
-
-int
-ncall_unregister_module(ncall_module_t *mod)
-{
- ncall_modinfo_t **mpp;
- int rc = ESRCH;
-
- mutex_enter(&ncall_mutex);
-
- for (mpp = &ncall_modules; *mpp != NULL; mpp = &((*mpp)->next)) {
- if ((*mpp)->module == mod) {
- *mpp = (*mpp)->next;
- rc = 0;
- break;
- }
- }
-
- mutex_exit(&ncall_mutex);
-
- return (rc);
-}
-
-
-static int
-ncall_stop(void)
-{
- ncall_modinfo_t *mod;
- int rc = 0;
-
- mutex_enter(&ncall_mutex);
-
- while ((rc == 0) && ((mod = ncall_modules) != NULL)) {
- mutex_exit(&ncall_mutex);
-
- rc = (*mod->module->ncall_stop)();
-
- mutex_enter(&ncall_mutex);
- }
-
- mutex_exit(&ncall_mutex);
-
- return (rc);
-}
-
-
-/* ARGSUSED */
-static int ncallioctl(dev_t dev, int cmd, intptr_t arg, int mode,
- cred_t *crp, int *rvalp)
-{
- ncall_node_t node = { 0, };
- int mirror;
- int rc = 0;
-
- *rvalp = 0;
-
- if ((rc = drv_priv(crp)) != 0)
- return (rc);
-
- switch (cmd) {
-
- case NC_IOC_START:
- if (ncall_active) {
- rc = EALREADY;
- break;
- }
-
- if (ddi_copyin((void *)arg, &node, sizeof (node), mode) < 0)
- return (EFAULT);
-
- bcopy(&node, &ncall_nodeinfo, sizeof (ncall_nodeinfo));
- ncall_init_stub();
- ncall_active = 1;
- break;
-
- case NC_IOC_STOP:
- ncall_active = 0;
- rc = ncall_stop();
- break;
-
- case NC_IOC_GETNODE:
- if (!ncall_active) {
- rc = ENONET;
- break;
- }
- if (ddi_copyout(&ncall_nodeinfo, (void *)arg,
- sizeof (ncall_nodeinfo), mode) < 0) {
- rc = EFAULT;
- break;
- }
- mirror = ncall_mirror(ncall_nodeinfo.nc_nodeid);
- /*
- * can't return -1, as this will mask the ioctl
- * failure, so return 0.
- */
- if (mirror == -1)
- mirror = 0;
- *rvalp = mirror;
- break;
-
- case NC_IOC_GETNETNODES:
- rc = ncallgetnodes(arg, mode, rvalp);
- break;
-
- case NC_IOC_PING:
- if (!ncall_active) {
- rc = ENONET;
- break;
- }
-
- if (ddi_copyin((void *)arg, &node, sizeof (node), mode) < 0) {
- rc = EFAULT;
- break;
- }
-
- node.nc_nodename[sizeof (node.nc_nodename)-1] = '\0';
- rc = ncall_ping(node.nc_nodename, rvalp);
- break;
-
- default:
- rc = EINVAL;
- break;
- }
-
- return (rc);
-}
-
-
-void
-ncall_register_svc(int svc_id, void (*func)(ncall_t *, int *))
-{
- if (ncall_modules)
- (*ncall_modules->module->ncall_register_svc)(svc_id, func);
-}
-
-
-void
-ncall_unregister_svc(int svc_id)
-{
- if (ncall_modules)
- (*ncall_modules->module->ncall_unregister_svc)(svc_id);
-}
-
-
-int
-ncall_nodeid(char *nodename)
-{
- if (ncall_modules)
- return ((ncall_modules->module->ncall_nodeid)(nodename));
- else
- return (0);
-}
-
-
-char *
-ncall_nodename(int nodeid)
-{
- if (ncall_modules)
- return ((*ncall_modules->module->ncall_nodename)(nodeid));
- else
- return ("unknown");
-}
-
-
-int
-ncall_mirror(int nodeid)
-{
- if (ncall_modules)
- return ((*ncall_modules->module->ncall_mirror)(nodeid));
- else
- return (-1);
-}
-
-
-int
-ncall_self(void)
-{
- if (ncall_modules)
- return ((*ncall_modules->module->ncall_self)());
- else
- return (-1);
-}
-
-
-int
-ncall_alloc(int host_id, int flags, int net, ncall_t **ncall_p)
-{
- int rc = ENOLINK;
-
- if (ncall_modules)
- rc = (*ncall_modules->module->ncall_alloc)(host_id,
- flags, net, ncall_p);
-
- return (rc);
-}
-
-
-int
-ncall_timedsend(ncall_t *ncall, int flags, int svc_id,
- struct timeval *t, ...)
-{
- va_list ap;
- int rc = ENOLINK;
-
- va_start(ap, t);
-
- if (ncall_modules)
- rc = (*ncall_modules->module->ncall_timedsend)(ncall, flags,
- svc_id, t, ap);
-
- va_end(ap);
-
- return (rc);
-}
-
-int
-ncall_timedsendnotify(ncall_t *ncall, int flags, int svc_id,
- struct timeval *t, void (*ncall_callback)(ncall_t *, void *),
- void *vptr, ...)
-{
- va_list ap;
- int rc = ENOLINK;
-
- va_start(ap, vptr);
-
- if (ncall_modules)
- rc = (*ncall_modules->module->ncall_timedsendnotify)(ncall,
- flags, svc_id, t, ncall_callback, vptr, ap);
- va_end(ap);
-
- return (rc);
-}
-
-int
-ncall_broadcast(ncall_t *ncall, int flags, int svc_id,
- struct timeval *t, ...)
-{
- va_list ap;
- int rc = ENOLINK;
-
- va_start(ap, t);
-
- if (ncall_modules)
- rc = (*ncall_modules->module->ncall_broadcast)(ncall, flags,
- svc_id, t, ap);
- va_end(ap);
-
- return (rc);
-}
-
-
-int
-ncall_send(ncall_t *ncall, int flags, int svc_id, ...)
-{
- va_list ap;
- int rc = ENOLINK;
-
- va_start(ap, svc_id);
-
- if (ncall_modules)
- rc = (*ncall_modules->module->ncall_timedsend)(ncall, flags,
- svc_id, NULL, ap);
-
- va_end(ap);
-
- return (rc);
-}
-
-
-int
-ncall_read_reply(ncall_t *ncall, int n, ...)
-{
- va_list ap;
- int rc = ENOLINK;
-
- va_start(ap, n);
-
- if (ncall_modules)
- rc = (*ncall_modules->module->ncall_read_reply)(ncall, n, ap);
-
- va_end(ap);
-
- return (rc);
-}
-
-
-void
-ncall_reset(ncall_t *ncall)
-{
- if (ncall_modules)
- (*ncall_modules->module->ncall_reset)(ncall);
-}
-
-
-void
-ncall_free(ncall_t *ncall)
-{
- if (ncall_modules)
- (*ncall_modules->module->ncall_free)(ncall);
-}
-
-
-int
-ncall_put_data(ncall_t *ncall, void *data, int len)
-{
- int rc = ENOLINK;
-
- if (ncall_modules)
- rc = (*ncall_modules->module->ncall_put_data)(ncall, data, len);
-
- return (rc);
-}
-
-
-int
-ncall_get_data(ncall_t *ncall, void *data, int len)
-{
- int rc = ENOLINK;
-
- if (ncall_modules)
- rc = (*ncall_modules->module->ncall_get_data)(ncall, data, len);
-
- return (rc);
-}
-
-
-int
-ncall_sender(ncall_t *ncall)
-{
- int rc = -1;
-
- if (ncall_modules)
- rc = (*ncall_modules->module->ncall_sender)(ncall);
-
- return (rc);
-}
-
-
-void
-ncall_reply(ncall_t *ncall, ...)
-{
- va_list ap;
-
- if (ncall_modules) {
- va_start(ap, ncall);
-
- (*ncall_modules->module->ncall_reply)(ncall, ap);
-
- va_end(ap);
- }
-}
-
-
-void
-ncall_pend(ncall_t *ncall)
-{
- if (ncall_modules)
- (*ncall_modules->module->ncall_pend)(ncall);
-}
-
-
-void
-ncall_done(ncall_t *ncall)
-{
- if (ncall_modules)
- (*ncall_modules->module->ncall_done)(ncall);
-}
-
-int
-ncall_ping(char *nodename, int *up)
-{
- int rc = ENOLINK;
- if (ncall_modules)
- rc = (*ncall_modules->module->ncall_ping)(nodename, up);
- return (rc);
-}
-
-int
-ncall_maxnodes()
-{
- int rc = 0;
-
- if (ncall_modules)
- rc = (*ncall_modules->module->ncall_maxnodes)();
-
- return (rc);
-}
-
-int
-ncall_nextnode(void **vptr)
-{
- int rc = 0;
-
- if (ncall_modules)
- rc = (*ncall_modules->module->ncall_nextnode)(vptr);
-
- return (rc);
-}
-
-int
-ncall_errcode(ncall_t *ncall, int *result)
-{
- int rc = ENOLINK;
- if (ncall_modules)
- rc = (*ncall_modules->module->ncall_errcode)(ncall, result);
-
- return (rc);
-}
-
-static int
-ncallgetnodes(intptr_t uaddr, int mode, int *rvalp)
-{
- ncall_node_t *nodelist;
- int slot;
- int rc;
- int nodecnt;
- int nodeid;
- void *sequence;
- char *nodename;
-
- rc = 0;
-
- nodecnt = ncall_maxnodes();
- if (nodecnt <= 0) {
- return (ENONET);
- }
-
- /*
- * If the user passes up a null address argument, then
- * they don't want the actual nodes, but the configured
- * maximum, so space can be correctly allocated.
- */
-
- if (uaddr == NULL) {
- *rvalp = nodecnt;
- return (0);
- }
- nodelist = kmem_zalloc(sizeof (*nodelist) * nodecnt, KM_SLEEP);
-
- slot = 0;
- sequence = NULL;
- while ((nodeid = ncall_nextnode(&sequence)) > 0) {
- nodename = ncall_nodename(nodeid);
- /*
- * There is a small window where nextnode can
- * return a valid nodeid, and it being disabled
- * which will get nodename to return "".
- * Discard the nodeid if this happens.
- */
- if (strlen(nodename) > 0) {
- int size = sizeof (nodelist[slot].nc_nodename) - 1;
- ASSERT(slot < nodecnt);
- /*
- * make sure its null terminated when it
- * gets to userland.
- */
- nodelist[slot].nc_nodename[size] = 0;
- (void) strncpy(nodelist[slot].nc_nodename, nodename,
- size);
- nodelist[slot].nc_nodeid = nodeid;
- slot++;
- }
- }
- if (ddi_copyout(nodelist, (void *)uaddr, sizeof (*nodelist) * slot,
- mode) < 0) {
- rc = EFAULT;
- } else {
- /*
- * tell them how many have come back.
- */
- *rvalp = slot;
- }
- kmem_free(nodelist, sizeof (*nodelist) * nodecnt);
- return (rc);
-}
diff --git a/usr/src/uts/common/avs/ncall/ncall.conf b/usr/src/uts/common/avs/ncall/ncall.conf
deleted file mode 100644
index ab9b05bda6..0000000000
--- a/usr/src/uts/common/avs/ncall/ncall.conf
+++ /dev/null
@@ -1,26 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ncall (media independent messaging)
-#
-name="ncall" parent="pseudo" instance=0;
diff --git a/usr/src/uts/common/avs/ncall/ncall.h b/usr/src/uts/common/avs/ncall/ncall.h
deleted file mode 100644
index 4c1328e8d6..0000000000
--- a/usr/src/uts/common/avs/ncall/ncall.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _NCALL_H
-#define _NCALL_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef DS_DDICT
-#include <sys/time.h>
-#endif
-
-#ifdef _KERNEL
-
-/*
- * ncall_t is opaque RPC pointer
- */
-typedef struct ncall_s {
- int opaque;
-} ncall_t;
-
-#define NCALL_DATA_SZ 8192 /* ncall_put/get_data max size */
-#define NCALL_BROADCAST_ID (-2) /* magic broadcast nodeid */
-/*
- * ncall send flags
- */
-#define NCALL_PEND 1 /* disconnect immediately */
-#define NCALL_UNUSED 2 /* unused */
-#define NCALL_ASYNC 4 /* asynchronous send (ncall_free implied) */
-#define NCALL_RDATA 8 /* allocate a buffer to receive data in */
-
-extern void ncall_register_svc(int, void (*)(ncall_t *, int *));
-extern void ncall_unregister_svc(int);
-
-extern int ncall_nodeid(char *);
-extern char *ncall_nodename(int);
-extern int ncall_mirror(int);
-extern int ncall_self(void);
-
-extern int ncall_alloc(int, int, int, ncall_t **);
-extern int ncall_timedsend(ncall_t *, int, int, struct timeval *, ...);
-extern int ncall_timedsendnotify(ncall_t *, int, int, struct timeval *,
- void (*)(ncall_t *, void *), void *, ...);
-extern int ncall_broadcast(ncall_t *, int, int, struct timeval *, ...);
-extern int ncall_send(ncall_t *, int, int, ...);
-extern int ncall_read_reply(ncall_t *, int, ...);
-extern void ncall_reset(ncall_t *);
-extern void ncall_free(ncall_t *);
-
-extern int ncall_put_data(ncall_t *, void *, int);
-extern int ncall_get_data(ncall_t *, void *, int);
-
-extern int ncall_sender(ncall_t *);
-extern void ncall_reply(ncall_t *, ...);
-extern void ncall_pend(ncall_t *);
-extern void ncall_done(ncall_t *);
-extern int ncall_ping(char *, int *);
-extern int ncall_maxnodes(void);
-extern int ncall_nextnode(void **);
-extern int ncall_errcode(ncall_t *, int *);
-
-#endif /* _KERNEL */
-
-#define NCALLNMLN 257
-
-/*
- * Basic node info
- */
-typedef struct ncall_node_s {
- char nc_nodename[NCALLNMLN]; /* Nodename */
- int nc_nodeid; /* Nodeid */
-} ncall_node_t;
-
-
-#define _NCIOC_(x) (('N'<<16)|('C'<<8)|(x))
-
-#define NC_IOC_GETNODE _NCIOC_(0) /* return this node */
-#define NC_IOC_START _NCIOC_(1) /* ncall core and stubs start */
-#define NC_IOC_STOP _NCIOC_(2) /* ncall stop */
-#define NC_IOC_GETNETNODES _NCIOC_(3) /* ncalladm -i */
-#define NC_IOC_PING _NCIOC_(4) /* ncalladm -p */
-/*
- * _NCIOC_(5) to _NCIOC_(20) are reserved for the implementation module
- */
-
-#define NCALL_NSC 100 /* 100 - 109 */
-#define NCALL_UNUSED1 110 /* 110 - 119 */
-#define NCALL_UNUSED2 120 /* 120 - 129 */
-#define NCALL_SDBC 130 /* 130 - 149 */
-#define NCALL_STE 150 /* 150 - 159 */
-#define NCALL_HM 160 /* 160 - 169 */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _NCALL_H */
diff --git a/usr/src/uts/common/avs/ncall/ncall_module.h b/usr/src/uts/common/avs/ncall/ncall_module.h
deleted file mode 100644
index 552f88c615..0000000000
--- a/usr/src/uts/common/avs/ncall/ncall_module.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _NCALL_MODULE_H
-#define _NCALL_MODULE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef _KERNEL
-
-#define NCALL_MODULE_VER 4
-
-typedef struct ncall_module_s {
- int ncall_version;
- char *ncall_name;
-
- int (*ncall_stop)(void);
-
- void (*ncall_register_svc)(int, void (*)(ncall_t *, int *));
- void (*ncall_unregister_svc)(int);
-
- int (*ncall_nodeid)(char *);
- char *(*ncall_nodename)(int);
- int (*ncall_mirror)(int);
- int (*ncall_self)(void);
-
- int (*ncall_alloc)(int, int, int, ncall_t **);
- int (*ncall_timedsend)(ncall_t *, int, int, struct timeval *,
- va_list);
- int (*ncall_timedsendnotify)(ncall_t *, int, int, struct timeval *,
- void (*)(ncall_t *, void *), void *, va_list);
- int (*ncall_broadcast)(ncall_t *, int, int, struct timeval *,
- va_list);
- int (*ncall_read_reply)(ncall_t *, int, va_list);
- void (*ncall_reset)(ncall_t *);
- void (*ncall_free)(ncall_t *);
-
- int (*ncall_put_data)(ncall_t *, void *, int);
- int (*ncall_get_data)(ncall_t *, void *, int);
-
- int (*ncall_sender)(ncall_t *);
- void (*ncall_reply)(ncall_t *, va_list);
- void (*ncall_pend)(ncall_t *);
- void (*ncall_done)(ncall_t *);
-
- int (*ncall_ping)(char *, int *);
- int (*ncall_maxnodes)(void);
- int (*ncall_nextnode)(void **);
- int (*ncall_errcode)(ncall_t *, int *);
-} ncall_module_t;
-
-extern int ncall_register_module(ncall_module_t *, ncall_node_t *);
-extern int ncall_unregister_module(ncall_module_t *);
-
-#endif /* _KERNEL */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _NCALL_MODULE_H */
diff --git a/usr/src/uts/common/avs/ncall/ncall_stub.c b/usr/src/uts/common/avs/ncall/ncall_stub.c
deleted file mode 100644
index 3756320e7e..0000000000
--- a/usr/src/uts/common/avs/ncall/ncall_stub.c
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/errno.h>
-#include <sys/ddi.h>
-#include <sys/sunddi.h>
-
-#include <sys/varargs.h>
-#ifdef DS_DDICT
-#include <sys/nsctl/contract.h>
-#endif
-#include "ncall.h"
-#include "ncall_module.h"
-
-static ncall_node_t nodeinfo;
-
-
-/* ARGSUSED */
-void
-ncall_stub_register_svc(int svc_id, void (*func)(ncall_t *, int *))
-{
- ;
-}
-
-/* ARGSUSED */
-void
-ncall_stub_unregister_svc(int svc_id)
-{
- ;
-}
-
-/* ARGSUSED */
-int
-ncall_stub_nodeid(char *nodename)
-{
- return (nodeinfo.nc_nodeid);
-}
-
-/* ARGSUSED */
-char *
-ncall_stub_nodename(int nodeid)
-{
- if (nodeid == nodeinfo.nc_nodeid)
- return (nodeinfo.nc_nodename);
- else
- return ("");
-}
-
-/* ARGSUSED */
-int
-ncall_stub_mirror(int nodeid)
-{
- return (-1);
-}
-
-/* ARGSUSED */
-int
-ncall_stub_self(void)
-{
- return (nodeinfo.nc_nodeid);
-}
-
-/* ARGSUSED */
-int
-ncall_stub_alloc(int host_id, int flags, int net, ncall_t **ncall_p)
-{
- return (ENOLINK);
-}
-
-/* ARGSUSED */
-int
-ncall_stub_timedsend(ncall_t *ncall, int flags, int svc_id,
- struct timeval *t, va_list ap)
-{
- return (ENOLINK);
-}
-
-/* ARGSUSED */
-int
-ncall_stub_timedsendnotify(ncall_t *ncall, int flags, int svc_id,
- struct timeval *t, void (*ncall_callback)(ncall_t *, void *), void *vptr,
- va_list ap)
-{
- return (ENOLINK);
-}
-
-/* ARGSUSED */
-int
-ncall_stub_broadcast(ncall_t *ncall, int flags, int svc_id,
- struct timeval *t, va_list ap)
-{
- return (ENOLINK);
-}
-
-/* ARGSUSED */
-int
-ncall_stub_read_reply(ncall_t *ncall, int n, va_list ap)
-{
- return (ENOLINK);
-}
-
-/* ARGSUSED */
-void
-ncall_stub_reset(ncall_t *ncall)
-{
- ;
-}
-
-/* ARGSUSED */
-void
-ncall_stub_free(ncall_t *ncall)
-{
- ;
-}
-
-/* ARGSUSED */
-int
-ncall_stub_put_data(ncall_t *ncall, void *data, int len)
-{
- return (ENOLINK);
-}
-
-/* ARGSUSED */
-int
-ncall_stub_get_data(ncall_t *ncall, void *data, int len)
-{
- return (ENOLINK);
-}
-
-/* ARGSUSED */
-int
-ncall_stub_sender(ncall_t *ncall)
-{
- return (nodeinfo.nc_nodeid);
-}
-
-/* ARGSUSED */
-void
-ncall_stub_reply(ncall_t *ncall, va_list ap)
-{
- ;
-}
-
-/* ARGSUSED */
-void
-ncall_stub_pend(ncall_t *ncall)
-{
- ;
-}
-
-/* ARGSUSED */
-void
-ncall_stub_done(ncall_t *ncall)
-{
- ;
-}
-
-int
-ncall_stub_ping(char *nodename, int *up)
-{
- int rc = 0;
-
- if (strcmp(nodename, nodeinfo.nc_nodename) == 0) {
- *up = 1;
- } else {
- rc = EHOSTUNREACH;
- *up = 0;
- }
-
- return (rc);
-}
-
-/* ARGSUSED */
-int
-ncall_stub_maxnodes()
-{
- return (0);
-}
-
-
-/* ARGSUSED */
-int
-ncall_stub_nextnode(void **vptr)
-{
- return (0);
-}
-
-/* ARGSUSED */
-int
-ncall_stub_errcode(ncall_t *ncall, int *result)
-{
- return (ENOLINK);
-}
-
-
-
-
-static int ncall_stub_stop(void);
-
-static ncall_module_t ncall_stubinfo = {
- NCALL_MODULE_VER,
- "ncall stubs",
- ncall_stub_stop,
- ncall_stub_register_svc,
- ncall_stub_unregister_svc,
- ncall_stub_nodeid,
- ncall_stub_nodename,
- ncall_stub_mirror,
- ncall_stub_self,
- ncall_stub_alloc,
- ncall_stub_timedsend,
- ncall_stub_timedsendnotify,
- ncall_stub_broadcast,
- ncall_stub_read_reply,
- ncall_stub_reset,
- ncall_stub_free,
- ncall_stub_put_data,
- ncall_stub_get_data,
- ncall_stub_sender,
- ncall_stub_reply,
- ncall_stub_pend,
- ncall_stub_done,
- ncall_stub_ping,
- ncall_stub_maxnodes,
- ncall_stub_nextnode,
- ncall_stub_errcode
-};
-
-
-static int
-ncall_stub_stop(void)
-{
- bzero(&nodeinfo, sizeof (nodeinfo));
- return (ncall_unregister_module(&ncall_stubinfo));
-}
-
-
-void
-ncall_init_stub(void)
-{
- (void) ncall_register_module(&ncall_stubinfo, &nodeinfo);
-}
diff --git a/usr/src/uts/common/avs/ns/Makefile b/usr/src/uts/common/avs/ns/Makefile
deleted file mode 100644
index 4c770fdb16..0000000000
--- a/usr/src/uts/common/avs/ns/Makefile
+++ /dev/null
@@ -1,57 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# include global definitions
-include ../../../../Makefile.master
-
-HDRS= \
- model.h \
- contract.h \
- nsctl_inter.h \
- ncall_inter.h \
- nsctl.h
-
-ROOTDIR= $(ROOT)/usr/include/sys/nsctl
-
-ROOTHDRS= $(HDRS:%=$(ROOTDIR)/%)
-
-# install rules
-$(ROOTDIR)/%: %
- $(INS.file)
-
-# standards checking rules
-%.check: %.h
- $(DOT_H_CHECK)
-
-CHECKHDRS= $(HDRS:%.h=%.check)
-
-.KEEP_STATE:
-
-.PARALLEL: $(CHECKHDRS)
-
-install_h: $(ROOTDIR) $(ROOTHDRS)
-
-$(ROOTDIR):
- $(INS.dir)
-
-check: $(CHECKHDRS)
diff --git a/usr/src/uts/common/avs/ns/contract.h b/usr/src/uts/common/avs/ns/contract.h
deleted file mode 100644
index 0a4ec90e43..0000000000
--- a/usr/src/uts/common/avs/ns/contract.h
+++ /dev/null
@@ -1,535 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * The sole purpose of this file is to document our violations of the DDI
- * in Solaris and to get ddict to run on the data services stack.
- * Definitions and declarations contained in this file are never compiled
- * into the code. It is only included if we are running ddict on our src.
- *
- * IMPORTANT NOTE:
- * Many of the declarations are not correct. It does not matter.
- * Structure declarations only define the fields we require.
- * Structures which we use in an opaque manner are defined as void *
- */
-
-#ifndef _SYS_CONTRACT_H
-#define _SYS_CONTRACT_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Define our interfaces for nsctl because ddict is stupid
- * about intermodule dependencies
- */
-#include <sys/nsctl/nsctl_inter.h>
-
-/*
- * Define our ncall interfaces
- */
-#include <sys/nsctl/ncall_inter.h>
-
-/*
- * The STRUCT_DECL definitions in the ddict headers are fouled up
- * we include our own model.h here to redefine it to avoid errors.
- */
-#if !defined(_SunOS_5_6)
-#include <sys/nsctl/model.h>
-#endif
-
-/*
- * General violations
- * Everybody violates these
- * Why are they called ddi if it is not part of it?
- */
-
-#define DDI_PROP_NOTPROM 0
-
-int ddi_rele_driver(void) { }
-int ddi_hold_installed_driver(void) { }
-
-/*
- * SV module violations
- */
-void *curthread;
-int devcnt;
-
-/*
- * The following from vnode.h
- */
-typedef struct vode {
- int v_lock; /* SDBC uses this too */
- int v_type; /* nskern too */
- int v_rdev; /* nskern too */
-} vnode_t;
-
-#define FOLLOW 0
-#define NULLVPP NULL
-#define AT_RDEV 0
-#define VOP_GETATTR(vp, vap, f, cr) ((void)0)
-#define VN_RELE(vp) ((void)0)
-
-/*
- * The fields we use from vattr_t
- */
-typedef struct vattr {
- uint_t va_mask;
- dev_t va_rdev;
- int va_size; /* nskern */
-} vattr_t;
-
-int lookupname(void, void, void, void, void) { }
-
-/*
- * End of SV module violations
- */
-
-/*
- * DSW/II module violations
- */
-
-/*
- * This is really bogus that ddict does not understand sys/inttypes.h
- */
-#define INT32_MIN 0
-#define INT32_MAX 0
-#define INT64_MAX 0
-
-/*
- * End of DSW/II module violations
- */
-
-/*
- * UNISTAT module violations
- */
-
-void mod_miscops;
-typedef enum { B_FALSE, B_TRUE } boolean_t;
-
-/*
- * End of UNISTAT module violations
- */
-
-/*
- * NSCTL module violations
- */
-#define ERESTART 0
-#define EUSERS 0
-#define ENAMETOOLONG 0
-#define ENOSYS 0
-#define FOPEN 0
-int ddi_name_to_major() { }
-/*
- * End of NSCTL module violations
- */
-
-/*
- * NSKERN module violations
- */
-#define UL_GETFSIZE 0
-#define USHRT_MAX 0
-
-typedef u_longlong_t rlim64_t;
-int ulimit() { }
-int maxphys;
-
-#define AT_SIZE 0
-#define VBLK 0
-#define VCHR 0
-#define VREG 0
-#define VLNK 0
-
-#define VOP_CLOSE(vp, f, c, o, cr) ((void)0)
-#define VOP_RWLOCK(vp, w) ((void)0)
-#define VOP_RWUNLOCK(vp, w) ((void)0)
-#define VOP_READ(vp, uiop, iof, cr) ((void)0)
-#define VOP_WRITE(vp, uiop, iof, cr) ((void)0)
-
-int vn_open(char *pnamep, void seg, int filemode, int createmode,
- struct vnode **vpp, void crwhy, mode_t umask) { }
-
-/*
- * End of NSKERN module violations
- */
-
-/*
- * NVRAM module violations
- */
-#define MMU_PAGESIZE 0
-
-#ifndef MAXNAMELEN
-#define MAXNAMELEN 1
-#endif
-
-#define DEVMAP_DEFAULTS 0
-#define PFN_INVALID -1
-
-char hw_serial[1];
-int mmu_ptob(void arg) { }
-int roundup(void arg) { }
-
-/*
- * End of NVRAM module violations
- */
-
-/*
- * RDCSVR (SNDR) module
- * Contract PSARC 2001/699
- */
-#define DUP_DONE 0
-#define DUP_ERROR 0
-#define DUP_INPROGRESS 0
-#define DUP_NEW 0
-#define DUP_DROP 0
-
-#define RPC_MAXDATASIZE 0
-
-
-typedef void * file_t; /* opaque */
-typedef void SVCXPRT; /* opaque */
-typedef void SVCMASTERXPRT; /* opaque */
-typedef void xdrproc_t; /* opaque */
-typedef int enum_t;
-
-typedef struct svc_req { /* required fields */
- int rq_vers;
- int rq_proc;
-} svc_req_t;
-
-void SVC_FREEARGS(void xprt, void a, void *b) { }
-void SVC_DUP(void xprt, void req, void i, void j, void *dr) { }
-void svcerr_systemerr(void xprt) { }
-void svcerr_noproc(void xprt) { }
-void SVC_DUPDONE(void xprt, void dr, void a, void b, void c) { }
-
-SVCXPRT *svc_tli_kcreate(void *f, void *n, void *b, void **x, void *t,
- uint_t c, uint_t d) { }
-
-/*
- * non-ddi not under contracts
- */
-struct netbuf {
- int maxlen;
- int len;
- char *buf;
-}
-
-/*
- * End of RDCSRV module Contracts
- */
-
-/*
- * RDC (SNDR) module
- * Contract PSARC 2001/699
- */
-
-typedef u_longlong_t rpcproc_t;
-typedef u_longlong_t xdrproc_t;
-typedef u_longlong_t rpcvers_t;
-#define __dontcare__ -1
-#define RPC_INTR 0
-#define RPC_SUCCESS 0
-#define RPC_TLIERROR 0
-#define RPC_XPRTFAILED 0
-#define RPC_VERSMISMATCH 0
-#define RPC_PROGVERSMISMATCH 0
-#define RPC_INPROGRESS 0
-
-#define ENOEXEC 0
-#define EBADF 0
-
-/*
- * XDR routines
- * from rpc/xdr.h
- */
-typedef void * XDR; /* opaque */
-int xdr_void() { }
-int xdr_int() { }
-int xdr_union() { }
-int xdr_enum() { }
-int xdr_u_int() { }
-int xdr_u_longlong_t() { }
-int xdr_opaque() { }
-int xdr_bytes() { }
-int xdr_array() { }
-#define NULL_xdrproc_t ((xdrproc_t)0)
-
-/*
- * The following imported rpc/clnt.h
- */
-
-/* Client is mostly opaque exccept for the following */
-
-typedef struct __client { /* required fields */
- void *cl_auth;
- bool_t cl_nosignal;
-} CLIENT;
-
-#define CLSET_PROGRESS 0
-#define KNC_STRSIZE 128
-struct knetconfig {
- unsigned int knc_semantics;
- caddr_t knc_protofmly;
- caddr_t knc_proto;
- dev_t knc_rdev;
-};
-
-void *clnt_sperrno() { }
-void IS_UNRECOVERABLE_RPC(a) { }
-void CLNT_CONTROL(cl, request, info) { }
-void AUTH_DESTROY(void *a) { }
-void CLNT_DESTROY(void *a) { }
-
-int clnt_tli_kcreate(void *a, void *b, void c, void d, void e, void f,
- void *g, void **h) { }
-
-int clnt_tli_kinit(void *h, void *config, void *addr, uint_t a, int b,
- void *c) { }
-
-void CLNT_CALL(void, void, void, void, void, void, void) { }
-
-/*
- * The following imported from rpc/svc.h
- */
-void svc_sendreply() { }
-void svcerr_decode() { }
-void SVC_GETARGS() { }
-
-/*
- * The following imported from sys/file.h
- */
-
-void getf(void) { }
-void releasef(void) { }
-
-/*
- * Not under contract
- */
-void sigintr(void) { }
-void sigunintr(void) { }
-dev_t expldev() { }
-
-/*
- * End of RDC module
- */
-
-/*
- * SDBC module violations
- */
-
-/*
- * devid uses internal structure
- * from sys/ddi_impldefs.h
- */
-typedef struct impl_devid {
- uchar_t did_type_hi;
- uchar_t did_type_lo;
-} impl_devid_t;
-
-#define DEVID_GETTYPE(devid) 0
-#define DEVID_SCSI_SERIAL 0
-
-#define ENOLINK 0 /* NCALL too */
-#define E2BIG 0
-#define ENOENT 0
-#define EIDRM 0
-
-#define B_KERNBUF 0
-#define KSTAT_TYPE_RAW 0
-#define MAXPATHLEN 0
-
-#define VN_HOLD(bp) ((void)0)
-
-/* Page list IO stuff */
-typedef struct page {
- int v_count; /* sdbc */
-} page_t;
-page_t kvp; /* We use the kernel segment */
-int page_add(void) { }
-int page_find(void) { }
-int page_list_concat(void) { }
-int pageio_setup(void) { }
-int pageio_done(void) { }
-
-void kobj_getsymvalue(void) { }
-int ddi_dev_pathname(void) { }
-
-/*
- * HACK ALERT
- * struct buf hack for ddict.
- * SDBC currently violates in struct buf
- * b_pages
- * b_proc
- * which we will define as the pad fields for ddict since
- * we can not overload the definition of struct buf with our own stuff.
- */
-
-#define b_pages b_pad7 /* b_pages in struct buf */
-#define b_proc b_pad8 /* b_proc in struct buf */
-#define b_forw b_pad1 /* b_forw in struct buf */
-#define b_back b_pad2 /* b_back in struct buf */
-
-/*
- * End of SDBC moduel violations
- */
-
-/*
- * SCMTEST module violations
- */
-
-#define ESRCH 0 /* NCALL too */
-
-/*
- * End of SCMTEST module violations
- */
-/*
- * SFTM module violations
- * Note: XXX This list is currently incomplete
- */
-
-typedef void * cqe_t; /* opaque */
-typedef void * fcal_packet_t; /* opaque */
-typedef void * soc_response_t; /* opaque */
-typedef void * la_els_logi_t; /* opaque */
-typedef void * la_els_adisc_t; /* opaque */
-typedef void * fcp_rsp_t; /* opaque */
-typedef void * soc_request_t; /* opaque */
-typedef void * els_payload_t; /* opaque */
-typedef void * la_els_logo_t; /* opaque */
-typedef void * fc_frame_header_t; /* opaque */
-
-typedef struct la_els_prli_s {
- uchar_t ls_code;
- uchar_t page_length;
- ushort_t payload_length;
- uchar_t service_params[1];
-} la_els_prli_t;
-
-typedef la_els_prli_t la_els_prli_reply_t;
-typedef la_els_prli_t la_els_prlo_t;
-typedef la_els_prli_t la_els_prlo_reply_t;
-
-/*
- * The following from /usr/include/sys/fc4/fcp.h
- */
-typedef struct fcp_cntl {
- uchar_t cntl_reserved_1 : 5,
- cntl_qtype : 3;
- uchar_t cntl_kill_tsk : 1,
- cntl_clr_aca : 1,
- cntl_reset : 1,
- cntl_reserved_2 : 2,
- cntl_clr_tsk : 1,
- cntl_abort_tsk : 1,
- cntl_reserved_3 : 1;
- uchar_t cntl_reserved_4 : 6,
- cntl_read_data : 1,
- cntl_write_data : 1;
-} fcp_cntl_t;
-
-typedef struct fcp_ent_addr {
- ushort_t ent_addr_0;
- ushort_t ent_addr_1;
- ushort_t ent_addr_2;
- ushort_t ent_addr_3;
-} fcp_ent_addr_t;
-
-typedef struct fcp_cmd_s {
- fcp_ent_addr_t fcp_ent_addr;
- fcp_cntl_t fcp_cntl;
- uchar_t fcp_cdb[1];
- int fcp_data_len;
-} fcp_cmd_t;
-
-typedef struct fcal_transport {
- uchar_t dummy1;
- uchar_t dummy2;
-} fcal_transport_t;
-
-/*
- * End of SFTM module violations
- */
-
-/*
- * STE module violations
- */
-
-typedef void la_wwn_t; /* opaque */
-/* WWN formats from sys/fcal/fcal_linkapp.h */
-typedef union la_wwn {
- uchar_t raw_wwn[8];
- struct {
- uint_t naa_id : 4;
- uint_t nport_id : 12;
- uint_t wwn_hi : 16;
- uint_t wwn_lo;
- } w;
-} la_wwn_t;
-
-insque(void) { }
-remque(void) { }
-snprintf(void) { }
-
-/*
- * STE uses inq_serial and inq_ackqreqq from struct scsi_inquiry
- */
-#define inq_serial inq_pid
-#define inq_ackqreqq inq_pid
-/*
- * End of STE module violations
- */
-
-/*
- * NCALL module violations
- */
-#define ENONET 0
-
-/* NCALLSRV */
-typedef int bool_t;
-
-/* NCALLIP */
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#define ERANGE 0
-#define ENODATA 0
-
-#define RPC_TIMEDOUT 0
-
-/*
- * End of NCALL violations
- */
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SYS_CONTRACT_H */
diff --git a/usr/src/uts/common/avs/ns/dsw/Makefile b/usr/src/uts/common/avs/ns/dsw/Makefile
deleted file mode 100644
index 9191e00d76..0000000000
--- a/usr/src/uts/common/avs/ns/dsw/Makefile
+++ /dev/null
@@ -1,48 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# include global definitions
-include ../../../../../Makefile.master
-
-HDRS= dsw.h dsw_dev.h
-
-ROOTDIRS= $(ROOT)/usr/include/sys/nsctl
-
-ROOTHDRS= $(HDRS:%=$(ROOTDIRS)/%)
-
-CHECKHDRS= $(HDRS:%.h=%.check)
-
-# install rule
-$(ROOTDIRS)/%: %
- $(INS.file)
-
-.KEEP_STATE:
-
-.PARALLEL: $(CHECKHDRS)
-
-install_h: $(ROOTDIRS) $(ROOTHDRS)
-
-$(ROOTDIRS):
- $(INS.dir)
-
-check: $(CHECKHDRS)
diff --git a/usr/src/uts/common/avs/ns/dsw/dsw.c b/usr/src/uts/common/avs/ns/dsw/dsw.c
deleted file mode 100644
index 270f97dfc2..0000000000
--- a/usr/src/uts/common/avs/ns/dsw/dsw.c
+++ /dev/null
@@ -1,655 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#define _DSW_
-
-#include <sys/types.h>
-#include <sys/ksynch.h>
-#include <sys/kmem.h>
-#include <sys/errno.h>
-#include <sys/conf.h>
-#include <sys/cmn_err.h>
-#include <sys/modctl.h>
-#include <sys/cred.h>
-#include <sys/file.h>
-#include <sys/ddi.h>
-#include <sys/unistat/spcs_s.h>
-#include <sys/dkio.h>
-
-#ifdef DS_DDICT
-#include "../contract.h"
-#endif
-
-#include <sys/nsctl/nsctl.h>
-#include <sys/nsctl/nsvers.h>
-
-#include <sys/sdt.h> /* dtrace is S10 or later */
-
-#include "dsw.h"
-#include "dsw_dev.h"
-
-#define DIDINIT 0x01
-#define DIDNODES 0x02
-
-
-static int iiopen(dev_t *devp, int flag, int otyp, cred_t *crp);
-static int iiclose(dev_t dev, int flag, int otyp, cred_t *crp);
-static int iiprint(dev_t dev, char *str);
-static int iiioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *crp,
- int *rvp);
-static int iiprobe(dev_info_t *dip);
-static int iiattach(dev_info_t *dip, ddi_attach_cmd_t cmd);
-static int iidetach(dev_info_t *dip, ddi_detach_cmd_t cmd);
-static int iistrat(struct buf *);
-static int iiread();
-
-
-static kstat_t *ii_gkstat = NULL;
-iigkstat_t iigkstat = {
- { "ii_debug", KSTAT_DATA_ULONG },
- { "ii_bitmap", KSTAT_DATA_ULONG },
- { "ii_throttle_unit", KSTAT_DATA_ULONG },
- { "ii_throttle_delay", KSTAT_DATA_ULONG },
- { "ii_copy_direct", KSTAT_DATA_ULONG },
- { "num-sets", KSTAT_DATA_ULONG },
- { "assoc-over", KSTAT_DATA_ULONG },
- { "spilled-over", KSTAT_DATA_ULONG },
-};
-
-static struct cb_ops ii_cb_ops = {
- iiopen,
- iiclose,
- iistrat, /* dummy strategy */
- iiprint,
- nodev, /* no dump */
- iiread, /* dummy read */
- nodev, /* no write */
- iiioctl,
- nodev, /* no devmap */
- nodev, /* no mmap */
- nodev, /* no segmap */
- nochpoll,
- ddi_prop_op,
- NULL, /* not STREAMS */
- D_NEW | D_MP
-};
-
-static struct dev_ops ii_ops = {
- DEVO_REV,
- 0,
- nodev, /* no getinfo */
- nulldev,
- iiprobe,
- iiattach,
- iidetach,
- nodev, /* no reset */
- &ii_cb_ops,
- (struct bus_ops *)NULL
-};
-
-static struct modldrv ii_ldrv = {
- &mod_driverops,
- "nws:Point-in-Time:" ISS_VERSION_STR,
- &ii_ops
-};
-
-static struct modlinkage ii_modlinkage = {
- MODREV_1,
- &ii_ldrv,
- NULL
-};
-
-struct ii_state {
- dev_info_t *dip;
- int instance;
-};
-
-/* used for logging sysevent, gets set in _ii_attach */
-dev_info_t *ii_dip = NULL;
-
-extern _ii_info_t *_ii_info_top;
-extern _ii_lsthead_t *_ii_cluster_top;
-extern _ii_lsthead_t *_ii_group_top;
-extern kmutex_t _ii_cluster_mutex;
-extern kmutex_t _ii_group_mutex;
-
-const int dsw_major_rev = ISS_VERSION_MAJ; /* Major release number */
-const int dsw_minor_rev = ISS_VERSION_MIN; /* Minor release number */
-const int dsw_micro_rev = ISS_VERSION_MIC; /* Micro release number */
-const int dsw_baseline_rev = ISS_VERSION_NUM; /* Baseline revision */
-static void *ii_statep;
-
-extern int _ii_init_dev();
-extern void _ii_deinit_dev();
-extern int _ii_config(intptr_t arg, int ilp32, int *rvp, int iflags);
-extern int _ii_disable(intptr_t arg, int ilp32, int *rvp);
-extern int _ii_suspend(intptr_t arg, int ilp32, int *rvp);
-extern int _ii_bitmap(intptr_t arg, int ilp32, int *rvp);
-extern int _ii_segment(intptr_t arg, int ilp32, int *rvp);
-extern int _ii_abort(intptr_t arg, int ilp32, int *rvp);
-extern int _ii_acopy(intptr_t arg, int ilp32, int *rvp);
-extern int _ii_copy(intptr_t arg, int ilp32, int *rvp);
-extern int _ii_shutdown(intptr_t arg, int *rvp);
-extern int _ii_stat(intptr_t arg, int ilp32, int *rvp);
-extern int _ii_version(intptr_t arg, int ilp32, int *rvp);
-extern int _ii_wait(intptr_t arg, int ilp32, int *rvp);
-extern int _ii_reset(intptr_t arg, int ilp32, int *rvp);
-extern int _ii_offline(intptr_t arg, int ilp32, int *rvp);
-extern int _ii_list(intptr_t arg, int ilp32, int *rvp);
-extern int _ii_listlen(int cmd, int ilp32, int *rvp);
-extern int _ii_export(intptr_t arg, int ilp32, int *rvp);
-extern int _ii_join(intptr_t arg, int ilp32, int *rvp);
-extern int _ii_copyparm(intptr_t arg, int ilp32, int *rvp);
-extern int _ii_ocreate(intptr_t arg, int ilp32, int *rvp);
-extern int _ii_oattach(intptr_t arg, int ilp32, int *rvp);
-extern int _ii_odetach(intptr_t arg, int ilp32, int *rvp);
-extern int _ii_olist(intptr_t arg, int ilp32, int *rvp);
-extern int _ii_ostat(intptr_t arg, int ilp32, int *rvp, int is_iost_2);
-extern int _ii_bitsset(intptr_t arg, int ilp32, int cmd, int *rvp);
-extern int _ii_gc_list(intptr_t, int, int *, kmutex_t *, _ii_lsthead_t *);
-extern int _ii_clist(intptr_t arg, int ilp32, int *rvp);
-extern int _ii_move_grp(intptr_t arg, int ilp32, int *rvp);
-extern int _ii_change_tag(intptr_t arg, int ilp32, int *rvp);
-extern int ii_debug;
-extern int ii_throttle_unit;
-extern int ii_throttle_delay;
-extern int ii_copy_direct;
-extern int ii_bitmap;
-
-int
-_init(void)
-{
- int error;
-
- error = ddi_soft_state_init(&ii_statep, sizeof (struct ii_state), 1);
- if (!error) {
- error = mod_install(&ii_modlinkage);
- if (error)
- ddi_soft_state_fini(&ii_statep);
- }
-
- return (error);
-}
-
-int
-_fini(void)
-{
- int error;
-
- error = mod_remove(&ii_modlinkage);
- if (!error)
- ddi_soft_state_fini(&ii_statep);
-
- return (error);
-}
-
-int
-_info(struct modinfo *modinfop)
-{
- int rc;
-
- rc = mod_info(&ii_modlinkage, modinfop);
-
- return (rc);
-}
-
-/* ARGSUSED */
-
-static int
-iiprobe(dev_info_t *dip)
-{
- return (DDI_PROBE_SUCCESS);
-}
-
-/*ARGSUSED*/
-static int
-ii_stats_update(kstat_t *ksp, int rw)
-{
- if (KSTAT_WRITE == rw) {
- return (EACCES);
- }
-
- /*
- * We do nothing here for now -- the kstat structure is
- * updated in-place
- */
-
- return (0);
-}
-
-static void
-ii_create_kstats()
-{
- /* create global info structure */
- if (!ii_gkstat) {
- ii_gkstat = kstat_create("ii", 0, "global", "StorEdge",
- KSTAT_TYPE_NAMED,
- sizeof (iigkstat) / sizeof (kstat_named_t),
- KSTAT_FLAG_VIRTUAL);
- if (ii_gkstat) {
- ii_gkstat->ks_data = &iigkstat;
- ii_gkstat->ks_update = ii_stats_update;
- ii_gkstat->ks_private = 0;
- kstat_install(ii_gkstat);
-
- /* fill in immutable values */
- iigkstat.ii_debug.value.ul = ii_debug;
- iigkstat.ii_bitmap.value.ul = ii_bitmap;
- iigkstat.ii_throttle_unit.value.ul = ii_throttle_unit;
- iigkstat.ii_throttle_delay.value.ul =
- ii_throttle_delay;
- iigkstat.ii_copy_direct.value.ul = ii_copy_direct;
- } else {
- cmn_err(CE_WARN, "!Unable to create II global stats");
- }
- }
-}
-
-static int
-iiattach(dev_info_t *dip, ddi_attach_cmd_t cmd)
-{
- struct ii_state *xsp;
- int instance;
- int i;
- intptr_t flags;
-
- if (cmd != DDI_ATTACH) {
- return (DDI_FAILURE);
- }
- /* save the dev_info_t to be used in logging using ddi_log_sysevent */
- ii_dip = dip;
-
- instance = ddi_get_instance(dip);
- if (ddi_soft_state_zalloc(ii_statep, instance) != 0) {
- cmn_err(CE_WARN, "!ii: no memory for instance %d state.",
- instance);
- return (DDI_FAILURE);
- }
-
- flags = 0;
- xsp = ddi_get_soft_state(ii_statep, instance);
- if (xsp == NULL) {
- cmn_err(CE_WARN,
- "!ii: attach: could not get state for instance %d.",
- instance);
- goto out;
- }
-
- ii_debug = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "ii_debug", 0);
- if (ii_debug != 0) {
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!ii: initializing ii version %d.%d.%d.%d",
- dsw_major_rev, dsw_minor_rev,
- dsw_micro_rev, dsw_baseline_rev);
-#else
- if (dsw_micro_rev) {
- cmn_err(CE_NOTE, "!ii: initializing ii vers %d.%d.%d",
- dsw_major_rev, dsw_minor_rev, dsw_micro_rev);
- } else {
- cmn_err(CE_NOTE, "!ii: initializing ii version %d.%d",
- dsw_major_rev, dsw_minor_rev);
- }
-#endif
- switch (ii_debug) {
- case 1:
- case 2: cmn_err(CE_NOTE,
- "!ii: ii_debug=%d is enabled.", ii_debug);
- break;
- default:
- cmn_err(CE_WARN,
- "!ii: Value of ii_debug=%d is not 0,1 or 2.",
- ii_debug);
- }
- }
-
- ii_bitmap = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "ii_bitmap", II_WTHRU);
- switch (ii_bitmap) {
- case II_KMEM:
- if (ii_debug > 0)
- cmn_err(CE_NOTE, "!ii: ii_bitmap is in memory");
- break;
- case II_FWC:
- if (ii_debug > 0)
- cmn_err(CE_NOTE, "!ii: ii_bitmap is on disk,"
- " no FWC");
- break;
- case II_WTHRU:
- if (ii_debug > 0)
- cmn_err(CE_NOTE, "!ii: ii_bitmap is on disk");
- break;
- default:
- cmn_err(CE_NOTE,
- "!ii: ii_bitmap=%d out of range; "
- "defaulting WTHRU(%d)", ii_bitmap, II_WTHRU);
- ii_bitmap = II_WTHRU;
- }
-
- /* pick up these values if in ii.conf, otherwise leave alone */
- i = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "ii_throttle_unit", 0);
- if (i > 0) {
- ii_throttle_unit = i;
- if ((ii_throttle_unit < MIN_THROTTLE_UNIT) ||
- (ii_throttle_unit > MAX_THROTTLE_UNIT) ||
- (ii_debug > 0))
- cmn_err(CE_NOTE,
- "!ii: ii_throttle_unit=%d", ii_throttle_unit);
- }
-
- i = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "ii_throttle_delay", 0);
- if (i > 0) {
- ii_throttle_delay = i;
- if ((ii_throttle_delay < MIN_THROTTLE_DELAY) ||
- (ii_throttle_delay > MIN_THROTTLE_DELAY) ||
- (ii_debug > 0))
- cmn_err(CE_NOTE,
- "!ii: ii_throttle_delay=%d", ii_throttle_delay);
- }
-
- ii_copy_direct = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "ii_copy_direct", 1);
- if (i > 0) {
- ii_copy_direct = i;
- if ((ii_copy_direct < 0) || (ii_copy_direct > 1))
- cmn_err(CE_NOTE,
- "!ii: ii_copy_direct=%d", ii_copy_direct);
- }
-
- if (_ii_init_dev()) {
- cmn_err(CE_WARN, "!ii: _ii_init_dev failed");
- goto out;
- }
- flags |= DIDINIT;
-
- xsp->dip = dip;
- xsp->instance = instance;
-
- if (ddi_create_minor_node(dip, "ii", S_IFCHR, instance, DDI_PSEUDO, 0)
- != DDI_SUCCESS) {
- cmn_err(CE_WARN, "!ii: could not create node.");
- goto out;
- }
- flags |= DIDNODES;
-
- ddi_set_driver_private(dip, (caddr_t)flags);
- ddi_report_dev(dip);
-
- ii_create_kstats();
-
- return (DDI_SUCCESS);
-
-out:
- ddi_set_driver_private(dip, (caddr_t)flags);
- (void) iidetach(dip, DDI_DETACH);
-
- return (DDI_FAILURE);
-}
-
-static int
-iidetach(dev_info_t *dip, ddi_detach_cmd_t cmd)
-{
- struct ii_state *xsp;
- int instance;
- intptr_t flags;
-
- if (cmd != DDI_DETACH) {
- return (DDI_FAILURE);
- }
-
- if (_ii_info_top) {
- return (DDI_FAILURE); /* busy */
- }
-
- instance = ddi_get_instance(dip);
- xsp = ddi_get_soft_state(ii_statep, instance);
- if (xsp == NULL) {
- cmn_err(CE_WARN,
- "!ii: detach: could not get state for instance %d.",
- instance);
- return (DDI_FAILURE);
- }
-
- flags = (intptr_t)ddi_get_driver_private(dip);
- if (flags & DIDNODES)
- ddi_remove_minor_node(dip, NULL);
- if (flags & DIDINIT)
- _ii_deinit_dev();
-
- ddi_soft_state_free(ii_statep, instance);
-
- if (ii_gkstat) {
- kstat_delete(ii_gkstat);
- ii_gkstat = NULL;
- }
-
- return (DDI_SUCCESS);
-}
-
-
-/* ARGSUSED */
-
-static int
-iiopen(dev_t *devp, int flag, int otyp, cred_t *crp)
-{
- int error;
-
- error = drv_priv(crp);
-
- return (error);
-}
-
-
-/* ARGSUSED */
-
-static int
-iiclose(dev_t dev, int flag, int otyp, cred_t *crp)
-{
- return (0);
-}
-
-/* ARGSUSED */
-
-static int
-iiprint(dev_t dev, char *str)
-{
- int instance = 0;
-
- cmn_err(CE_WARN, "!ii%d: %s", instance, str);
- return (0);
-}
-
-/* ARGSUSED */
-
-static int
-iiioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *crp, int *rvp)
-{
- int rc;
- int ilp32;
-
- ilp32 = (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32);
-
-
- switch (cmd) {
- case DSWIOC_WAIT:
- rc = _ii_wait(arg, ilp32, rvp);
- break;
-
- case DSWIOC_RESET:
- rc = _ii_reset(arg, ilp32, rvp);
- break;
-
- case DSWIOC_VERSION:
- rc = _ii_version(arg, ilp32, rvp);
- break;
-
- case DSWIOC_ENABLE:
- rc = _ii_config(arg, ilp32, rvp, 0);
- break;
-
- case DSWIOC_RESUME:
- rc = _ii_config(arg, ilp32, rvp, II_EXISTING);
- break;
-
- case DSWIOC_DISABLE:
- rc = _ii_disable(arg, ilp32, rvp);
- break;
-
- case DSWIOC_SUSPEND:
- rc = _ii_suspend(arg, ilp32, rvp);
- break;
-
- case DSWIOC_ACOPY:
- rc = _ii_acopy(arg, ilp32, rvp);
- break;
-
- case DSWIOC_COPY:
- rc = _ii_copy(arg, ilp32, rvp);
- break;
-
- case DSWIOC_SHUTDOWN:
- rc = _ii_shutdown(arg, rvp);
- break;
-
- case DSWIOC_STAT:
- rc = _ii_stat(arg, ilp32, rvp);
- break;
-
- case DSWIOC_BITMAP:
- rc = _ii_bitmap(arg, ilp32, rvp);
- break;
-
- case DSWIOC_SEGMENT:
- rc = _ii_segment(arg, ilp32, rvp);
- break;
-
- case DSWIOC_ABORT:
- rc = _ii_abort(arg, ilp32, rvp);
- break;
-
- case DSWIOC_OFFLINE:
- rc = _ii_offline(arg, ilp32, rvp);
- break;
-
- case DSWIOC_LIST:
- rc = _ii_list(arg, ilp32, rvp);
- break;
-
- case DSWIOC_LISTLEN:
- case DSWIOC_OLISTLEN:
- rc = _ii_listlen(cmd, ilp32, rvp);
- break;
-
- case DSWIOC_EXPORT:
- rc = _ii_export(arg, ilp32, rvp);
- break;
-
- case DSWIOC_IMPORT:
- rc = _ii_config(arg, ilp32, rvp, II_IMPORT);
- break;
-
- case DSWIOC_JOIN:
- rc = _ii_join(arg, ilp32, rvp);
- break;
-
- case DSWIOC_COPYP:
- rc = _ii_copyparm(arg, ilp32, rvp);
- break;
-
- case DSWIOC_OCREAT:
- rc = _ii_ocreate(arg, ilp32, rvp);
- break;
-
- case DSWIOC_OATTACH:
- rc = _ii_oattach(arg, ilp32, rvp);
- break;
-
- case DSWIOC_ODETACH:
- rc = _ii_odetach(arg, ilp32, rvp);
- break;
-
- case DSWIOC_OLIST:
- rc = _ii_olist(arg, ilp32, rvp);
- break;
-
- case DSWIOC_OSTAT:
- rc = _ii_ostat(arg, ilp32, rvp, FALSE);
- break;
-
- case DSWIOC_OSTAT2:
- rc = _ii_ostat(arg, ilp32, rvp, TRUE);
- break;
-
- case DSWIOC_SBITSSET:
- case DSWIOC_CBITSSET:
- rc = _ii_bitsset(arg, ilp32, cmd, rvp);
- break;
-
- case DSWIOC_CLIST:
- rc = _ii_gc_list(arg, ilp32, rvp, &_ii_cluster_mutex,
- _ii_cluster_top);
- break;
-
- case DSWIOC_GLIST:
- rc = _ii_gc_list(arg, ilp32, rvp, &_ii_group_mutex,
- _ii_group_top);
- break;
-
- case DSWIOC_MOVEGRP:
- rc = _ii_move_grp(arg, ilp32, rvp);
- break;
-
- case DSWIOC_CHANGETAG:
- rc = _ii_change_tag(arg, ilp32, rvp);
- break;
-
- default:
- rc = EINVAL;
- break;
- }
-
- return (rc);
-}
-
-/*
- * dummy function
- */
-
-static int
-iistrat(struct buf *bp)
-{
- bp->b_error = EIO;
- biodone(bp);
-
- return (0);
-}
-
-static int
-iiread()
-{
- return (EIO);
-}
diff --git a/usr/src/uts/common/avs/ns/dsw/dsw.h b/usr/src/uts/common/avs/ns/dsw/dsw.h
deleted file mode 100644
index 3243e9a6e9..0000000000
--- a/usr/src/uts/common/avs/ns/dsw/dsw.h
+++ /dev/null
@@ -1,485 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _DSW_H
-#define _DSW_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Miscellaneous defines
- */
-
-#define DSW_BITS 8 /* # of bits in a byte */
-#define DSW_SIZE 64 /* fba's in a DSW chunk */
-
-
-/*
- * Ioctl definitions
- */
-
-#define _D_(x) (('D'<<16)|('W'<<8)|(x))
-
-#define DSWIOC_ENABLE _D_(1) /* Configure DSW pair */
-#define DSWIOC_RESUME _D_(2) /* Resume a DSW pair */
-#define DSWIOC_SUSPEND _D_(3) /* Suspend a DSW pair */
-#define DSWIOC_COPY _D_(4) /* Copy DSW volume over its pair */
-#define DSWIOC_BITMAP _D_(5) /* Get bitmap */
-#define DSWIOC_STAT _D_(6) /* Get state of shadow */
-#define DSWIOC_DISABLE _D_(7) /* Deconfigure DSW pair */
-#define DSWIOC_SHUTDOWN _D_(8) /* Suspend all DSW pairs */
-#define DSWIOC_ABORT _D_(9) /* Abort Copy of DSW pair */
-#define DSWIOC_VERSION _D_(10) /* DataShadow version */
-#define DSWIOC_RESET _D_(11) /* Reset DataShadow set */
-#define DSWIOC_OFFLINE _D_(12) /* Offline volumes */
-#define DSWIOC_WAIT _D_(13) /* Wait for copy to complete */
-#define DSWIOC_LIST _D_(14) /* List current kernel shadow groups */
-#define DSWIOC_ACOPY _D_(15) /* Copy DSW volumes over their pairs */
-#define DSWIOC_EXPORT _D_(16) /* Export the shadow volume */
-#define DSWIOC_IMPORT _D_(17) /* Import shadow volume */
-#define DSWIOC_JOIN _D_(18) /* Rejoin previously exported shadow */
-#define DSWIOC_COPYP _D_(19) /* Set and get copy parameters */
-#define DSWIOC_OCREAT _D_(20) /* Create overflow volume */
-#define DSWIOC_OATTACH _D_(21) /* Attach overflow volume */
-#define DSWIOC_ODETACH _D_(22) /* Detach overflow volume */
-#define DSWIOC_OLIST _D_(23) /* List overflow volumes */
-#define DSWIOC_OSTAT _D_(24) /* Stat overflow volume */
-#define DSWIOC_SBITSSET _D_(25) /* Get # of bits set in shadow bitmap */
-#define DSWIOC_CBITSSET _D_(26) /* Get # of bits set in copy bitmap */
-#define DSWIOC_LISTLEN _D_(27) /* length of DSWIOC_LIST data */
-#define DSWIOC_OLISTLEN _D_(28) /* length of DSWIOC_OLIST data */
-#define DSWIOC_SEGMENT _D_(29) /* Get segemented bitmaps */
-#define DSWIOC_MOVEGRP _D_(30) /* Move set from one group to another */
-#define DSWIOC_CLIST _D_(31) /* get list of resource groups */
-#define DSWIOC_GLIST _D_(32) /* get list of groups */
-#define DSWIOC_CHANGETAG _D_(33) /* change the cluster tag of a set */
-#define DSWIOC_OSTAT2 _D_(34) /* Stat overflow volume enhanced */
-
-/*
- * Config and status flags
- */
-
-#define DSW_GOLDEN 0x0001 /* the set is independent */
-
-#define DSW_COPYINGP 0x0100 /* Copy in progress */
-#define DSW_COPYINGM 0x0200 /* Copying master to shadow */
-#define DSW_COPYINGS 0x0400 /* Copying shadow to master */
-#define DSW_COPYING 0x0600 /* Copying, may be in progress */
-#define DSW_COPY_FLAGS 0x0700 /* Copy flags */
-#define DSW_COPYINGX 0x0800 /* Copy exit requested */
-#define DSW_OFFLINE 0xf000 /* An underlying volume offline */
-#define DSW_BMPOFFLINE 0x1000 /* Bitmap volume offline */
-#define DSW_SHDOFFLINE 0x2000 /* Shadow volume offline */
-#define DSW_MSTOFFLINE 0x4000 /* Master volume offline */
-#define DSW_OVROFFLINE 0x8000 /* Overflow volume offline */
-#define DSW_TREEMAP 0x10000 /* Shadow volume accessed by an index */
-#define DSW_OVERFLOW 0x20000 /* Shadow volume has overflowed */
-#define DSW_SHDEXPORT 0x40000 /* Shadow volume has been exported */
-#define DSW_SHDIMPORT 0x80000 /* Shadow volume has been imported */
-#define DSW_VOVERFLOW 0x100000 /* Shadow volume using overflow vol */
-#define DSW_HANGING 0x200000 /* Hanging master structure */
-#define DSW_CFGOFFLINE 0x400000 /* config db is offline */
-#define DSW_OVRHDRDRTY 0x800000 /* Overflow header dirty */
-#define DSW_RESIZED 0x1000000 /* mst_size != shd_size */
-#define DSW_FRECLAIM 0x2000000 /* force the reclaim of an ovr vol */
-
-/*
- * used for SNMP trap only.
- * These flags help distinguish between enable and resume,
- * suspend and disable.
- * Note that DSW_HANGING is set for both suspend and disable
- */
-#define DSW_SNMP_CLR 0 /* no flag is set */
-#define DSW_SNMP_DISABLE 1 /* Set is disabled */
-#define DSW_SNMP_SUSPEND 2 /* Set is suspended */
-#define DSW_SNMP_ENABLE 3 /* Set is enabled */
-#define DSW_SNMP_RESUME 4 /* Set is resumed */
-#define DSW_SNMP_OVER_ATTACH 5 /* overflow attached */
-#define DSW_SNMP_OVER_DETACH 6 /* overflow detached */
-#define DSW_SNMP_UPDATE 7 /* update operation */
-#define DSW_SNMP_COPIED 8 /* copy operation */
-
- /* Overflow volume flags */
-#define IIO_OFFLINE 0x0001 /* Volume is offline */
-#define IIO_HDR_WRTN 0x0002 /* Header written */
-#define IIO_CNTR_INVLD 0x0004 /* Overflow counters invalid */
-#define IIO_VOL_UPDATE 0x0008 /* Performing group update */
-
-#define DSW_NAMELEN 64 /* NSC_MAXPATH - don't change without */
- /* amending header version number */
-
-#define DSWDEV "/dev/ii"
-#define II_IMPORTED_SHADOW "<imported_shadow>"
-
-/*
- * Configuration parameter defines
- * ii_bitmap, ii_throttle_unit, ii_throttle_delay
- */
-#define II_KMEM 0 /* Load/store on resume/suspend, in memory */
-#define II_WTHRU 1 /* Read/write bitmap thru to bitmap volume */
-#define II_FWC 2 /* Read/write bitmap to FWC, else WTHRU */
-
-#define MIN_THROTTLE_UNIT 100 /* Min. number of units to transfer */
-#define MAX_THROTTLE_UNIT 60000 /* Max. number of units to transfer */
-#define MIN_THROTTLE_DELAY 2 /* Min. delay between unit transfer */
-#define MAX_THROTTLE_DELAY 10000 /* Max. delay between unit transfer */
-
-/*
- * DSW user config structure
- */
-
-typedef struct dsw_config_s {
- spcs_s_info_t status;
- char master_vol[DSW_NAMELEN];
- char shadow_vol[DSW_NAMELEN];
- char bitmap_vol[DSW_NAMELEN];
- char cluster_tag[DSW_NAMELEN];
- char group_name[DSW_NAMELEN];
- int flag;
-} dsw_config_t;
-
-/*
- * DSW segmented bitmap I/O structure
- */
-typedef struct dsw_segment_s {
- spcs_s_info_t status;
- char shadow_vol[DSW_NAMELEN];
- unsigned seg_number; /* 32KB Segment number to start at */
- unsigned char *shd_bitmap; /* pointer to shadow bitmap */
- int shd_size; /* size of shadow bitmap */
- unsigned char *cpy_bitmap; /* pointer to copy bitmap */
- int cpy_size; /* size of copy bitmap */
- unsigned char *idx_bitmap; /* pointer to index table */
- int idx_size; /* size of index table */
-} dsw_segment_t;
-
-/*
- * DSW user bitmap structure
- */
-
-typedef struct dsw_bitmap_s {
- spcs_s_info_t status;
- char shadow_vol[DSW_NAMELEN];
- unsigned char *shd_bitmap; /* pointer to shadow bitmap */
- uint64_t shd_size; /* size of shadow bitmap */
- uint64_t copy_size; /* size of copy bitmap */
- unsigned char *copy_bitmap; /* pointer to copy bitmap */
-} dsw_bitmap_t;
-
-
-/*
- * DSW general ioctl structure
- */
-
-typedef struct dsw_ioctl_s {
- spcs_s_info_t status;
- char shadow_vol[DSW_NAMELEN];
- int flags;
- pid_t pid;
-} dsw_ioctl_t;
-
-
-/*
- * DSW general atomic ioctl structure operating on several Image sets
- */
-
-typedef struct dsw_aioctl_s {
- spcs_s_info_t status;
- int flags;
- int count;
- pid_t pid;
- char shadow_vol[DSW_NAMELEN]; /* start of list of image sets */
-} dsw_aioctl_t;
-
-
-/*
- * DSW stat ioctl structure
- */
-
-typedef struct dsw_stat_s {
- spcs_s_info_t status;
- char shadow_vol[DSW_NAMELEN];
- int stat;
- uint64_t size;
- char overflow_vol[DSW_NAMELEN];
- uint64_t shdsize;
- uint64_t shdused;
- char group_name[DSW_NAMELEN];
- char cluster_tag[DSW_NAMELEN];
- uint64_t mtime;
-} dsw_stat_t;
-
-
-/*
- * DSW version ioctl structure
- */
-
-typedef struct dsw_version_s {
- spcs_s_info_t status;
- int major; /* Major release number */
- int minor; /* Minor release number */
- int micro; /* Micro release number */
- int baseline; /* Baseline revision number */
-} dsw_version_t;
-
-/*
- * DSW get bits set in bitmap structure
- */
-
-typedef struct dsw_bitsset_s {
- spcs_s_info_t status;
- char shadow_vol[DSW_NAMELEN];
- uint64_t tot_size; /* total number of bits in map */
- uint64_t tot_set; /* number of bitmap bits set */
-} dsw_bitsset_t;
-
-
-/*
- * DSW list ioctl structure
- */
-
-typedef struct dsw_list_s {
- spcs_s_info_t status;
- int list_size; /* number of elements in list */
- int list_used; /* number of elements returned */
- dsw_config_t *list;
-} dsw_list_t;
-
-/*
- * DSW copy parameter structure
- */
-
-typedef struct dsw_copyp_s {
- spcs_s_info_t status;
- char shadow_vol[DSW_NAMELEN];
- int copy_unit;
- int copy_delay;
-} dsw_copyp_t;
-
-/*
- * DSW ostat ioctl structure
- */
-
-typedef struct dsw_ostat_s {
- spcs_s_info_t status;
- char overflow_vol[DSW_NAMELEN];
- int drefcnt;
- uint64_t used;
- uint64_t unused;
- uint64_t nchunks;
- int crefcnt;
- int flags;
- int hversion;
- int hmagic;
-} dsw_ostat_t;
-
-/*
- * DSW move group structure
- */
-
-typedef struct dsw_movegrp_s {
- spcs_s_info_t status;
- char shadow_vol[DSW_NAMELEN];
- char new_group[DSW_NAMELEN];
-} dsw_movegrp_t;
-
-/*
- * II_PIT_PROPS structure
- */
-typedef struct pit_props_s {
- int iirc;
- int mstid;
- int shdid;
- int bmpid;
- int ovrid;
- char group[DSW_NAMELEN];
- char cluster[DSW_NAMELEN];
- int has_overflow;
- int flags;
- uint64_t size;
- int64_t shdchks;
- int64_t copybits;
- int64_t shdbits;
-} pit_props_t;
-
-/*
- * II_PIT_UPDATE structure
- */
-typedef struct pit_update_s {
- int iirc;
- char direction;
-} pit_update_t;
-
-#ifdef _KERNEL
-/*
- * 32 bit versions of ioctl structures
- */
-
-typedef struct dsw_config32_s {
- spcs_s_info32_t status;
- char master_vol[DSW_NAMELEN];
- char shadow_vol[DSW_NAMELEN];
- char bitmap_vol[DSW_NAMELEN];
- char cluster_tag[DSW_NAMELEN];
- char group_name[DSW_NAMELEN];
- int flag;
-} dsw_config32_t;
-
-/*
- * DSW segmented bitmap I/O structure
- */
-typedef struct dsw_segment32_s {
- spcs_s_info32_t status;
- char shadow_vol[DSW_NAMELEN];
- uint32_t seg_number;
- uint32_t shd_bitmap;
- int shd_size;
- uint32_t cpy_bitmap;
- int cpy_size;
- uint32_t idx_bitmap;
- int idx_size;
-} dsw_segment32_t;
-
-/*
- * DSW user bitmap structure
- */
-
-typedef struct dsw_bitmap32_s {
- spcs_s_info32_t status;
- char shadow_vol[DSW_NAMELEN];
- uint32_t shd_bitmap; /* 32 bit pointer value */
- uint64_t shd_size;
- uint64_t copy_size;
- uint32_t copy_bitmap; /* 32 bit pointer value */
-} dsw_bitmap32_t;
-
-typedef struct dsw_ioctl32_s {
- spcs_s_info32_t status;
- char shadow_vol[DSW_NAMELEN];
- int flags;
- pid_t pid;
-} dsw_ioctl32_t;
-
-typedef struct dsw_stat32_s {
- spcs_s_info32_t status;
- char shadow_vol[DSW_NAMELEN];
- int stat;
- uint64_t size;
- char overflow_vol[DSW_NAMELEN];
- uint64_t shdsize;
- uint64_t shdused;
- char group_name[DSW_NAMELEN];
- char cluster_tag[DSW_NAMELEN];
- uint64_t mtime;
-} dsw_stat32_t;
-
-typedef struct dsw_version32_s {
- spcs_s_info32_t status;
- int major; /* Major release number */
- int minor; /* Minor release number */
- int micro; /* Micro release number */
- int baseline; /* Baseline revision number */
-} dsw_version32_t;
-
-typedef struct dsw_bitsset32_s {
- spcs_s_info32_t status;
- char shadow_vol[DSW_NAMELEN];
- uint64_t tot_size; /* total number of bits in map */
- uint64_t tot_set; /* number of bitmap bits set */
-} dsw_bitsset32_t;
-
-typedef struct dsw_list32_s {
- spcs_s_info32_t status;
- int list_size;
- int list_used;
- uint32_t list;
-} dsw_list32_t;
-
-typedef struct dsw_aioctl32_s {
- spcs_s_info32_t status;
- int flags;
- int count;
- pid_t pid;
- char shadow_vol[DSW_NAMELEN]; /* start of list of image sets */
-} dsw_aioctl32_t;
-
-typedef struct dsw_copyp32_s {
- spcs_s_info32_t status;
- char shadow_vol[DSW_NAMELEN];
- int copy_unit;
- int copy_delay;
-} dsw_copyp32_t;
-
-typedef struct dsw_ostat32_s {
- spcs_s_info32_t status;
- char overflow_vol[DSW_NAMELEN];
- int drefcnt;
- uint64_t used;
- uint64_t unused;
- uint64_t nchunks;
- int crefcnt;
- int flags;
- int hversion;
- int hmagic;
-} dsw_ostat32_t;
-
-/*
- * DSW move group structure
- */
-
-typedef struct dsw_movegrp32_s {
- spcs_s_info32_t status;
- char shadow_vol[DSW_NAMELEN];
- char new_group[DSW_NAMELEN];
-} dsw_movegrp32_t;
-
-#endif /* _KERNEL */
-
-/* dsw_copy dsw_ioctl_t flag bits */
-#define CV_BMP_ONLY 0x00000001 /* copy only chunks flagged by bitmap */
-#define CV_SHD2MST 0x00000002 /* copy shadow to master */
-#define CV_LOCK_PID 0x00000004 /* On copy/update, lock PIT by PID */
-#define CV_CLR_BMP 0x00000010 /* clear bits in bit map during copy */
-#define CV_IS_CLUSTER 0x00000020 /* struct refers to cluster */
-#define CV_IS_GROUP 0x00000040 /* struct refers to group (cpy/upd) */
-#define CV_SIBLING 0x00010000 /* internal copy_on_write flag */
-
-/* nsc_control commands */
-
-#define II_CONTROL(x) ('I' << 24 | 'I' << 16 | (x)) /* 0x49490000 */
-
-#define II_PIT_COPY II_CONTROL(1) /* Perform an II Copy */
-#define II_PIT_UPDATE II_CONTROL(2) /* Perform an II Update */
-#define II_PIT_ABORT II_CONTROL(3) /* Perform an II Abort */
-#define II_PIT_WAIT II_CONTROL(4) /* Perform an II Wait */
-#define II_PIT_PROPS II_CONTROL(5) /* Perform an II Properties */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _DSW_H */
diff --git a/usr/src/uts/common/avs/ns/dsw/dsw_dev.c b/usr/src/uts/common/avs/ns/dsw/dsw_dev.c
deleted file mode 100644
index 098990bc15..0000000000
--- a/usr/src/uts/common/avs/ns/dsw/dsw_dev.c
+++ /dev/null
@@ -1,10386 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/ksynch.h>
-#include <sys/kmem.h>
-#include <sys/errno.h>
-#include <sys/cmn_err.h>
-#include <sys/debug.h>
-#include <sys/ddi.h>
-#include <sys/nsc_thread.h>
-#include <sys/sysmacros.h>
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_errors.h>
-
-#include <sys/unistat/spcs_s_k.h>
-#include <sys/nsctl/nsctl.h>
-#include "dsw.h"
-#include "dsw_dev.h"
-#include "../rdc/rdc_update.h"
-#include <sys/nskernd.h>
-
-#include <sys/sdt.h> /* dtrace is S10 or later */
-
-#ifdef DS_DDICT
-#include "../contract.h"
-#endif
-
-/*
- * Instant Image
- *
- * This file contains the core implementation of II.
- *
- * II is implemented as a simple filter module that pushes itself between
- * user (SV, STE, etc.) and SDBC or NET.
- *
- */
-
-
-#define REMOTE_VOL(s, ip) (((s) && ((ip->bi_flags)&DSW_SHDEXPORT)) || \
- (!(s)&&((ip->bi_flags)&DSW_SHDIMPORT)))
-
-#define total_ref(ip) ((ip->bi_shdref + ip->bi_shdrref + ip->bi_bmpref) + \
- (NSHADOWS(ip) ? 0 : ip->bi_mstref + ip->bi_mstrref))
-
-
-#define II_TAIL_COPY(d, s, m, t) bcopy(&(s.m), &(d.m), \
- sizeof (d) - (uintptr_t)&((t *)0)->m)
-extern dev_info_t *ii_dip;
-
-#define II_LINK_CLUSTER(ip, cluster) \
- _ii_ll_add(ip, &_ii_cluster_mutex, &_ii_cluster_top, cluster, \
- &ip->bi_cluster)
-#define II_UNLINK_CLUSTER(ip) \
- _ii_ll_remove(ip, &_ii_cluster_mutex, &_ii_cluster_top, &ip->bi_cluster)
-
-#define II_LINK_GROUP(ip, group) \
- _ii_ll_add(ip, &_ii_group_mutex, &_ii_group_top, group, &ip->bi_group)
-#define II_UNLINK_GROUP(ip) \
- _ii_ll_remove(ip, &_ii_group_mutex, &_ii_group_top, &ip->bi_group)
-
-_ii_info_t *_ii_info_top;
-_ii_info_t *_ii_mst_top = 0;
-_ii_overflow_t *_ii_overflow_top;
-_ii_lsthead_t *_ii_cluster_top;
-_ii_lsthead_t *_ii_group_top;
-
-int ii_debug; /* level of cmn_err noise */
-int ii_bitmap; /* bitmap operations switch */
-uint_t ii_header = 16; /* Undocumented tunable (with adb!), start */
- /* of area cleared in volume when a dependent */
- /* shadow is disabled. */
- /* max # of chunks in copy loop before delay */
-int ii_throttle_unit = MIN_THROTTLE_UNIT;
- /* length of delay during update loop */
-int ii_throttle_delay = MIN_THROTTLE_DELAY;
-int ii_copy_direct = 1;
-int ii_nconcopy = 10; /* default value when starting with no cache */
-kmutex_t _ii_cluster_mutex;
-kmutex_t _ii_group_mutex;
-
-static int _ii_shutting_down = 0;
-static nsc_io_t *_ii_io, *_ii_ior;
-static nsc_mem_t *_ii_local_mem;
-static nsc_def_t _ii_fd_def[], _ii_io_def[], _ii_ior_def[];
-static kmutex_t _ii_info_mutex;
-static kmutex_t _ii_overflow_mutex;
-static kmutex_t _ii_config_mutex;
-static _ii_bmp_ops_t alloc_buf_bmp, kmem_buf_bmp;
-static nsc_svc_t *ii_volume_update; /* IIVolumeUpdate token */
-static nsc_svc_t *ii_report_luns; /* IIReportLuns token */
-static nsc_svc_t *ii_get_initiators; /* IIGetInitiators token */
-static ksema_t _ii_concopy_sema;
-static int _ii_concopy_init = 0;
-static int _ii_instance = 0;
-
-void _ii_deinit_dev();
-
-static void _ii_info_free(_ii_info_t *ip);
-static void _ii_info_freeshd(_ii_info_t *ip);
-static void ii_sibling_free(_ii_info_t *ip);
-ii_header_t *_ii_bm_header_get(_ii_info_t *ip, nsc_buf_t **tmp);
-int _ii_bm_header_put(ii_header_t *hdr, _ii_info_t *ip,
- nsc_buf_t *tmp);
-static void _ii_bm_header_free(ii_header_t *hdr, _ii_info_t *ip,
- nsc_buf_t *tmp);
-static int _ii_copyvol(_ii_info_t *, int, int, spcs_s_info_t, int);
-static void _ii_stopvol(_ii_info_t *ip);
-static int _ii_stopcopy(_ii_info_t *ip);
-static _ii_info_t *_ii_find_set(char *volume);
-static _ii_info_t *_ii_find_vol(char *, int);
-static _ii_overflow_t *_ii_find_overflow(char *volume);
-static void _ii_ioctl_done(_ii_info_t *ip);
-static void _ii_lock_chunk(_ii_info_t *ip, chunkid_t);
-static void _ii_unlock_chunks(_ii_info_t *ip, chunkid_t, int);
-void _ii_error(_ii_info_t *ip, int error_type);
-static nsc_buf_t *_ii_alloc_handle(void (*d_cb)(), void (*r_cb)(),
- void (*w_cb)(), ii_fd_t *bfd);
-static int _ii_free_handle(ii_buf_t *h, ii_fd_t *bfd);
-extern nsc_size_t ii_btsize(nsc_size_t);
-extern int ii_tinit(_ii_info_t *);
-extern chunkid_t ii_tsearch(_ii_info_t *, chunkid_t);
-extern void ii_tdelete(_ii_info_t *, chunkid_t);
-extern void ii_reclaim_overflow(_ii_info_t *);
-static void ii_overflow_free(_ii_info_t *ip, int disable);
-static int ii_overflow_attach(_ii_info_t *, char *, int);
-int _ii_nsc_io(_ii_info_t *, int, nsc_fd_t *, int, nsc_off_t, unsigned char *,
- nsc_size_t);
-static nsc_path_t *_ii_register_path(char *path, int type, nsc_io_t *io);
-static int _ii_unregister_path(nsc_path_t *sp, int flag, char *type);
-static int _ii_reserve_begin(_ii_info_t *ip);
-static int _ii_wait_for_it(_ii_info_t *ip);
-static void _ii_reserve_end(_ii_info_t *ip);
-static kstat_t *_ii_overflow_kstat_create(_ii_info_t *ip, _ii_overflow_t *op);
-static int _ii_ll_add(_ii_info_t *, kmutex_t *, _ii_lsthead_t **, char *,
- char **);
-static int _ii_ll_remove(_ii_info_t *, kmutex_t *, _ii_lsthead_t **, char **);
-#define _ii_unlock_chunk(ip, chunk) _ii_unlock_chunks(ip, chunk, 1)
-extern const int dsw_major_rev;
-extern const int dsw_minor_rev;
-extern const int dsw_micro_rev;
-extern const int dsw_baseline_rev;
-
-/*
- * These constants are used by ii_overflow_free() to indicate how the
- * reclamation should take place.
- * NO_RECLAIM: just detach the overflow from the set; do not
- * attempt to reclaim chunks, do not decrement the
- * used-by count
- * RECLAIM: reclaim all chunks before decrementing the used-by count
- * INIT_OVR: decrement the used-by count only; do not reclaim chunks
- */
-
-#define NO_RECLAIM 0
-#define RECLAIM 1
-#define INIT_OVR 2
-
-struct copy_args { /* arguments passed to copy process */
- _ii_info_t *ip;
- int flag;
- int rtype;
- int wait;
- spcs_s_info_t kstatus;
- int rc;
-};
-
-/* set-specific kstats info */
-ii_kstat_set_t ii_kstat_set = {
- { DSW_SKSTAT_SIZE, KSTAT_DATA_ULONG },
- { DSW_SKSTAT_MTIME, KSTAT_DATA_ULONG },
- { DSW_SKSTAT_FLAGS, KSTAT_DATA_ULONG },
- { DSW_SKSTAT_THROTTLE_UNIT, KSTAT_DATA_ULONG },
- { DSW_SKSTAT_THROTTLE_DELAY, KSTAT_DATA_ULONG },
- { DSW_SKSTAT_SHDCHKS, KSTAT_DATA_ULONG },
- { DSW_SKSTAT_SHDCHKUSED, KSTAT_DATA_ULONG },
- { DSW_SKSTAT_SHDBITS, KSTAT_DATA_ULONG },
- { DSW_SKSTAT_COPYBITS, KSTAT_DATA_ULONG },
- { DSW_SKSTAT_MSTA, KSTAT_DATA_CHAR },
- { DSW_SKSTAT_MSTB, KSTAT_DATA_CHAR },
- { DSW_SKSTAT_MSTC, KSTAT_DATA_CHAR },
- { DSW_SKSTAT_MSTD, KSTAT_DATA_CHAR },
- { DSW_SKSTAT_SETA, KSTAT_DATA_CHAR },
- { DSW_SKSTAT_SETB, KSTAT_DATA_CHAR },
- { DSW_SKSTAT_SETC, KSTAT_DATA_CHAR },
- { DSW_SKSTAT_SETD, KSTAT_DATA_CHAR },
- { DSW_SKSTAT_BMPA, KSTAT_DATA_CHAR },
- { DSW_SKSTAT_BMPB, KSTAT_DATA_CHAR },
- { DSW_SKSTAT_BMPC, KSTAT_DATA_CHAR },
- { DSW_SKSTAT_BMPD, KSTAT_DATA_CHAR },
- { DSW_SKSTAT_OVRA, KSTAT_DATA_CHAR },
- { DSW_SKSTAT_OVRB, KSTAT_DATA_CHAR },
- { DSW_SKSTAT_OVRC, KSTAT_DATA_CHAR },
- { DSW_SKSTAT_OVRD, KSTAT_DATA_CHAR },
- { DSW_SKSTAT_MSTIO, KSTAT_DATA_CHAR },
- { DSW_SKSTAT_SHDIO, KSTAT_DATA_CHAR },
- { DSW_SKSTAT_BMPIO, KSTAT_DATA_CHAR },
- { DSW_SKSTAT_OVRIO, KSTAT_DATA_CHAR },
-};
-
-/*
- * _ii_init_dev
- * Initialise the shadow driver
- *
- */
-
-int
-_ii_init_dev()
-{
- _ii_io = nsc_register_io("ii", NSC_II_ID|NSC_REFCNT|NSC_FILTER,
- _ii_io_def);
- if (_ii_io == NULL)
- cmn_err(CE_WARN, "!ii: nsc_register_io failed.");
-
- _ii_ior = nsc_register_io("ii-raw", NSC_IIR_ID|NSC_REFCNT|NSC_FILTER,
- _ii_ior_def);
- if (_ii_ior == NULL)
- cmn_err(CE_WARN, "!ii: nsc_register_io r failed.");
-
- _ii_local_mem = nsc_register_mem("ii:kmem", NSC_MEM_LOCAL, 0);
- if (_ii_local_mem == NULL)
- cmn_err(CE_WARN, "!ii: nsc_register_mem failed.");
-
-
- if (!_ii_io || !_ii_ior || !_ii_local_mem) {
- _ii_deinit_dev();
- return (ENOMEM);
- }
-
- mutex_init(&_ii_info_mutex, NULL, MUTEX_DRIVER, NULL);
- mutex_init(&_ii_overflow_mutex, NULL, MUTEX_DRIVER, NULL);
- mutex_init(&_ii_config_mutex, NULL, MUTEX_DRIVER, NULL);
- mutex_init(&_ii_cluster_mutex, NULL, MUTEX_DRIVER, NULL);
- mutex_init(&_ii_group_mutex, NULL, MUTEX_DRIVER, NULL);
-
- ii_volume_update = nsc_register_svc("RDCVolumeUpdated", 0);
- ii_report_luns = nsc_register_svc("IIReportLuns", 0);
- ii_get_initiators = nsc_register_svc("IIGetInitiators", 0);
-
- if (!ii_volume_update || !ii_report_luns || !ii_get_initiators) {
- _ii_deinit_dev();
- return (ENOMEM);
- }
-
- return (0);
-}
-
-
-/*
- * _ii_deinit_dev
- * De-initialise the shadow driver
- *
- */
-
-void
-_ii_deinit_dev()
-{
-
- if (_ii_io)
- (void) nsc_unregister_io(_ii_io, 0);
-
- if (_ii_ior)
- (void) nsc_unregister_io(_ii_ior, 0);
-
- if (_ii_local_mem)
- (void) nsc_unregister_mem(_ii_local_mem);
-
- if (ii_volume_update)
- (void) nsc_unregister_svc(ii_volume_update);
-
- if (ii_report_luns)
- (void) nsc_unregister_svc(ii_report_luns);
-
- if (ii_get_initiators)
- (void) nsc_unregister_svc(ii_get_initiators);
-
- mutex_destroy(&_ii_info_mutex);
- mutex_destroy(&_ii_overflow_mutex);
- mutex_destroy(&_ii_config_mutex);
- mutex_destroy(&_ii_cluster_mutex);
- mutex_destroy(&_ii_group_mutex);
- if (_ii_concopy_init)
- sema_destroy(&_ii_concopy_sema);
- _ii_concopy_init = 0;
-
-}
-
-static char *
-ii_pathname(nsc_fd_t *fd)
-{
- char *rc;
-
- if (fd == NULL || (rc = nsc_pathname(fd)) == NULL)
- return ("");
- else
- return (rc);
-}
-
-
-/*
- * _ii_rlse_d
- * Internal mechanics of _ii_rlse_devs(). Takes care of
- * resetting the ownership information as required.
- */
-
-static void
-_ii_rlse_d(ip, mst, raw)
-_ii_info_t *ip;
-int mst, raw;
-{
- _ii_info_dev_t *cip;
- _ii_info_dev_t *rip;
-
- rip = mst ? (ip->bi_mstrdev) : &(ip->bi_shdrdev);
- cip = mst ? (ip->bi_mstdev) : &(ip->bi_shddev);
-
- DTRACE_PROBE2(_ii_rlse_d_type,
- _ii_info_dev_t *, rip,
- _ii_info_dev_t *, cip);
-
-
- if (RSRV(cip)) {
- if (raw) {
- ASSERT(cip->bi_orsrv > 0);
- cip->bi_orsrv--;
- } else {
- ASSERT(cip->bi_rsrv > 0);
- cip->bi_rsrv--;
- }
-
- if (cip->bi_rsrv > 0) {
- nsc_set_owner(cip->bi_fd, cip->bi_iodev);
- } else if (cip->bi_orsrv > 0) {
- nsc_set_owner(cip->bi_fd, rip->bi_iodev);
- } else {
- nsc_set_owner(cip->bi_fd, NULL);
- }
-
- if (!RSRV(cip)) {
- nsc_release(cip->bi_fd);
- }
- } else {
- if (raw) {
- ASSERT(rip->bi_rsrv > 0);
- rip->bi_rsrv--;
- } else {
- ASSERT(rip->bi_orsrv > 0);
- rip->bi_orsrv--;
- }
-
- if (rip->bi_rsrv > 0) {
- nsc_set_owner(rip->bi_fd, rip->bi_iodev);
- } else if (rip->bi_orsrv > 0) {
- nsc_set_owner(rip->bi_fd, cip->bi_iodev);
- } else {
- nsc_set_owner(rip->bi_fd, NULL);
- }
-
- if (!RSRV(rip)) {
- rip->bi_flag = 0;
- nsc_release(rip->bi_fd);
- cv_broadcast(&ip->bi_releasecv);
- }
- }
-
-}
-
-
-/*
- * _ii_rlse_devs
- * Release named underlying devices.
- *
- * NOTE: the 'devs' argument must be the same as that passed to
- * the preceding _ii_rsrv_devs call.
- */
-
-void
-_ii_rlse_devs(ip, devs)
-_ii_info_t *ip;
-int devs;
-{
-
- ASSERT(!(devs & (MST|SHD)));
-
- ASSERT(ip->bi_head != (_ii_info_t *)0xdeadbeef);
- if (!ip) {
- cmn_err(CE_WARN, "!ii: _ii_rlse_devs null ip");
- return;
- }
-
- mutex_enter(&ip->bi_rsrvmutex);
-
- DTRACE_PROBE(_ii_rlse_devs_mutex);
-
- if ((devs&(MST|MSTR)) != 0 && (ip->bi_flags&DSW_SHDIMPORT) == 0) {
- if (NSHADOWS(ip) && ip != ip->bi_master)
- _ii_rlse_devs(ip->bi_master, devs&(MST|MSTR));
- else
- _ii_rlse_d(ip, 1, (devs&MSTR));
- }
-
- if ((devs&(SHD|SHDR)) != 0 && (ip->bi_flags&DSW_SHDEXPORT) == 0) {
- _ii_rlse_d(ip, 0, (devs&SHDR));
- }
-
- if ((devs&BMP) != 0 && ip->bi_bmpfd) {
- if (--(ip->bi_bmprsrv) == 0)
- nsc_release(ip->bi_bmpfd);
- }
-
- ASSERT(ip->bi_bmprsrv >= 0);
- ASSERT(ip->bi_shdrsrv >= 0);
- ASSERT(ip->bi_shdrrsrv >= 0);
- mutex_exit(&ip->bi_rsrvmutex);
-
-}
-
-
-/*
- * _ii_rsrv_d
- * Reserve device flagged, unless its companion is already reserved,
- * in that case increase the reserve on the companion.
- */
-
-static int
-_ii_rsrv_d(int raw, _ii_info_dev_t *rid, _ii_info_dev_t *cid, int flag,
- _ii_info_t *ip)
-{
- _ii_info_dev_t *p = NULL;
- int other = 0;
- int rc;
-
- /*
- * If user wants to do a cache reserve and it's already
- * raw reserved, we need to do a real nsc_reserve, so wait
- * until the release has been done.
- */
- if (RSRV(rid) && (flag == II_EXTERNAL) &&
- (raw == 0) && (rid->bi_flag != II_EXTERNAL)) {
- ip->bi_release++;
- while (RSRV(rid)) {
- DTRACE_PROBE1(_ii_rsrv_d_wait, _ii_info_dev_t *, rid);
- cv_wait(&ip->bi_releasecv, &ip->bi_rsrvmutex);
- DTRACE_PROBE1(_ii_rsrv_d_resume, _ii_info_dev_t *, rid);
- }
- ip->bi_release--;
- }
-
- if (RSRV(rid)) {
- p = rid;
- if (!raw) {
- other = 1;
- }
- } else if (RSRV(cid)) {
- p = cid;
- if (raw) {
- other = 1;
- }
- }
-
- if (p) {
- if (other) {
- p->bi_orsrv++;
- } else {
- p->bi_rsrv++;
- }
-
- if (p->bi_iodev) {
- nsc_set_owner(p->bi_fd, p->bi_iodev);
- }
-
- return (0);
- }
- p = raw ? rid : cid;
-
- if ((rc = nsc_reserve(p->bi_fd, 0)) == 0) {
- if (p->bi_iodev) {
- nsc_set_owner(p->bi_fd, p->bi_iodev);
- }
- p->bi_rsrv++;
- if (raw)
- p->bi_flag = flag;
- }
-
- return (rc);
-}
-
-/*
- * _ii_rsrv_devs
- * Reserve named underlying devices.
- *
- */
-
-int
-_ii_rsrv_devs(_ii_info_t *ip, int devs, int flag)
-{
- int rc = 0;
- int got = 0;
-
- ASSERT(!(devs & (MST|SHD)));
-
- if (!ip) {
- cmn_err(CE_WARN, "!ii: _ii_rsrv_devs null ip");
- return (EINVAL);
- }
-
- mutex_enter(&ip->bi_rsrvmutex);
-
- DTRACE_PROBE(_ii_rsrv_devs_mutex);
-
- if (rc == 0 && (devs&(MST|MSTR)) != 0 &&
- (ip->bi_flags&DSW_SHDIMPORT) == 0) {
- DTRACE_PROBE(_ii_rsrv_devs_master);
- if (NSHADOWS(ip) && ip != ip->bi_master) {
- if ((rc = _ii_rsrv_devs(ip->bi_master, devs&(MST|MSTR),
- flag)) != 0) {
- cmn_err(CE_WARN,
- "!ii: nsc_reserve multi-master failed");
- } else {
- got |= devs&(MST|MSTR);
- }
- } else {
- if ((rc = _ii_rsrv_d((devs&MSTR) != 0, ip->bi_mstrdev,
- ip->bi_mstdev, flag, ip)) != 0) {
- cmn_err(CE_WARN,
- "!ii: nsc_reserve master failed %d", rc);
- } else {
- got |= (devs&(MST|MSTR));
- }
- }
- }
-
- if (rc == 0 && (devs&(SHD|SHDR)) != 0 &&
- (ip->bi_flags&DSW_SHDEXPORT) == 0) {
- DTRACE_PROBE(_ii_rsrv_devs_shadow);
- if ((rc = _ii_rsrv_d((devs&SHDR) != 0, &ip->bi_shdrdev,
- &ip->bi_shddev, flag, ip)) != 0) {
- cmn_err(CE_WARN,
- "!ii: nsc_reserve shadow failed %d", rc);
- } else {
- got |= (devs&(SHD|SHDR));
- }
- }
-
- if (rc == 0 && (devs&BMP) != 0 && ip->bi_bmpfd) {
- DTRACE_PROBE(_ii_rsrv_devs_bitmap);
- if ((ip->bi_bmprsrv == 0) &&
- (rc = nsc_reserve(ip->bi_bmpfd, 0)) != 0) {
- cmn_err(CE_WARN,
- "!ii: nsc_reserve bitmap failed %d", rc);
- } else {
- (ip->bi_bmprsrv)++;
- got |= BMP;
- }
- }
- mutex_exit(&ip->bi_rsrvmutex);
- if (rc != 0 && got != 0)
- _ii_rlse_devs(ip, got);
-
- return (rc);
-}
-
-static int
-_ii_reserve_begin(_ii_info_t *ip)
-{
- int rc;
-
- mutex_enter(&ip->bi_rlsemutex);
- if ((rc = _ii_wait_for_it(ip)) == 0) {
- ++ip->bi_rsrvcnt;
- }
- mutex_exit(&ip->bi_rlsemutex);
-
- return (rc);
-}
-
-static int
-_ii_wait_for_it(_ii_info_t *ip)
-{
- int nosig;
-
- nosig = 1;
- while (ip->bi_rsrvcnt > 0) {
- nosig = cv_wait_sig(&ip->bi_reservecv, &ip->bi_rlsemutex);
- if (!nosig) {
- break;
- }
- }
-
- return (nosig? 0 : EINTR);
-}
-
-static void
-_ii_reserve_end(_ii_info_t *ip)
-{
- mutex_enter(&ip->bi_rlsemutex);
- if (ip->bi_rsrvcnt <= 0) {
- mutex_exit(&ip->bi_rlsemutex);
- return;
- }
- --ip->bi_rsrvcnt;
- mutex_exit(&ip->bi_rlsemutex);
- cv_broadcast(&ip->bi_reservecv);
-
-}
-
-static int
-ii_fill_copy_bmp(_ii_info_t *ip)
-{
- int rc;
- chunkid_t max_chunk, chunk_num;
-
- if ((rc = II_FILL_COPY_BMP(ip)) != 0)
- return (rc);
- /*
- * make certain that the last bits of the last byte of the bitmap
- * aren't filled as they may be copied out to the user.
- */
-
- chunk_num = ip->bi_size / DSW_SIZE;
- if ((ip->bi_size % DSW_SIZE) != 0)
- ++chunk_num;
-
- max_chunk = chunk_num;
- if ((max_chunk & 0x7) != 0)
- max_chunk = (max_chunk + 7) & ~7;
-
- DTRACE_PROBE2(_ii_fill_copy_bmp_chunks, chunkid_t, chunk_num,
- chunkid_t, max_chunk);
-
- for (; chunk_num < max_chunk; chunk_num++) {
- (void) II_CLR_COPY_BIT(ip, chunk_num);
- }
-
- return (0);
-}
-
-static int
-ii_update_denied(_ii_info_t *ip, spcs_s_info_t kstatus,
- int direction, int all)
-{
- rdc_update_t update;
- int size;
- unsigned char *bmp;
-
- update.volume = direction == CV_SHD2MST ? ii_pathname(MSTFD(ip)) :
- ip->bi_keyname;
- update.denied = 0;
- update.protocol = RDC_SVC_ONRETURN;
- update.size = size = FBA_SIZE(DSW_BM_FBA_LEN(ip->bi_size));
- update.status = kstatus;
- update.bitmap = bmp = kmem_alloc(update.size, KM_SLEEP);
- if (bmp == NULL) {
- spcs_s_add(kstatus, ENOMEM);
- return (1);
- }
-
- DTRACE_PROBE2(_ii_update_denied, int, all, int, size);
-
- if (all) {
- while (size-- > 0)
- *bmp++ = (unsigned char)0xff;
- } else {
- if (II_CHANGE_BMP(ip, update.bitmap) != 0) {
- /* failed to read bitmap */
- spcs_s_add(kstatus, EIO);
- update.denied = 1;
- }
- }
-
- /* check that no user of volume objects */
- if (update.denied == 0) {
- (void) nsc_call_svc(ii_volume_update, (intptr_t)&update);
- }
- kmem_free(update.bitmap, FBA_SIZE(DSW_BM_FBA_LEN(ip->bi_size)));
-
- return (update.denied);
-}
-
-static int
-ii_need_same_size(_ii_info_t *ip)
-{
- rdc_update_t update;
-
- update.volume = ip->bi_keyname;
- update.denied = 0;
- update.protocol = RDC_SVC_VOL_ENABLED;
-
- (void) nsc_call_svc(ii_volume_update, (intptr_t)&update);
-
- return (update.denied);
-}
-
-/*
- * ii_volume: check if vol is already known to Instant Image and return
- * volume type if it is.
- */
-
-static int
-ii_volume(char *vol, int locked)
-{
- _ii_info_t *ip;
- _ii_overflow_t *op;
- int rc = NONE;
-
- /* scan overflow volume list */
- mutex_enter(&_ii_overflow_mutex);
-
- DTRACE_PROBE(_ii_volume_mutex);
-
- for (op = _ii_overflow_top; op; op = op->ii_next) {
- if (strcmp(vol, op->ii_volname) == 0)
- break;
- }
- mutex_exit(&_ii_overflow_mutex);
- if (op) {
- return (OVR);
- }
-
- if (!locked) {
- mutex_enter(&_ii_info_mutex);
- }
-
- DTRACE_PROBE(_ii_volume_mutex2);
-
- for (ip = _ii_info_top; ip; ip = ip->bi_next) {
- if (strcmp(vol, ii_pathname(ip->bi_mstfd)) == 0) {
- rc = MST;
- break;
- }
- if (strcmp(vol, ip->bi_keyname) == 0) {
- rc = SHD;
- break;
- }
- if (strcmp(vol, ii_pathname(ip->bi_bmpfd)) == 0) {
- rc = BMP;
- break;
- }
- }
- DTRACE_PROBE1(_ii_volume_data, int, rc);
-
- if (!locked) {
- mutex_exit(&_ii_info_mutex);
- }
-
- return (rc);
-}
-
-/*
- * ii_open_shadow: open shadow volume for both cached and raw access,
- * if the normal device open fails attempt a file open to allow
- * shadowing into a file.
- */
-
-static int
-ii_open_shadow(_ii_info_t *ip, char *shadow_vol)
-{
- int rc = 0;
- int file_rc = 0;
-
- ip->bi_shdfd = nsc_open(shadow_vol,
- NSC_IIR_ID|NSC_DEVICE|NSC_RDWR, _ii_fd_def,
- (blind_t)&(ip->bi_shddev), &rc);
- if (!ip->bi_shdfd) {
- ip->bi_shdfd = nsc_open(shadow_vol,
- NSC_IIR_ID|NSC_FILE|NSC_RDWR, _ii_fd_def,
- (blind_t)&(ip->bi_shddev), &file_rc);
- file_rc = 1;
- if (!ip->bi_shdfd) {
- return (rc);
- }
- DTRACE_PROBE(_ii_open_shadow);
- }
- else
- DTRACE_PROBE(_ii_open_shadow);
-
- if (file_rc == 0) {
- ip->bi_shdrfd = nsc_open(shadow_vol,
- NSC_IIR_ID|NSC_DEVICE|NSC_RDWR, _ii_fd_def,
- (blind_t)&(ip->bi_shdrdev), &rc);
- DTRACE_PROBE(_ii_open_shadow);
- } else {
- ip->bi_shdrfd = nsc_open(shadow_vol,
- NSC_IIR_ID|NSC_FILE|NSC_RDWR, _ii_fd_def,
- (blind_t)&(ip->bi_shdrdev), &rc);
- DTRACE_PROBE(_ii_open_shadow);
- }
-
- if (!ip->bi_shdrfd) {
- (void) nsc_close(ip->bi_shdfd);
- DTRACE_PROBE(_ii_open_shadow);
- return (rc);
- }
-
- return (0);
-}
-
-static void
-ii_register_shd(_ii_info_t *ip)
-{
- ip->bi_shd_tok = _ii_register_path(ip->bi_keyname,
- NSC_CACHE, _ii_io);
- ip->bi_shdr_tok = _ii_register_path(ip->bi_keyname,
- NSC_DEVICE, _ii_ior);
-
-}
-
-static void
-ii_register_mst(_ii_info_t *ip)
-{
- ip->bi_mst_tok = _ii_register_path(ii_pathname(ip->bi_mstfd),
- NSC_CACHE, _ii_io);
- ip->bi_mstr_tok = _ii_register_path(ii_pathname(ip->bi_mstrfd),
- NSC_DEVICE, _ii_ior);
-
-}
-
-static int
-ii_register_ok(_ii_info_t *ip)
-{
- int rc;
- int sibling;
- int exported;
-
- rc = 1;
- sibling = NSHADOWS(ip) && ip != ip->bi_head;
- exported = ip->bi_flags & DSW_SHDEXPORT;
-
- if ((ip->bi_bmpfd && !ip->bi_bmp_tok) || (!exported && (
- !ip->bi_shd_tok || !ip->bi_shdr_tok)))
- rc = 0;
- else if (!sibling && (!ip->bi_mst_tok || !ip->bi_mstr_tok))
- rc = 0;
-
- return (rc);
-}
-
-#ifndef DISABLE_KSTATS
-
-/*
- * _ii_kstat_create
- * Create and install kstat_io data
- *
- * Calling/Exit State:
- * Returns 0 if kstats couldn't be created, otherwise it returns
- * a pointer to the created kstat_t.
- */
-
-static kstat_t *
-_ii_kstat_create(_ii_info_t *ip, char *type)
-{
- kstat_t *result;
- char name[ IOSTAT_NAME_LEN ];
- int setnum;
- char *nptr;
- static int mstnum = 0;
- static int shdbmpnum = -1;
-
- switch (*type) {
- case 'm':
- setnum = mstnum++;
- nptr = ip->bi_kstat_io.mstio;
- break;
- case 's':
- /* assumption: shadow kstats created before bitmap */
- setnum = ++shdbmpnum;
- nptr = ip->bi_kstat_io.shdio;
- break;
- case 'b':
- setnum = shdbmpnum;
- nptr = ip->bi_kstat_io.bmpio;
- break;
- default:
- cmn_err(CE_WARN, "!Unable to determine kstat type (%c)", *type);
- setnum = -1;
- break;
- }
- /*
- * The name of the kstat, defined below, is designed to work
- * with the 'iostat -x' command. This command leaves only
- * 9 characters for the name, and the kstats built in to Solaris
- * all seem to be of the form <service><number>. For that
- * reason, we have chosen ii<type><number>, where <type> is
- * m, s, b, or o (for master, shadow, bitmap, and overflow
- * respectively), and the number is monotonically increasing from
- * 0 for each time one of those <type>s are created. Note that
- * the shadow and bitmap are always created in pairs and so, for
- * any given set, they will have the same <number>.
- */
- (void) sprintf(name, "ii%c%d", *type, setnum);
- (void) strncpy(nptr, name, IOSTAT_NAME_LEN);
- result = kstat_create("ii", 0, name, "disk", KSTAT_TYPE_IO, 1, 0);
- if (result) {
- result->ks_private = ip;
- result->ks_lock = &ip->bi_kstat_io.statmutex;
- kstat_install(result);
- } else {
- cmn_err(CE_WARN, "!Unable to create %s kstats for set %s", type,
- ip->bi_keyname);
- }
-
- return (result);
-}
-
-/*
- * _ii_overflow_kstat_create
- * Create and install kstat_io data for an overflow volume
- *
- * Calling/Exit State:
- * Returns 0 if kstats couldn't be created, otherwise it returns
- * a pointer to the created kstat_t.
- *
- * See comments in _ii_kstat_create for additional information.
- *
- */
-static kstat_t *
-_ii_overflow_kstat_create(_ii_info_t *ip, _ii_overflow_t *op)
-{
- kstat_t *result;
- char *nptr;
- char name [IOSTAT_NAME_LEN];
- static int ovrnum = 0;
- int setnum = ovrnum++;
-
- nptr = ip->bi_kstat_io.ovrio;
-
- (void) sprintf(name, "iio%d", setnum);
- (void) strncpy(nptr, name, IOSTAT_NAME_LEN);
-
- mutex_init(&op->ii_kstat_mutex, NULL, MUTEX_DRIVER, NULL);
-
- if ((result =
- kstat_create("ii", 0, name, "disk", KSTAT_TYPE_IO, 1, 0))) {
- result->ks_private = ip;
- result->ks_lock = &op->ii_kstat_mutex;
- kstat_install(result);
- } else {
- mutex_destroy(&op->ii_kstat_mutex);
- cmn_err(CE_WARN, "!Unabled to create overflow kstat for set "
- "%s", ip->bi_keyname);
- }
-
- return (result);
-}
-
-#endif
-
-static void
-ii_str_kstat_copy(char *str, char *p1, char *p2, char *p3, char *p4)
-{
- static int whinged = 0;
- char *part[ 4 ];
- char fulldata[ DSW_NAMELEN ];
- int i, offset, remain;
- int num_parts;
- int leftover;
- int kscharsize = KSTAT_DATA_CHAR_LEN - 1;
-
- /*
- * NOTE: the following lines must be changed if DSW_NAMELEN
- * ever changes. You'll need a part[] for every kscharsize
- * characters (or fraction thereof). The ii_kstat_set_t
- * definition in dsw_dev.h will also need new ovr_? entries.
- */
- part[ 0 ] = p1;
- part[ 1 ] = p2;
- part[ 2 ] = p3;
- part[ 3 ] = p4;
-
- bzero(fulldata, DSW_NAMELEN);
- if (str) {
- (void) strncpy(fulldata, str, DSW_NAMELEN);
- }
-
- num_parts = DSW_NAMELEN / kscharsize;
- leftover = DSW_NAMELEN % kscharsize;
- if (leftover) {
- ++num_parts;
- }
-
- if (num_parts > sizeof (part) / sizeof (part[0])) {
- /*
- * DSW_NAMELEN is 64 and kscharsize is 15.
- * It's always "whinged"
- */
- if (!whinged) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!May not have enough room "
- "to store volume name in kstats");
-#endif
- whinged = 1;
- }
- num_parts = sizeof (part) / sizeof (part[0]);
- }
-
- offset = 0;
- remain = DSW_NAMELEN;
- for (i = 0; i < num_parts; i++) {
- int to_copy = remain > kscharsize? kscharsize : remain;
- bcopy(&fulldata[ offset ], part[ i ], to_copy);
- offset += to_copy;
- remain -= to_copy;
- }
-}
-
-static int
-ii_set_stats_update(kstat_t *ksp, int rw)
-{
- _ii_info_t *ip = (_ii_info_t *)ksp->ks_private;
- ii_kstat_set_t *kp = (ii_kstat_set_t *)ksp->ks_data;
-
- if (KSTAT_WRITE == rw) {
- return (EACCES);
- }
-
- /* copy values over */
- kp->size.value.ul = ip->bi_size;
- kp->flags.value.ul = ip->bi_flags;
- kp->unit.value.ul = ip->bi_throttle_unit;
- kp->delay.value.ul = ip->bi_throttle_delay;
- kp->mtime.value.ul = ip->bi_mtime;
-
- /* update bitmap counters if necessary */
- if (ip->bi_state & DSW_CNTCPYBITS) {
- ip->bi_copybits = 0;
- if (_ii_rsrv_devs(ip, BMP, II_INTERNAL) == 0) {
- ip->bi_state &= ~DSW_CNTCPYBITS;
- II_CNT_BITS(ip, ip->bi_copyfba,
- &ip->bi_copybits,
- DSW_BM_SIZE_BYTES(ip));
- _ii_rlse_devs(ip, BMP);
- }
- }
-
- if (ip->bi_state & DSW_CNTSHDBITS) {
- ip->bi_shdbits = 0;
- if (_ii_rsrv_devs(ip, BMP, II_INTERNAL) == 0) {
- ip->bi_state &= ~DSW_CNTSHDBITS;
- II_CNT_BITS(ip, ip->bi_shdfba,
- &ip->bi_shdbits,
- DSW_BM_SIZE_BYTES(ip));
- _ii_rlse_devs(ip, BMP);
- }
- }
-
- kp->copybits.value.ul = ip->bi_copybits;
- kp->shdbits.value.ul = ip->bi_shdbits;
-
- /* copy volume names */
- ii_str_kstat_copy(ii_pathname(MSTFD(ip)),
- kp->mst_a.value.c, kp->mst_b.value.c,
- kp->mst_c.value.c, kp->mst_d.value.c);
-
- ii_str_kstat_copy(ip->bi_keyname, kp->set_a.value.c, kp->set_b.value.c,
- kp->set_c.value.c, kp->set_d.value.c);
-
- ii_str_kstat_copy(ii_pathname(ip->bi_bmpfd),
- kp->bmp_a.value.c, kp->bmp_b.value.c,
- kp->bmp_c.value.c, kp->bmp_d.value.c);
-
- if (ip->bi_overflow) {
- ii_str_kstat_copy(ip->bi_overflow->ii_volname,
- kp->ovr_a.value.c, kp->ovr_b.value.c, kp->ovr_c.value.c,
- kp->ovr_d.value.c);
- (void) strlcpy(kp->ovr_io.value.c, ip->bi_kstat_io.ovrio,
- KSTAT_DATA_CHAR_LEN);
- } else {
- ii_str_kstat_copy("", kp->ovr_a.value.c, kp->ovr_b.value.c,
- kp->ovr_c.value.c, kp->ovr_d.value.c);
- bzero(kp->ovr_io.value.c, KSTAT_DATA_CHAR_LEN);
- }
- if ((ip->bi_flags) & DSW_TREEMAP) {
- kp->shdchks.value.ul = ip->bi_shdchks;
- kp->shdchkused.value.ul = ip->bi_shdchkused;
- } else {
- kp->shdchks.value.ul = 0;
- kp->shdchkused.value.ul = 0;
- }
- /* make sure value.c are always null terminated */
- (void) strlcpy(kp->mst_io.value.c, ip->bi_kstat_io.mstio,
- KSTAT_DATA_CHAR_LEN);
- (void) strlcpy(kp->shd_io.value.c, ip->bi_kstat_io.shdio,
- KSTAT_DATA_CHAR_LEN);
- (void) strlcpy(kp->bmp_io.value.c, ip->bi_kstat_io.bmpio,
- KSTAT_DATA_CHAR_LEN);
-
- return (0);
-}
-
-/*
- * _ii_config
- * Configure an II device pair
- *
- * Calling/Exit State:
- * Returns 0 if the pairing was configured, otherwise an
- * error code. The ioctl data stucture is copied out to the user
- * and contains any additional error information, and the master
- * and shadow volume names if not supplied by the user.
- *
- * Description:
- * Reads the user configuration structure and attempts
- * to establish an II pairing. The snapshot of the master
- * device is established at this point in time.
- */
-
-int
-_ii_config(intptr_t arg, int ilp32, int *rvp, int iflags)
-{
- dsw_config_t uconf;
- dsw_config32_t *uconf32;
- _ii_info_t *ip, *hip, **ipp;
- int rc;
- int type;
- int nshadows;
- int add_to_mst_top;
- int import;
- int existing;
- int resized;
- nsc_size_t mst_size, shd_size, bmp_size;
- nsc_off_t shdfba;
- nsc_off_t copyfba;
- int keylen, keyoffset;
- ii_header_t *bm_header;
- nsc_buf_t *tmp;
- spcs_s_info_t kstatus;
- spcs_s_info32_t ustatus32;
- int rtype;
- uint_t hints;
-
- /* Import is a once only operation like an enable */
- ASSERT((iflags&(II_EXISTING|II_IMPORT)) != (II_EXISTING|II_IMPORT));
- existing = (iflags&II_EXISTING) != 0;
- import = (iflags&II_IMPORT) != 0;
- *rvp = 0;
- if (ilp32) {
- uconf32 = kmem_zalloc(sizeof (dsw_config32_t), KM_SLEEP);
- if (uconf32 == NULL) {
- return (ENOMEM);
- }
- if (copyin((void *)arg, uconf32, sizeof (*uconf32)) < 0)
- return (EFAULT);
- II_TAIL_COPY(uconf, (*uconf32), master_vol, dsw_config_t);
- uconf.status = (spcs_s_info_t)uconf32->status;
- ustatus32 = uconf32->status;
- kmem_free(uconf32, sizeof (dsw_config32_t));
- } else if (copyin((void *)arg, &uconf, sizeof (uconf)) < 0)
- return (EFAULT);
-
- DTRACE_PROBE3(_ii_config_info, char *, uconf.master_vol,
- char *, uconf.shadow_vol, char *, uconf.bitmap_vol);
-
- kstatus = spcs_s_kcreate();
- if (kstatus == NULL)
- return (ENOMEM);
-
- if (_ii_shutting_down)
- return (spcs_s_ocopyoutf(&kstatus, uconf.status,
- DSW_ESHUTDOWN));
-
- if (uconf.bitmap_vol[0] == 0)
- return (spcs_s_ocopyoutf(&kstatus, uconf.status, DSW_EEMPTY));
-
- mutex_enter(&_ii_config_mutex);
- ip = nsc_kmem_zalloc(sizeof (*ip), KM_SLEEP, _ii_local_mem);
- if (!ip) {
- mutex_exit(&_ii_config_mutex);
- return (spcs_s_ocopyoutf(&kstatus, uconf.status, ENOMEM));
- }
- ip->bi_mstdev = nsc_kmem_zalloc(sizeof (*ip->bi_mstdev), KM_SLEEP,
- _ii_local_mem);
- ip->bi_mstrdev = nsc_kmem_zalloc(sizeof (*ip->bi_mstdev), KM_SLEEP,
- _ii_local_mem);
- if (ip->bi_mstdev == NULL || ip->bi_mstrdev == NULL) {
- mutex_exit(&_ii_config_mutex);
- _ii_info_free(ip);
- return (spcs_s_ocopyoutf(&kstatus, uconf.status, ENOMEM));
- }
-
- ip->bi_disabled = 1; /* mark as disabled until we are ready to go */
- mutex_init(&ip->bi_mutex, NULL, MUTEX_DRIVER, NULL);
- mutex_init(&ip->bi_bmpmutex, NULL, MUTEX_DRIVER, NULL);
- mutex_init(&ip->bi_rsrvmutex, NULL, MUTEX_DRIVER, NULL);
- mutex_init(&ip->bi_rlsemutex, NULL, MUTEX_DRIVER, NULL);
- mutex_init(&ip->bi_chksmutex, NULL, MUTEX_DRIVER, NULL);
- cv_init(&ip->bi_copydonecv, NULL, CV_DRIVER, NULL);
- cv_init(&ip->bi_reservecv, NULL, CV_DRIVER, NULL);
- cv_init(&ip->bi_releasecv, NULL, CV_DRIVER, NULL);
- cv_init(&ip->bi_ioctlcv, NULL, CV_DRIVER, NULL);
- cv_init(&ip->bi_closingcv, NULL, CV_DRIVER, NULL);
- cv_init(&ip->bi_busycv, NULL, CV_DRIVER, NULL);
- rw_init(&ip->bi_busyrw, NULL, RW_DRIVER, NULL);
- rw_init(&ip->bi_linkrw, NULL, RW_DRIVER, NULL);
- (void) strncpy(ip->bi_keyname, uconf.shadow_vol, DSW_NAMELEN);
- ip->bi_keyname[DSW_NAMELEN-1] = '\0';
- ip->bi_throttle_unit = ii_throttle_unit;
- ip->bi_throttle_delay = ii_throttle_delay;
-
- /* First check the list to see if uconf.bitmap_vol's already there */
-
- if (ii_volume(uconf.bitmap_vol, 0) != NONE) {
- DTRACE_PROBE(_ii_config_bmp_found);
- mutex_exit(&_ii_config_mutex);
- _ii_info_free(ip);
- return (spcs_s_ocopyoutf(&kstatus, uconf.status, DSW_EINUSE));
- }
-
- ip->bi_bmpfd = nsc_open(uconf.bitmap_vol,
- NSC_IIR_ID|NSC_FILE|NSC_RDWR, NULL, (blind_t)&(ip->bi_bmpdev), &rc);
- if (!ip->bi_bmpfd)
- ip->bi_bmpfd = nsc_open(uconf.bitmap_vol,
- NSC_IIR_ID|NSC_CACHE|NSC_DEVICE|NSC_RDWR, NULL,
- (blind_t)&(ip->bi_bmpdev), &rc);
- if (!ip->bi_bmpfd && !existing) {
- mutex_exit(&_ii_config_mutex);
- _ii_info_free(ip);
- spcs_s_add(kstatus, rc);
- DTRACE_PROBE(_ii_config_no_bmp);
- return (spcs_s_ocopyoutf(&kstatus, uconf.status, DSW_EOPEN));
- }
-
- if (import) {
- uconf.flag = DSW_GOLDEN;
- II_FLAG_SETX(DSW_SHDIMPORT|DSW_GOLDEN, ip);
- }
-
- if (existing) {
-
- DTRACE_PROBE(_ii_config_existing);
- /*
- * ii_config is used by enable, import and resume (existing)
- * If not importing or resuming, then this must be enable.
- * Indicate this fact for SNMP use.
- */
-
- if (!ip->bi_bmpfd) {
- /*
- * Couldn't read bitmap, mark master and shadow as
- * unusable.
- */
- II_FLAG_ASSIGN(DSW_BMPOFFLINE|DSW_MSTOFFLINE|
- DSW_SHDOFFLINE, ip);
-
- /*
- * Set cluster tag for this element so it can
- * be suspended later
- */
- (void) II_LINK_CLUSTER(ip, uconf.cluster_tag);
-
- /* need to check on master, might be shared */
- goto header_checked;
- }
- /* check the header */
- (void) _ii_rsrv_devs(ip, BMP, II_INTERNAL);
-
- /* get first block of bit map */
- mutex_enter(&ip->bi_mutex);
- bm_header = _ii_bm_header_get(ip, &tmp);
- mutex_exit(&ip->bi_mutex);
- if (bm_header == NULL) {
- if (ii_debug > 0)
- cmn_err(CE_WARN,
- "!ii: _ii_bm_header_get returned NULL");
- mutex_exit(&_ii_config_mutex);
- _ii_info_free(ip);
- return (spcs_s_ocopyoutf(&kstatus, uconf.status,
- DSW_EHDRBMP));
- }
-
- if (bm_header->ii_magic != DSW_DIRTY &&
- bm_header->ii_magic != DSW_CLEAN) {
- mutex_exit(&_ii_config_mutex);
- _ii_bm_header_free(bm_header, ip, tmp);
- _ii_info_free(ip);
- return (spcs_s_ocopyoutf(&kstatus, uconf.status,
- DSW_EINVALBMP));
- }
-
- II_FLAG_ASSIGN(bm_header->ii_state, ip);
- /* Restore copy throttle parameters, if header version is 3 */
- if (bm_header->ii_version >= 3) { /* II_HEADER_VERSION */
- ip->bi_throttle_delay = bm_header->ii_throttle_delay;
- ip->bi_throttle_unit = bm_header->ii_throttle_unit;
- }
-
- /* Restore cluster & group names, if header version is 4 */
- if (bm_header->ii_version >= 4) {
- /* cluster */
- if (*bm_header->clstr_name) {
- (void) strncpy(uconf.cluster_tag,
- bm_header->clstr_name, DSW_NAMELEN);
- (void) II_LINK_CLUSTER(ip, uconf.cluster_tag);
- }
-
- /* group */
- if (*bm_header->group_name) {
- (void) strncpy(uconf.group_name,
- bm_header->group_name, DSW_NAMELEN);
- (void) II_LINK_GROUP(ip, uconf.group_name);
- }
- }
- /* restore latest modification time, if header version >= 5 */
- if (bm_header->ii_version >= 5) {
- ip->bi_mtime = bm_header->ii_mtime;
- }
-
- /* Fetch master and shadow names from bitmap header */
- if (uconf.master_vol[0] == 0)
- (void) strncpy(uconf.master_vol, bm_header->master_vol,
- DSW_NAMELEN);
- if (uconf.shadow_vol[0] == 0)
- (void) strncpy(uconf.shadow_vol, bm_header->shadow_vol,
- DSW_NAMELEN);
-
- /* return the fetched names to the user */
- if (ilp32) {
- uconf32 = kmem_zalloc(sizeof (dsw_config32_t),
- KM_SLEEP);
- if (uconf32 == NULL) {
- mutex_exit(&_ii_config_mutex);
- _ii_bm_header_free(bm_header, ip, tmp);
- _ii_rlse_devs(ip, BMP);
- _ii_info_free(ip);
- return (ENOMEM);
- }
- uconf32->status = ustatus32;
- II_TAIL_COPY((*uconf32), uconf, master_vol,
- dsw_config32_t);
- rc = copyout(uconf32, (void *)arg, sizeof (*uconf32));
- kmem_free(uconf32, sizeof (dsw_config32_t));
- } else {
- rc = copyout(&uconf, (void *)arg, sizeof (uconf));
- }
- if (rc) {
- mutex_exit(&_ii_config_mutex);
- _ii_bm_header_free(bm_header, ip, tmp);
- _ii_rlse_devs(ip, BMP);
- _ii_info_free(ip);
- return (EFAULT);
- }
-
- if (strncmp(bm_header->bitmap_vol, uconf.bitmap_vol,
- DSW_NAMELEN) || ((!(ip->bi_flags&DSW_SHDIMPORT)) &&
- strncmp(bm_header->master_vol, uconf.master_vol,
- DSW_NAMELEN)) || strncmp(bm_header->shadow_vol,
- uconf.shadow_vol, DSW_NAMELEN)) {
- mutex_exit(&_ii_config_mutex);
- _ii_bm_header_free(bm_header, ip, tmp);
- _ii_rlse_devs(ip, BMP);
- _ii_info_free(ip);
- return (spcs_s_ocopyoutf(&kstatus, uconf.status,
- DSW_EMISMATCH));
- }
- shdfba = bm_header->ii_shdfba;
- copyfba = bm_header->ii_copyfba;
- if ((ip->bi_flags)&DSW_TREEMAP) {
- if (ii_debug > 0)
- cmn_err(CE_NOTE,
- "!II: Resuming short shadow volume");
-
- ip->bi_mstchks = bm_header->ii_mstchks;
- ip->bi_shdchks = bm_header->ii_shdchks;
- ip->bi_shdchkused = bm_header->ii_shdchkused;
- ip->bi_shdfchk = bm_header->ii_shdfchk;
-
- if (bm_header->overflow_vol[0] != 0)
- if ((rc = ii_overflow_attach(ip,
- bm_header->overflow_vol, 0)) != 0) {
- mutex_exit(&_ii_config_mutex);
- _ii_bm_header_free(bm_header, ip, tmp);
- _ii_rlse_devs(ip, BMP);
- _ii_info_free(ip);
- return (spcs_s_ocopyoutf(&kstatus,
- uconf.status, rc));
- }
- }
- _ii_bm_header_free(bm_header, ip, tmp);
- _ii_rlse_devs(ip, BMP);
- }
-header_checked:
-
- if (ip->bi_flags&DSW_SHDIMPORT)
- (void) strcpy(uconf.master_vol, "<imported shadow>");
- if (!uconf.master_vol[0] || !uconf.shadow_vol[0]) {
- mutex_exit(&_ii_config_mutex);
- _ii_info_free(ip);
- return (spcs_s_ocopyoutf(&kstatus, uconf.status, DSW_EEMPTY));
- }
-
- /* check that no volume has been given twice */
- if (strncmp(uconf.master_vol, uconf.shadow_vol, DSW_NAMELEN) == 0) {
- mutex_exit(&_ii_config_mutex);
- _ii_info_free(ip);
- return (spcs_s_ocopyoutf(&kstatus, uconf.status, DSW_EOPEN));
- }
-
- if (strncmp(uconf.master_vol, uconf.bitmap_vol, DSW_NAMELEN) == 0) {
- mutex_exit(&_ii_config_mutex);
- _ii_info_free(ip);
- return (spcs_s_ocopyoutf(&kstatus, uconf.status, DSW_EOPEN));
- }
-
- if (strncmp(uconf.bitmap_vol, uconf.shadow_vol, DSW_NAMELEN) == 0) {
- mutex_exit(&_ii_config_mutex);
- _ii_info_free(ip);
- return (spcs_s_ocopyoutf(&kstatus, uconf.status, DSW_EOPEN));
- }
-
- /* check that master is not already a bitmap, shadow or overflow */
- type = ii_volume(uconf.master_vol, 1);
- if (type != NONE && type != MST) {
- mutex_exit(&_ii_config_mutex);
- _ii_info_free(ip);
- return (spcs_s_ocopyoutf(&kstatus, uconf.status, DSW_EINUSE));
- }
-
- /* check that shadow is not used as anything else */
- type = ii_volume(uconf.shadow_vol, 1);
- if (type != NONE && type != SHD) {
- mutex_exit(&_ii_config_mutex);
- _ii_info_free(ip);
- return (spcs_s_ocopyoutf(&kstatus, uconf.status, DSW_EINUSE));
- }
-
- /* Setup the table bitmap operations table */
- switch (ii_bitmap) {
- case II_KMEM:
- if (ii_debug > 0)
- cmn_err(CE_NOTE, "!ii: using volatile bitmaps");
- ip->bi_bitmap_ops = &kmem_buf_bmp;
- break;
- case II_FWC:
- hints = 0;
- (void) nsc_node_hints(&hints);
- if ((hints & NSC_FORCED_WRTHRU) == 0)
- ip->bi_bitmap_ops = &kmem_buf_bmp;
- else
- ip->bi_bitmap_ops = &alloc_buf_bmp;
- if (ii_debug > 0) {
- cmn_err(CE_NOTE, "!ii: chosen to use %s bitmaps",
- ip->bi_bitmap_ops == &kmem_buf_bmp ?
- "volatile" : "persistent");
- }
- break;
- case II_WTHRU:
- default:
- if (ii_debug > 0)
- cmn_err(CE_NOTE, "!ii: using persistent bitmaps");
- ip->bi_bitmap_ops = &alloc_buf_bmp;
- break;
- }
-
- /*
- * If we found aother shadow volume with the same name,
- * If this is an resume operation,
- * If this shadow is in the exported state
- * then try an on the fly join instead
- */
- for (hip = _ii_info_top; hip; hip = hip->bi_next)
- if (strcmp(uconf.shadow_vol, hip->bi_keyname) == 0)
- break;
- if ((hip) && (type == SHD) && existing &&
- (ip->bi_flags & DSW_SHDEXPORT)) {
-
- /*
- * Stop any copy in progress
- */
- while (_ii_stopcopy(hip) == EINTR)
- ;
-
- /*
- * Start the imported shadow teardown
- */
- mutex_enter(&hip->bi_mutex);
-
- /* disable accesss to imported shadow */
- hip->bi_disabled = 1;
-
- /* Wait for any I/O's to complete */
- while (hip->bi_ioctl) {
- hip->bi_state |= DSW_IOCTL;
- cv_wait(&hip->bi_ioctlcv, &hip->bi_mutex);
- }
- mutex_exit(&hip->bi_mutex);
-
- /* this rw_enter forces us to drain all active IO */
- rw_enter(&hip->bi_linkrw, RW_WRITER);
- rw_exit(&hip->bi_linkrw);
-
- /* remove ip from _ii_info_top linked list */
- mutex_enter(&_ii_info_mutex);
- for (ipp = &_ii_info_top; *ipp; ipp = &((*ipp)->bi_next)) {
- if (hip == *ipp) {
- *ipp = hip->bi_next;
- break;
- }
- }
- if (hip->bi_kstat) {
- kstat_delete(hip->bi_kstat);
- hip->bi_kstat = NULL;
- }
- mutex_exit(&_ii_info_mutex);
-
- /* Gain access to both bitmap volumes */
- rtype = BMP;
- if (((rc = _ii_rsrv_devs(hip, rtype, II_INTERNAL)) != 0) ||
- ((rc = _ii_rsrv_devs(ip, rtype, II_INTERNAL)) != 0)) {
- mutex_exit(&_ii_config_mutex);
- _ii_info_free(ip);
- return (spcs_s_ocopyoutf(&kstatus, uconf.status, rc));
- }
-
- /* Merge imported bitmap */
- rc = II_JOIN_BMP(ip, hip);
-
- /* Release access to bitmap volume */
- _ii_rlse_devs(hip, rtype);
- ii_sibling_free(hip);
-
- /* Clear the fact that we are exported */
- mutex_enter(&ip->bi_mutex);
- II_FLAG_CLR(DSW_SHDEXPORT, ip);
-
- /* Release resources */
- mutex_exit(&ip->bi_mutex);
- _ii_rlse_devs(ip, BMP);
-
- } else if (type != NONE) {
- mutex_exit(&_ii_config_mutex);
- _ii_info_free(ip);
- return (spcs_s_ocopyoutf(&kstatus, uconf.status, DSW_EINUSE));
- }
-
- /*
- * Handle non-exported shadow
- */
- if ((ip->bi_flags & DSW_SHDEXPORT) == 0) {
- if ((rc = ii_open_shadow(ip, uconf.shadow_vol)) != 0) {
- mutex_exit(&_ii_config_mutex);
- _ii_info_free(ip);
- spcs_s_add(kstatus, rc);
- return (spcs_s_ocopyoutf(&kstatus, uconf.status,
- DSW_EOPEN));
- }
- }
-
- /*
- * allocate _ii_concopy_sema and set to a value that won't allow
- * all cache to be allocated by copy loops.
- */
-
- if (_ii_concopy_init == 0 && ip->bi_bmpfd != NULL) {
- int asize = 0, wsize;
- nsc_size_t cfbas, maxfbas;
-
- (void) nsc_cache_sizes(&asize, &wsize);
-
- if (asize > 0) {
- cfbas = FBA_NUM(asize);
- (void) _ii_rsrv_devs(ip, BMP, II_INTERNAL);
- rc = nsc_maxfbas(ip->bi_bmpfd, 0, &maxfbas);
- _ii_rlse_devs(ip, BMP);
- if (!II_SUCCESS(rc))
- maxfbas = 1024; /* i.e. _SD_MAX_FBAS */
- ii_nconcopy = cfbas / (maxfbas * 2) / 3;
- }
- if (ii_nconcopy < 2)
- ii_nconcopy = 2;
- ASSERT(ii_nconcopy > 0);
- sema_init(&_ii_concopy_sema, ii_nconcopy, NULL,
- SEMA_DRIVER, NULL);
- _ii_concopy_init = 1;
- }
-
- /* check for shared master volume */
- for (hip = _ii_mst_top; hip; hip = hip->bi_nextmst)
- if (strcmp(uconf.master_vol, ii_pathname(hip->bi_mstfd)) == 0)
- break;
- add_to_mst_top = (hip == NULL);
- if (!hip)
- for (hip = _ii_info_top; hip; hip = hip->bi_next)
- if (strcmp(uconf.master_vol,
- ii_pathname(hip->bi_mstfd)) == 0)
- break;
- nshadows = (hip != NULL);
-
- /* Check if master is offline */
- if (hip) {
- if (hip->bi_flags & DSW_MSTOFFLINE) {
- mutex_exit(&_ii_config_mutex);
- _ii_info_free(ip);
- return (spcs_s_ocopyoutf(&kstatus, uconf.status,
- DSW_EOFFLINE));
- }
- }
-
- if (!nshadows && (ip->bi_flags&DSW_SHDIMPORT) == 0) {
- ip->bi_mstfd = nsc_open(uconf.master_vol,
- NSC_IIR_ID|NSC_DEVICE|NSC_RDWR, _ii_fd_def,
- (blind_t)(ip->bi_mstdev), &rc);
- if (!ip->bi_mstfd) {
- mutex_exit(&_ii_config_mutex);
- _ii_info_free(ip);
- spcs_s_add(kstatus, rc);
- return (spcs_s_ocopyoutf(&kstatus, uconf.status,
- DSW_EOPEN));
- }
-
- ip->bi_mstrfd = nsc_open(uconf.master_vol,
- NSC_IIR_ID|NSC_DEVICE|NSC_RDWR, _ii_fd_def,
- (blind_t)(ip->bi_mstrdev), &rc);
- if (!ip->bi_mstrfd) {
- mutex_exit(&_ii_config_mutex);
- _ii_info_free(ip);
- spcs_s_add(kstatus, rc);
- return (spcs_s_ocopyoutf(&kstatus, uconf.status,
- DSW_EOPEN));
- }
- }
-
- ip->bi_head = ip;
- ip->bi_master = ip;
-
- mutex_enter(&_ii_info_mutex);
- ip->bi_next = _ii_info_top;
- _ii_info_top = ip;
- if (nshadows) {
- /* link new shadow group together with others sharing master */
- if (ii_debug > 0)
- cmn_err(CE_NOTE,
- "!II: shadow %s shares master %s with other shadow"
- " groups", uconf.shadow_vol, uconf.master_vol);
- hip = hip->bi_head;
- nsc_kmem_free(ip->bi_mstrdev, sizeof (*ip->bi_mstrdev));
- nsc_kmem_free(ip->bi_mstdev, sizeof (*ip->bi_mstdev));
- ip->bi_mstrdev = hip->bi_mstrdev;
- ip->bi_mstdev = hip->bi_mstdev;
- ip->bi_head = hip;
- ip->bi_sibling = hip->bi_sibling;
- if (add_to_mst_top) {
- hip->bi_nextmst = _ii_mst_top;
- _ii_mst_top = hip;
- }
- hip->bi_sibling = ip;
- ip->bi_master = ip->bi_head->bi_master;
- }
- mutex_exit(&_ii_info_mutex);
- mutex_exit(&_ii_config_mutex);
-
- keylen = strlen(ip->bi_keyname);
- if (keylen > KSTAT_STRLEN - 1) {
- keyoffset = keylen + 1 - KSTAT_STRLEN;
- } else {
- keyoffset = 0;
- }
- ip->bi_kstat = kstat_create("ii", _ii_instance++,
- &ip->bi_keyname[ keyoffset ], "iiset", KSTAT_TYPE_NAMED,
- sizeof (ii_kstat_set) / sizeof (kstat_named_t),
- KSTAT_FLAG_VIRTUAL);
- if (ip->bi_kstat) {
- ip->bi_kstat->ks_data = &ii_kstat_set;
- ip->bi_kstat->ks_update = ii_set_stats_update;
- ip->bi_kstat->ks_private = ip;
- kstat_install(ip->bi_kstat);
- } else {
- cmn_err(CE_WARN, "!Unable to create set-specific kstats");
- }
-
-#ifndef DISABLE_KSTATS
- /* create kstats information */
- mutex_init(&ip->bi_kstat_io.statmutex, NULL, MUTEX_DRIVER, NULL);
- if (ip == ip->bi_master) {
- ip->bi_kstat_io.master = _ii_kstat_create(ip, "master");
- } else {
- ip->bi_kstat_io.master = ip->bi_master->bi_kstat_io.master;
- (void) strlcpy(ip->bi_kstat_io.mstio,
- ip->bi_master->bi_kstat_io.mstio, KSTAT_DATA_CHAR_LEN);
- }
- ip->bi_kstat_io.shadow = _ii_kstat_create(ip, "shadow");
- ip->bi_kstat_io.bitmap = _ii_kstat_create(ip, "bitmap");
-#endif
-
- (void) _ii_reserve_begin(ip);
- rtype = MSTR|SHDR|BMP;
- if ((rc = _ii_rsrv_devs(ip, rtype, II_INTERNAL)) != 0) {
- spcs_s_add(kstatus, rc);
- rc = DSW_ERSRVFAIL;
- goto fail;
- }
-
- if (ip->bi_flags&DSW_SHDIMPORT) {
- rc = 0; /* no master for imported volumes */
- mst_size = 0;
- } else
- rc = nsc_partsize(MSTFD(ip), &mst_size);
- if (rc == 0 && (ip->bi_flags&DSW_SHDEXPORT) == 0)
- rc = nsc_partsize(SHDFD(ip), &shd_size);
- if (!ip->bi_bmpfd)
- rc = EINVAL;
- if (rc == 0)
- rc = nsc_partsize(ip->bi_bmpfd, &bmp_size);
-
- if (ip->bi_flags&DSW_SHDIMPORT)
- ip->bi_size = shd_size;
- else
- ip->bi_size = mst_size;
-
- if ((((ip->bi_flags&DSW_SHDIMPORT) != DSW_SHDIMPORT) &&
- (mst_size < 1)) ||
- (((ip->bi_flags&DSW_SHDEXPORT) != DSW_SHDEXPORT) &&
- (shd_size < 1)) ||
- ((rc == 0) && (bmp_size < 1))) {
- /* could be really zero, or could be > 1 TB; fail the enable */
- rc = EINVAL;
- }
-
- if (rc != 0) { /* rc set means an nsc_partsize() failed */
- /*
- * If existing group, mark bitmap as offline and set
- * bmp_size to "right size".
- */
- if (existing) {
- bmp_size = 2 * DSW_BM_FBA_LEN(mst_size) +
- DSW_SHD_BM_OFFSET;
- goto no_more_bmp_tests;
- }
- spcs_s_add(kstatus, rc);
- rc = DSW_EPARTSIZE;
- _ii_rlse_devs(ip, rtype);
- _ii_reserve_end(ip);
- goto fail;
- }
-
- if (ip->bi_flags&DSW_SHDIMPORT)
- mst_size = shd_size;
- if (ip->bi_flags&DSW_SHDEXPORT)
- shd_size = mst_size;
- /*
- * Check with RDC if the master & shadow sizes are different.
- * Once II is enabled, the shadow size will be made to appear
- * the same as the master, and this will panic RDC if we're
- * changing sizes on it.
- */
- resized = (shd_size != mst_size);
- if (resized && ii_need_same_size(ip)) {
- cmn_err(CE_WARN, "!Cannot enable II set: would change volume "
- "size on RDC");
- rc = DSW_EOPACKAGE;
- _ii_rlse_devs(ip, rtype);
- _ii_reserve_end(ip);
- goto fail;
- }
- if (bmp_size < 2 * DSW_BM_FBA_LEN(mst_size) + DSW_SHD_BM_OFFSET) {
- /* bitmap volume too small */
- if (ii_debug > 0)
- cmn_err(CE_NOTE,
- "!ii: invalid sizes: bmp %" NSC_SZFMT " mst %"
- NSC_SZFMT " %" NSC_SZFMT "",
- bmp_size, mst_size, DSW_BM_FBA_LEN(mst_size));
- rc = DSW_EBMPSIZE;
- _ii_rlse_devs(ip, rtype);
- _ii_reserve_end(ip);
- goto fail;
- }
- if ((shd_size < mst_size) && (uconf.flag&DSW_GOLDEN) != 0) {
- /* shadow volume too small */
- if (ii_debug > 0)
- cmn_err(CE_NOTE, "!shd size too small (%" NSC_SZFMT
- ") for independent set's master (%" NSC_SZFMT ")",
- shd_size, mst_size);
- rc = DSW_ESHDSIZE;
- _ii_rlse_devs(ip, rtype);
- _ii_reserve_end(ip);
- goto fail;
- }
-
- ip->bi_busy = kmem_zalloc(1 + (ip->bi_size / (DSW_SIZE * DSW_BITS)),
- KM_SLEEP);
- if (!ip->bi_busy) {
- rc = ENOMEM;
- _ii_rlse_devs(ip, rtype);
- _ii_reserve_end(ip);
- goto fail;
- }
-
- if (existing == 0) {
-
- DTRACE_PROBE(_ii_config);
-
- /* first time this shadow has been set up */
- mutex_enter(&ip->bi_mutex);
- bm_header = _ii_bm_header_get(ip, &tmp);
- mutex_exit(&ip->bi_mutex);
- if (bm_header == NULL) {
- if (ii_debug > 0)
- cmn_err(CE_WARN,
- "!ii: _ii_bm_header_get returned NULL");
- rc = DSW_EHDRBMP;
- _ii_rlse_devs(ip, rtype);
- _ii_reserve_end(ip);
- goto fail;
- }
- bzero(bm_header, sizeof (*bm_header));
- /* copy pathnames into it */
- (void) strncpy(bm_header->master_vol, uconf.master_vol,
- DSW_NAMELEN);
- (void) strncpy(bm_header->shadow_vol, uconf.shadow_vol,
- DSW_NAMELEN);
- (void) strncpy(bm_header->bitmap_vol, uconf.bitmap_vol,
- DSW_NAMELEN);
- (void) strncpy(bm_header->clstr_name, uconf.cluster_tag,
- DSW_NAMELEN);
- (void) strncpy(bm_header->group_name, uconf.group_name,
- DSW_NAMELEN);
-
- if (uconf.cluster_tag[0] != 0)
- (void) II_LINK_CLUSTER(ip, uconf.cluster_tag);
-
- if (uconf.group_name[0] != 0)
- (void) II_LINK_GROUP(ip, uconf.group_name);
-
-
- bm_header->ii_state = (uconf.flag & DSW_GOLDEN);
- II_FLAG_ASSIGN(bm_header->ii_state, ip);
-
- if (import) {
- II_FLAG_SETX(DSW_SHDIMPORT, ip);
- bm_header->ii_state |= DSW_SHDIMPORT;
- }
- if (resized) {
- II_FLAG_SETX(DSW_RESIZED, ip);
- bm_header->ii_state |= DSW_RESIZED;
- }
- bm_header->ii_type = (uconf.flag & DSW_GOLDEN) ?
- DSW_GOLDEN_TYPE : DSW_QUICK_TYPE;
- bm_header->ii_magic = DSW_DIRTY;
- bm_header->ii_version = II_HEADER_VERSION;
- bm_header->ii_shdfba = DSW_SHD_BM_OFFSET;
- bm_header->ii_copyfba = DSW_COPY_BM_OFFSET;
- bm_header->ii_throttle_delay = ip->bi_throttle_delay;
- bm_header->ii_throttle_unit = ip->bi_throttle_unit;
- ip->bi_shdfba = bm_header->ii_shdfba;
- ip->bi_copyfba = bm_header->ii_copyfba;
- ip->bi_mtime = ddi_get_time();
-
- /* write it to disk */
- mutex_enter(&ip->bi_mutex);
- rc = _ii_bm_header_put(bm_header, ip, tmp);
- mutex_exit(&ip->bi_mutex);
- if (!II_SUCCESS(rc)) {
- spcs_s_add(kstatus, rc);
- rc = DSW_EHDRBMP;
- _ii_rlse_devs(ip, rtype);
- _ii_reserve_end(ip);
- goto fail;
- }
- if ((shd_size < mst_size) && (uconf.flag & DSW_GOLDEN) == 0) {
- /*
- * shadow volume smaller than master, must use a dependent
- * copy with a bitmap file stored mapping for chunk locations.
- */
- /* number of chunks in shadow volume */
- nsc_size_t shd_chunks;
- nsc_size_t bmp_chunks;
- nsc_size_t tmp_chunks;
-
- if (ii_debug > 1)
- cmn_err(CE_NOTE, "!ii: using tree index on %s",
- uconf.master_vol);
- shd_chunks = shd_size / DSW_SIZE;
- /* do not add in partial chunk at end */
-
- ip->bi_mstchks = mst_size / DSW_SIZE;
- if (mst_size % DSW_SIZE != 0)
- ip->bi_mstchks++;
- bmp_chunks = ii_btsize(bmp_size - ip->bi_copyfba -
- DSW_BM_FBA_LEN(ip->bi_size));
- tmp_chunks = ip->bi_copyfba +
- DSW_BM_FBA_LEN(ip->bi_size);
- if (bmp_chunks < (nsc_size_t)ip->bi_mstchks) {
- if (ii_debug > -1) {
- cmn_err(CE_NOTE, "!ii: bitmap vol too"
- "small: %" NSC_SZFMT " vs. %"
- NSC_SZFMT, bmp_size,
- tmp_chunks);
- }
- spcs_s_add(kstatus, rc);
- rc = DSW_EHDRBMP;
- _ii_rlse_devs(ip, rtype);
- _ii_reserve_end(ip);
- goto fail;
- }
- mutex_enter(&ip->bi_mutex);
- II_FLAG_SET(DSW_TREEMAP, ip);
- mutex_exit(&ip->bi_mutex);
-
- /* following values are written to header by ii_tinit */
-#if (defined(NSC_MULTI_TERABYTE) && !defined(II_MULTIMULTI_TERABYTE))
- ASSERT(shd_chunks <= INT32_MAX);
- ASSERT(mst_size / DSW_SIZE <= INT32_MAX);
-#endif
- ip->bi_mstchks = mst_size / DSW_SIZE;
- if (mst_size % DSW_SIZE != 0)
- ip->bi_mstchks++;
-#ifdef II_MULTIMULTI_TERABYTE
- ip->bi_shdchks = shd_chunks;
-#else
- /* still have 31 bit chunkid's */
- ip->bi_shdchks = (chunkid_t)shd_chunks;
-#endif
- ip->bi_shdchkused = 0;
- rc = ii_tinit(ip);
- } else {
- ip->bi_shdchks = shd_size / DSW_SIZE;
- ip->bi_shdchkused = 0;
- }
- if (rc == 0)
- rc = II_LOAD_BMP(ip, 1);
- if (rc == 0)
- rc = II_ZEROBM(ip);
- if (rc == 0)
- rc = II_COPYBM(ip); /* also clear copy bitmap */
- if (rc == 0 && (uconf.flag & DSW_GOLDEN) && !import)
- rc = ii_fill_copy_bmp(ip);
- if (rc) {
- spcs_s_add(kstatus, rc);
- rc = DSW_EHDRBMP;
- _ii_rlse_devs(ip, rtype);
- goto fail;
- }
- /* check that changing shadow won't upset RDC */
- if (ii_update_denied(ip, kstatus, 0, 1)) {
- rc = DSW_EOPACKAGE;
- _ii_rlse_devs(ip, rtype);
- _ii_reserve_end(ip);
- goto fail;
- }
- ip->bi_disabled = 0; /* all okay and ready, we can go now */
- _ii_rlse_devs(ip, rtype);
- /* no _ii_reserve_end() here - we must register first */
- ip->bi_bmp_tok = _ii_register_path(ii_pathname(ip->bi_bmpfd),
- NSC_CACHE|NSC_DEVICE, _ii_io);
- if (!nshadows)
- ii_register_mst(ip);
- ii_register_shd(ip);
-
- if (!ii_register_ok(ip)) {
- ip->bi_disabled = 1; /* argh */
- rc = DSW_EREGISTER;
- goto fail;
- }
- /* no _ii_reserve_begin() here -- we're still in process */
- (void) _ii_rsrv_devs(ip, rtype, II_INTERNAL);
-
- if (ii_debug > 0)
- cmn_err(CE_NOTE, "!ii: config: master %s shadow %s",
- uconf.master_vol, uconf.shadow_vol);
- rc = 0;
- if ((uconf.flag & DSW_GOLDEN) && !import) {
- mutex_enter(&ip->bi_mutex);
- II_FLAG_SET(DSW_COPYINGM | DSW_COPYINGP, ip);
- ip->bi_ioctl++; /* we are effectively in an ioctl */
- mutex_exit(&ip->bi_mutex);
- rc = _ii_copyvol(ip, 0, rtype, kstatus, 1);
- }
- _ii_rlse_devs(ip, rtype);
- _ii_reserve_end(ip);
-
- ++iigkstat.num_sets.value.ul;
-
- return (spcs_s_ocopyoutf(&kstatus, uconf.status, rc));
- }
-
- ip->bi_shdchks = shd_size / DSW_SIZE;
- ip->bi_shdfba = shdfba;
- ip->bi_copyfba = copyfba;
- rc = II_LOAD_BMP(ip, 0); /* reload saved bitmap */
- mutex_enter(&ip->bi_mutex);
- if (rc == 0)
- bm_header = _ii_bm_header_get(ip, &tmp);
- mutex_exit(&ip->bi_mutex);
- if (rc || bm_header == NULL) {
- if (existing) {
- goto no_more_bmp_tests;
- }
- rc = DSW_EHDRBMP;
- goto fail;
- }
-
- /*
- * If the header is dirty and it wasn't kept on persistent storage
- * then the bitmaps must be assumed to be bad.
- */
- if (bm_header->ii_magic == DSW_DIRTY &&
- ip->bi_bitmap_ops != &alloc_buf_bmp) {
- type = bm_header->ii_type;
- _ii_bm_header_free(bm_header, ip, tmp);
- if (type == DSW_GOLDEN_TYPE) {
- if ((ip->bi_flags & DSW_COPYINGM) != 0)
- _ii_error(ip, DSW_SHDOFFLINE);
- else if ((ip->bi_flags & DSW_COPYINGS) != 0)
- _ii_error(ip, DSW_MSTOFFLINE);
- else {
- /* No copying, so they're just different */
- rc = ii_fill_copy_bmp(ip);
- if (rc) {
- spcs_s_add(kstatus, rc);
- rc = DSW_EHDRBMP;
- goto fail;
- }
- }
- } else
- _ii_error(ip, DSW_SHDOFFLINE);
-
- mutex_enter(&ip->bi_mutex);
- bm_header = _ii_bm_header_get(ip, &tmp);
- mutex_exit(&ip->bi_mutex);
- if (bm_header == NULL) {
- rc = DSW_EHDRBMP;
- goto fail;
- }
- }
-
- bm_header->ii_magic = DSW_DIRTY;
- mutex_enter(&ip->bi_mutex);
- rc = _ii_bm_header_put(bm_header, ip, tmp);
- mutex_exit(&ip->bi_mutex);
- if (!II_SUCCESS(rc)) {
- spcs_s_add(kstatus, rc);
- rc = DSW_EHDRBMP;
- goto fail;
- }
-
- ip->bi_bmp_tok = _ii_register_path(ii_pathname(ip->bi_bmpfd),
- NSC_CACHE|NSC_DEVICE, _ii_io);
-no_more_bmp_tests:
- _ii_rlse_devs(ip, rtype);
- ip->bi_disabled = 0; /* all okay and ready, we can go now */
- if (!nshadows)
- ii_register_mst(ip);
- if ((ip->bi_flags & DSW_SHDEXPORT) == 0)
- ii_register_shd(ip);
-
- if (!ii_register_ok(ip)) {
- rc = DSW_EREGISTER;
- goto fail;
- }
- _ii_reserve_end(ip);
-
- if (ii_debug > 0)
- cmn_err(CE_NOTE, "!ii: config: master %s shadow %s",
- uconf.master_vol, uconf.shadow_vol);
-
- rc = 0;
- if (ip->bi_flags & DSW_COPYINGP) {
- /* Copy was in progress, so continue it */
- (void) _ii_rsrv_devs(ip, rtype, II_INTERNAL);
- mutex_enter(&ip->bi_mutex);
- ip->bi_ioctl++; /* we are effectively in an ioctl */
- mutex_exit(&ip->bi_mutex);
- rc = _ii_copyvol(ip, ((ip->bi_flags & DSW_COPYINGS) != 0) ?
- CV_SHD2MST : 0, rtype, kstatus, 0);
- }
-
- ++iigkstat.num_sets.value.ul;
-
- return (spcs_s_ocopyoutf(&kstatus, uconf.status, rc));
-
-fail:
- /* remove ip from _ii_info_top linked list */
- mutex_enter(&_ii_info_mutex);
- for (ipp = &_ii_info_top; *ipp; ipp = &((*ipp)->bi_next)) {
- if (ip == *ipp) {
- *ipp = ip->bi_next;
- break;
- }
- }
- mutex_exit(&_ii_info_mutex);
- ii_sibling_free(ip);
-
- return (spcs_s_ocopyoutf(&kstatus, uconf.status, rc));
-}
-
-static int
-_ii_perform_disable(char *setname, spcs_s_info_t *kstatusp, int reclaim)
-{
- _ii_info_t **xip, *ip;
- _ii_overflow_t *op;
- nsc_buf_t *tmp = NULL;
- int rc;
- ii_header_t *bm_header;
- int rtype;
-
- mutex_enter(&_ii_info_mutex);
- ip = _ii_find_set(setname);
- if (ip == NULL) {
- mutex_exit(&_ii_info_mutex);
- return (DSW_ENOTFOUND);
- }
-
- if ((ip->bi_flags & DSW_GOLDEN) &&
- ((ip->bi_flags & DSW_COPYINGP) != 0)) {
- /*
- * Cannot disable an independent copy while still copying
- * as it means that a data dependency exists.
- */
- mutex_exit(&_ii_info_mutex);
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- DTRACE_PROBE(_ii_perform_disable_end_DSW_EDEPENDENCY);
- return (DSW_EDEPENDENCY);
- }
-
- if ((ip->bi_flags & DSW_GOLDEN) == 0 &&
- ii_update_denied(ip, *kstatusp, 0, 1)) {
- /* Cannot disable a dependent shadow while RDC is unsure */
- mutex_exit(&_ii_info_mutex);
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- DTRACE_PROBE(DSW_EOPACKAGE);
- return (DSW_EOPACKAGE);
- }
-
- if (((ip->bi_flags & DSW_RESIZED) == DSW_RESIZED) &&
- ii_need_same_size(ip)) {
- /* We can't disable the set whilst RDC is using it */
- mutex_exit(&_ii_info_mutex);
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- cmn_err(CE_WARN, "!Cannot disable II set: would change "
- "volume size on RDC");
- DTRACE_PROBE(DSW_EOPACKAGE_resize);
- return (DSW_EOPACKAGE);
- }
-
- ip->bi_disabled = 1;
- if (NSHADOWS(ip) && (ip->bi_master == ip)) {
- ip->bi_flags &= (~DSW_COPYING);
- ip->bi_state |= DSW_MULTIMST;
- }
- mutex_exit(&_ii_info_mutex);
-
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
-
- _ii_stopvol(ip);
-
- rtype = SHDR|BMP;
- if ((rc = _ii_rsrv_devs(ip, rtype, II_INTERNAL)) != 0) {
- spcs_s_add(*kstatusp, rc);
- DTRACE_PROBE(DSW_ERSRVFAIL);
- return (DSW_ERSRVFAIL);
- }
-
- if ((ii_header < 128) &&
- (((ip->bi_flags & DSW_GOLDEN) == 0) ||
- (ip->bi_flags & DSW_COPYING))) {
- /*
- * Not a full copy so attempt to prevent use of partial copy
- * by clearing where the first ufs super-block would be
- * located. Solaris often incorporates the disk header into
- * the start of the first slice, so avoid clearing the very
- * first 16 blocks of the volume.
- */
-
- if (ii_debug > 1)
- cmn_err(CE_NOTE, "!ii: Shadow copy invalidated");
- II_READ_START(ip, shadow);
- rc = nsc_alloc_buf(SHDFD(ip), ii_header, 128 - ii_header,
- NSC_RDWRBUF, &tmp);
- II_READ_END(ip, shadow, rc, 128 - ii_header);
- if (II_SUCCESS(rc)) {
- rc = nsc_zero(tmp, ii_header, 128 - ii_header, 0);
- if (II_SUCCESS(rc)) {
- II_NSC_WRITE(ip, shadow, rc, tmp, ii_header,
- (128 - ii_header), 0);
- }
- }
- if (tmp)
- (void) nsc_free_buf(tmp);
- if (!II_SUCCESS(rc))
- _ii_error(ip, DSW_SHDOFFLINE);
- }
-
- /* this rw_enter forces us to drain all active IO */
- rw_enter(&ip->bi_linkrw, RW_WRITER);
- rw_exit(&ip->bi_linkrw);
-
- /* remove ip from _ii_info_top linked list */
- mutex_enter(&_ii_info_mutex);
- for (xip = &_ii_info_top; *xip; xip = &((*xip)->bi_next)) {
- if (ip == *xip) {
- *xip = ip->bi_next;
- break;
- }
- }
- if (ip->bi_kstat) {
- kstat_delete(ip->bi_kstat);
- ip->bi_kstat = NULL;
- }
- mutex_exit(&_ii_info_mutex);
-
- rc = II_SAVE_BMP(ip, 1);
- mutex_enter(&ip->bi_mutex);
- if (rc == 0)
- bm_header = _ii_bm_header_get(ip, &tmp);
- if (rc == 0 && bm_header) {
- if (ii_debug > 1)
- cmn_err(CE_NOTE, "!ii: Invalid header written");
- bm_header->ii_magic = DSW_INVALID;
- /* write it to disk */
- (void) _ii_bm_header_put(bm_header, ip, tmp);
- }
- mutex_exit(&ip->bi_mutex);
-
- op = ip->bi_overflow;
- if (op && (reclaim == -1)) {
- reclaim = (op->ii_drefcnt == 1? NO_RECLAIM : RECLAIM);
- }
-
- if ((op != NULL) && (op->ii_hversion >= 1) &&
- (op->ii_hmagic == II_OMAGIC)) {
- mutex_enter(&_ii_overflow_mutex);
- if (ip->bi_flags & DSW_OVRHDRDRTY) {
- mutex_enter(&ip->bi_mutex);
- ip->bi_flags &= ~DSW_OVRHDRDRTY;
- mutex_exit(&ip->bi_mutex);
- ASSERT(op->ii_urefcnt > 0);
- op->ii_urefcnt--;
- }
- if (op->ii_urefcnt == 0) {
- op->ii_flags &= ~IIO_CNTR_INVLD;
- op->ii_unused = op->ii_nchunks - 1;
- }
- mutex_exit(&_ii_overflow_mutex);
- }
- ii_overflow_free(ip, reclaim);
- _ii_rlse_devs(ip, rtype);
-
- ii_sibling_free(ip);
-
- --iigkstat.num_sets.value.ul;
- return (0);
-}
-
-/*
- * _ii_disable
- * Deconfigures an II pair
- *
- * Calling/Exit State:
- * Returns 0 if the pair was disabled. Otherwise an error code
- * is returned and any additional error information is copied
- * out to the user.
- *
- * Description:
- * Reads the user configuration structure and attempts to
- * deconfigure that pairing based on the master device pathname.
- */
-
-int
-_ii_disable(intptr_t arg, int ilp32, int *rvp)
-{
- dsw_ioctl_t uparms;
- dsw_ioctl32_t uparms32;
- _ii_overflow_t *op;
- int rc, rerr;
- spcs_s_info_t kstatus;
- uint64_t hash;
- int reclaim;
- _ii_lsthead_t *oldhead, **head;
- _ii_lstinfo_t *np, **xnp, *oldp;
-
- *rvp = 0;
-
- if (ilp32) {
- if (copyin((void *)arg, &uparms32, sizeof (uparms32)) < 0)
- return (EFAULT);
- II_TAIL_COPY(uparms, uparms32, shadow_vol, dsw_ioctl_t);
- uparms.status = (spcs_s_info_t)uparms32.status;
- } else if (copyin((void *)arg, &uparms, sizeof (uparms)) < 0)
- return (EFAULT);
-
- kstatus = spcs_s_kcreate();
- if (kstatus == NULL)
- return (ENOMEM);
-
- if (!uparms.shadow_vol[0])
- return (spcs_s_ocopyoutf(&kstatus, uparms.status, DSW_EEMPTY));
-
- DTRACE_PROBE2(_ii_disable_info, char *, uparms.shadow_vol,
- int, uparms.flags);
-
- /* group or single set? */
- if (uparms.flags & CV_IS_GROUP) {
- hash = nsc_strhash(uparms.shadow_vol);
- mutex_enter(&_ii_group_mutex);
- for (head = &_ii_group_top; *head;
- head = &((*head)->lst_next)) {
- if ((hash == (*head)->lst_hash) &&
- strncmp((*head)->lst_name, uparms.shadow_vol,
- DSW_NAMELEN) == 0)
- break;
- }
-
- if (!*head) {
- mutex_exit(&_ii_group_mutex);
- return (spcs_s_ocopyoutf(&kstatus, uparms.status,
- DSW_EGNOTFOUND));
- }
-
- /* clear any overflow vol usage counts */
- for (np = (*head)->lst_start; np; np = np->lst_next) {
- if (np->lst_ip->bi_overflow) {
- np->lst_ip->bi_overflow->ii_detachcnt = 0;
- }
- }
-
- /* now increment */
- for (np = (*head)->lst_start; np; np = np->lst_next) {
- if (np->lst_ip->bi_overflow) {
- ++np->lst_ip->bi_overflow->ii_detachcnt;
- }
- }
-
- /* finally, disable all group members */
- rerr = 0;
- xnp = &(*head)->lst_start;
- while (*xnp) {
- op = (*xnp)->lst_ip->bi_overflow;
- if (op) {
- reclaim = (op->ii_drefcnt == op->ii_detachcnt?
- NO_RECLAIM : RECLAIM);
- --op->ii_detachcnt;
- }
-
- /* clear out the group pointer */
- (*xnp)->lst_ip->bi_group = NULL;
-
- rc = _ii_perform_disable((*xnp)->lst_ip->bi_keyname,
- &kstatus, reclaim);
- if (rc) {
- /* restore group name */
- (*xnp)->lst_ip->bi_group = (*head)->lst_name;
-
- /* restore detachcnt */
- if (op) {
- ++op->ii_detachcnt;
- }
-
- /* don't delete branch */
- ++rerr;
- spcs_s_add(kstatus, rc);
-
- /* move forward in linked list */
- xnp = &(*xnp)->lst_next;
- } else {
- oldp = (*xnp);
- *xnp = (*xnp)->lst_next;
- kmem_free(oldp, sizeof (_ii_lstinfo_t));
- }
- }
- if (rerr) {
- mutex_exit(&_ii_group_mutex);
- return (spcs_s_ocopyoutf(&kstatus, uparms.status,
- DSW_EDISABLE));
- }
- /* no errors, all sets disabled, OK to free list head */
- oldhead = *head;
- *head = (*head)->lst_next;
- kmem_free(oldhead, sizeof (_ii_lsthead_t));
- mutex_exit(&_ii_group_mutex);
- } else {
- /* only a single set is being disabled */
- rc = _ii_perform_disable(uparms.shadow_vol, &kstatus, -1);
- if (rc)
- return (spcs_s_ocopyoutf(&kstatus, uparms.status, rc));
- }
-
- spcs_s_kfree(kstatus);
-
- return (0);
-}
-
-
-/*
- * _ii_stat
- * Get state of the shadow.
- *
- * Calling/Exit State:
- * Returns 0 on success, otherwise an error code is returned
- * and any additional error information is copied out to the user.
- * The size variable in the dsw_stat_t is set to the FBA size
- * of the volume, the stat variable is set to the state, and
- * the structure is copied out.
- */
-/*ARGSUSED*/
-int
-_ii_stat(intptr_t arg, int ilp32, int *rvp)
-{
- dsw_stat_t ustat;
- dsw_stat32_t ustat32;
- _ii_info_t *ip;
- spcs_s_info_t kstatus;
- char *group, *cluster;
-
- if (ilp32) {
- if (copyin((void *)arg, &ustat32, sizeof (ustat32)) < 0)
- return (EFAULT);
- II_TAIL_COPY(ustat, ustat32, shadow_vol, dsw_stat_t);
- ustat.status = (spcs_s_info_t)ustat32.status;
- } else if (copyin((void *)arg, &ustat, sizeof (ustat)) < 0)
- return (EFAULT);
-
- kstatus = spcs_s_kcreate();
- if (kstatus == NULL)
- return (ENOMEM);
-
- if (!ustat.shadow_vol[0])
- return (spcs_s_ocopyoutf(&kstatus, ustat.status, DSW_EEMPTY));
-
- mutex_enter(&_ii_info_mutex);
- ip = _ii_find_set(ustat.shadow_vol);
- mutex_exit(&_ii_info_mutex);
- if (ip == NULL)
- return (spcs_s_ocopyoutf(&kstatus, ustat.status,
- DSW_ENOTFOUND));
-
- ustat.stat = ip->bi_flags;
- ustat.size = ip->bi_size;
- ustat.mtime = ip->bi_mtime;
-
- if (ilp32)
- bzero(ustat32.overflow_vol, DSW_NAMELEN);
- else
- bzero(ustat.overflow_vol, DSW_NAMELEN);
- if (ip->bi_overflow) {
- (void) strncpy(ilp32 ? ustat32.overflow_vol :
- ustat.overflow_vol, ip->bi_overflow->ii_volname,
- DSW_NAMELEN);
- }
-
- ustat.shdsize = ip->bi_shdchks;
- if ((ip->bi_flags) & DSW_TREEMAP) {
- ustat.shdused = ip->bi_shdchkused;
- } else {
- ustat.shdused = 0;
- }
-
- /* copy over group and cluster associations */
- group = ilp32? ustat32.group_name : ustat.group_name;
- cluster = ilp32? ustat32.cluster_tag : ustat.cluster_tag;
- bzero(group, DSW_NAMELEN);
- bzero(cluster, DSW_NAMELEN);
- if (ip->bi_group)
- (void) strncpy(group, ip->bi_group, DSW_NAMELEN);
- if (ip->bi_cluster)
- (void) strncpy(cluster, ip->bi_cluster, DSW_NAMELEN);
-
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
-
- spcs_s_kfree(kstatus);
- if (ilp32) {
- ustat32.stat = ustat.stat;
- ustat32.size = ustat.size;
- ustat32.shdsize = ustat.shdsize;
- ustat32.shdused = ustat.shdused;
- ustat32.mtime = ustat.mtime;
- if (copyout(&ustat32, (void *)arg, sizeof (ustat32)))
- return (EFAULT);
- } else if (copyout(&ustat, (void *)arg, sizeof (ustat)))
- return (EFAULT);
-
- return (0);
-}
-
-
-/*
- * _ii_list
- * List what shadow sets are currently configured.
- *
- * Calling/Exit State:
- * Returns 0 on success, otherwise an error code is returned
- * and any additional error information is copied out to the user.
- */
-/*ARGSUSED*/
-int
-_ii_list(intptr_t arg, int ilp32, int *rvp)
-{
- dsw_list_t ulist;
- dsw_list32_t ulist32;
- _ii_info_t *ip;
- dsw_config_t cf, *cfp;
- dsw_config32_t cf32, *cf32p;
- int rc;
- int used;
- spcs_s_info_t kstatus;
-
- if (ilp32) {
- if (copyin((void *)arg, &ulist32, sizeof (ulist32)) < 0)
- return (EFAULT);
- II_TAIL_COPY(ulist, ulist32, list_size, dsw_list_t);
- ulist.status = (spcs_s_info_t)ulist32.status;
- } else if (copyin((void *)arg, &ulist, sizeof (ulist)) < 0)
- return (EFAULT);
-
- kstatus = spcs_s_kcreate();
- if (kstatus == NULL)
- return (ENOMEM);
-
- cf32p = (dsw_config32_t *)(unsigned long)ulist32.list;
- cfp = ulist.list;
- ulist.list_used = 0;
- mutex_enter(&_ii_info_mutex);
- ip = _ii_info_top;
-
- DTRACE_PROBE1(_ii_list_count, int, ulist.list_size);
-
- for (rc = used = 0; used < ulist.list_size && ip; ip = ip->bi_next) {
-
- if (ip->bi_disabled)
- continue;
-
- mutex_enter(&ip->bi_mutex);
- ip->bi_ioctl++;
- if (ilp32) {
- bzero(&cf32, sizeof (cf32));
- cf32.flag = ip->bi_flags;
- (void) strncpy(cf32.master_vol,
- ii_pathname(ip->bi_mstfd), DSW_NAMELEN);
- (void) strncpy(cf32.shadow_vol,
- ip->bi_keyname, DSW_NAMELEN);
- (void) strncpy(cf32.bitmap_vol, (ip->bi_bmpfd)
- ? ii_pathname(ip->bi_bmpfd)
- : "<offline_bitmap>", DSW_NAMELEN);
- if (copyout(&cf32, (void *)cf32p, sizeof (cf32)))
- rc = EFAULT;
- cf32p++;
- } else {
- bzero(&cf, sizeof (cf));
- cf.flag = ip->bi_flags;
- (void) strncpy(cf.master_vol,
- ii_pathname(ip->bi_mstfd), DSW_NAMELEN);
- (void) strncpy(cf.shadow_vol,
- ip->bi_keyname, DSW_NAMELEN);
- (void) strncpy(cf.bitmap_vol, (ip->bi_bmpfd)
- ? ii_pathname(ip->bi_bmpfd)
- : "<offline_bitmap>", DSW_NAMELEN);
- if (copyout(&cf, (void *)cfp, sizeof (cf)))
- rc = EFAULT;
- cfp++;
- }
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- used++;
- }
- mutex_exit(&_ii_info_mutex);
-
- spcs_s_kfree(kstatus);
- if (rc)
- return (rc);
-
- ulist.list_used = used;
- if (ilp32) {
- ulist32.list_used = ulist.list_used;
- if (copyout(&ulist32, (void *)arg, sizeof (ulist32)))
- return (EFAULT);
- } else if (copyout(&ulist, (void *)arg, sizeof (ulist)))
- return (EFAULT);
-
- return (0);
-}
-
-/*
- * _ii_listlen
- * Counts the number of items the DSWIOC_LIST and DSWIOC_OLIST
- * ioctl calls would return.
- *
- * Calling/Exit State:
- * Returns 0 on success, otherwise an error code is returned.
- * Result is returned as successful ioctl value.
- */
-/*ARGSUSED*/
-int
-_ii_listlen(int cmd, int ilp32, int *rvp)
-{
- _ii_info_t *ip;
- _ii_overflow_t *op;
- int count = 0;
-
- switch (cmd) {
-
- case DSWIOC_LISTLEN:
- mutex_enter(&_ii_info_mutex);
- for (ip = _ii_info_top; ip; ip = ip->bi_next) {
- if (ip->bi_disabled == 0) {
- count++;
- }
- }
- mutex_exit(&_ii_info_mutex);
- break;
- case DSWIOC_OLISTLEN:
- mutex_enter(&_ii_overflow_mutex);
- for (op = _ii_overflow_top; op; op = op->ii_next)
- count++;
- mutex_exit(&_ii_overflow_mutex);
- break;
- default:
- return (EINVAL);
- }
- *rvp = count;
-
- return (0);
-}
-
-/*
- * _ii_report_bmp
- *
- * Report to the user daemon that the bitmap has gone bad
- */
-static int
-_ii_report_bmp(_ii_info_t *ip)
-{
- int rc;
- struct nskernd *nsk;
-
- nsk = kmem_zalloc(sizeof (*nsk), KM_SLEEP);
- if (!nsk) {
- return (ENOMEM);
- }
- nsk->command = NSKERND_IIBITMAP;
- nsk->data1 = (int64_t)(ip->bi_flags | DSW_BMPOFFLINE);
- (void) strncpy(nsk->char1, ip->bi_keyname,
- min(DSW_NAMELEN, NSC_MAXPATH));
-
- rc = nskernd_get(nsk);
- if (rc == 0) {
- rc = (int)nsk->data1;
- }
- if (rc == 0) {
- DTRACE_PROBE(_ii_report_bmp_end);
- } else {
- DTRACE_PROBE1(_ii_report_bmp_end_2, int, rc);
- }
- kmem_free(nsk, sizeof (*nsk));
- return (rc);
-}
-
-/*
- * _ii_offline
- * Set volume offline flag(s) for a shadow.
- *
- * Calling/Exit State:
- * Returns 0 on success, otherwise an error code is returned
- * and any additional error information is copied out to the user.
- */
-/*ARGSUSED*/
-int
-_ii_offline(intptr_t arg, int ilp32, int *rvp)
-{
- dsw_ioctl_t uparms;
- dsw_ioctl32_t uparms32;
- _ii_info_t *ip;
- int rc;
- spcs_s_info_t kstatus;
-
- if (ilp32) {
- if (copyin((void *)arg, &uparms32, sizeof (uparms32)) < 0)
- return (EFAULT);
- II_TAIL_COPY(uparms, uparms32, shadow_vol, dsw_ioctl_t);
- uparms.status = (spcs_s_info_t)uparms32.status;
- } else if (copyin((void *)arg, &uparms, sizeof (uparms)) < 0)
- return (EFAULT);
-
- kstatus = spcs_s_kcreate();
- if (kstatus == NULL)
- return (ENOMEM);
-
- if (!uparms.shadow_vol[0])
- return (spcs_s_ocopyoutf(&kstatus, uparms.status, DSW_EEMPTY));
-
- mutex_enter(&_ii_info_mutex);
- ip = _ii_find_set(uparms.shadow_vol);
- mutex_exit(&_ii_info_mutex);
- if (ip == NULL)
- return (spcs_s_ocopyoutf(&kstatus, uparms.status,
- DSW_ENOTFOUND));
-
- if ((rc = _ii_rsrv_devs(ip, BMP, II_INTERNAL)) != 0) {
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- spcs_s_add(kstatus, rc);
- return (spcs_s_ocopyoutf(&kstatus, uparms.status,
- DSW_ERSRVFAIL));
- }
-
- mutex_exit(&ip->bi_mutex);
- _ii_error(ip, uparms.flags & DSW_OFFLINE);
- mutex_enter(&ip->bi_mutex);
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
-
- _ii_rlse_devs(ip, BMP);
-
- spcs_s_kfree(kstatus);
-
- return (0);
-}
-
-
-/*
- * _ii_wait
- * Wait for a copy to complete.
- *
- * Calling/Exit State:
- * Returns 0 if the copy completed, otherwise error code.
- *
- */
-/*ARGSUSED*/
-int
-_ii_wait(intptr_t arg, int ilp32, int *rvp)
-{
- dsw_ioctl_t uparms;
- dsw_ioctl32_t uparms32;
- _ii_info_t *ip;
- int rc = 0;
- spcs_s_info_t kstatus;
-
- if (ilp32) {
- if (copyin((void *)arg, &uparms32, sizeof (uparms32)) < 0)
- return (EFAULT);
- II_TAIL_COPY(uparms, uparms32, shadow_vol, dsw_ioctl_t);
- uparms.status = (spcs_s_info_t)uparms32.status;
- uparms.pid = uparms32.pid;
- } else if (copyin((void *)arg, &uparms, sizeof (uparms)) < 0)
- return (EFAULT);
-
- kstatus = spcs_s_kcreate();
- if (kstatus == NULL)
- return (ENOMEM);
-
- if (!uparms.shadow_vol[0])
- return (spcs_s_ocopyoutf(&kstatus, uparms.status, DSW_EEMPTY));
-
- mutex_enter(&_ii_info_mutex);
- ip = _ii_find_set(uparms.shadow_vol);
- mutex_exit(&_ii_info_mutex);
- if (ip == NULL)
- return (spcs_s_ocopyoutf(&kstatus, uparms.status,
- DSW_ENOTFOUND));
-
- while (ip->bi_flags & DSW_COPYINGP) {
- if (cv_wait_sig(&ip->bi_copydonecv, &ip->bi_mutex) == 0) {
- /* Awoken by a signal */
- rc = EINTR;
- break;
- }
- }
-
- /* Is this an attempt to unlock the copy/update PID? */
- if (uparms.flags & CV_LOCK_PID) {
- if (ip->bi_locked_pid == 0) {
- rc = DSW_ENOTLOCKED;
- } else if (uparms.pid == -1) {
- cmn_err(CE_WARN, "!ii: Copy/Update PID %d, cleared",
- ip->bi_locked_pid);
- ip->bi_locked_pid = 0;
- } else if (uparms.pid != ip->bi_locked_pid) {
- rc = DSW_EINUSE;
- } else {
- ip->bi_locked_pid = 0;
- }
- }
-
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
-
- return (spcs_s_ocopyoutf(&kstatus, uparms.status, rc));
-}
-
-
-static int
-_ii_reset_mstvol(_ii_info_t *ip)
-{
- _ii_info_t *xip;
-
- if (!NSHADOWS(ip))
- return (DSW_COPYINGS | DSW_COPYINGP);
-
- /* check for siblings updating master */
- for (xip = ip->bi_head; xip; xip = xip->bi_sibling) {
- if (xip == ip)
- continue;
- /* check if master is okay */
- if ((xip->bi_flags & DSW_MSTOFFLINE) == 0) {
- return (0);
- }
- }
-
- return (DSW_COPYINGS | DSW_COPYINGP);
-}
-
-/*
- * _ii_reset
- * Reset offlined underlying volumes
- *
- * Calling/Exit State:
- * Returns 0 on success, otherwise an error code is returned
- * and any additional error information is copied out to the user.
- */
-/*ARGSUSED*/
-int
-_ii_reset(intptr_t arg, int ilp32, int *rvp)
-{
- dsw_ioctl_t uparms;
- dsw_ioctl32_t uparms32;
- _ii_info_t *ip;
- nsc_buf_t *tmp = NULL;
- int rc;
- int flags;
- ii_header_t *bm_header;
- spcs_s_info_t kstatus;
- int rtype;
-
- if (ilp32) {
- if (copyin((void *)arg, &uparms32, sizeof (uparms32)) < 0)
- return (EFAULT);
- II_TAIL_COPY(uparms, uparms32, shadow_vol, dsw_ioctl_t);
- uparms.status = (spcs_s_info_t)uparms32.status;
- } else if (copyin((void *)arg, &uparms, sizeof (uparms)) < 0)
- return (EFAULT);
-
- kstatus = spcs_s_kcreate();
- if (kstatus == NULL)
- return (ENOMEM);
-
- if (!uparms.shadow_vol[0])
- return (spcs_s_ocopyoutf(&kstatus, uparms.status, DSW_EEMPTY));
-
- mutex_enter(&_ii_info_mutex);
- ip = _ii_find_set(uparms.shadow_vol);
- mutex_exit(&_ii_info_mutex);
- if (ip == NULL)
- return (spcs_s_ocopyoutf(&kstatus, uparms.status,
- DSW_ENOTFOUND));
-
- mutex_exit(&ip->bi_mutex);
-
- /* Figure out what to do according to what was flagged as */
-
- if ((ip->bi_flags & DSW_OFFLINE) == 0) {
- /* Nothing offline, so no op */
- mutex_enter(&ip->bi_mutex);
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- spcs_s_kfree(kstatus);
- return (0);
- }
-
- if (!ip->bi_bmpfd) {
- /* No bitmap fd, can't do anything */
- mutex_enter(&ip->bi_mutex);
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- spcs_s_kfree(kstatus);
- return (DSW_EHDRBMP);
- }
-
- rtype = MSTR|SHDR|BMP;
- if ((rc = _ii_rsrv_devs(ip, rtype, II_INTERNAL)) != 0) {
- mutex_enter(&ip->bi_mutex);
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- spcs_s_add(kstatus, rc);
- return (spcs_s_ocopyoutf(&kstatus, uparms.status,
- DSW_ERSRVFAIL));
- }
-
- /*
- * Cannot use _ii_bm_header_get as it will fail if DSW_BMPOFFLINE
- */
- II_READ_START(ip, bitmap);
- rc = nsc_alloc_buf(ip->bi_bmpfd, 0, FBA_LEN(sizeof (ii_header_t)),
- NSC_RDWRBUF, &tmp);
- II_READ_END(ip, bitmap, rc, FBA_LEN(sizeof (ii_header_t)));
- if (!II_SUCCESS(rc)) {
- _ii_rlse_devs(ip, rtype);
- mutex_enter(&ip->bi_mutex);
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- if (tmp)
- (void) nsc_free_buf(tmp);
- _ii_error(ip, DSW_BMPOFFLINE);
- spcs_s_add(kstatus, rc);
- return (spcs_s_ocopyoutf(&kstatus, uparms.status, DSW_EHDRBMP));
- }
-
- bm_header = (ii_header_t *)(tmp)->sb_vec[0].sv_addr;
- if (bm_header == NULL) {
- _ii_rlse_devs(ip, rtype);
- mutex_enter(&ip->bi_mutex);
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- if (tmp)
- (void) nsc_free_buf(tmp);
- return (spcs_s_ocopyoutf(&kstatus, uparms.status, DSW_EHDRBMP));
- }
-
- flags = ip->bi_flags & ~DSW_COPY_FLAGS;
- if ((flags & (DSW_SHDIMPORT|DSW_SHDEXPORT)) == 0) {
- if (((flags & DSW_SHDOFFLINE) == 0) &&
- ((flags & DSW_MSTOFFLINE) == DSW_MSTOFFLINE)) {
- /* Shadow was OK but master was offline */
- flags |= _ii_reset_mstvol(ip);
- } else if ((flags & DSW_SHDOFFLINE) == DSW_SHDOFFLINE) {
- /* Shadow was offline, don't care what the master was */
- flags |= (DSW_COPYINGM | DSW_COPYINGP);
- }
- }
- if (ip->bi_flags & DSW_VOVERFLOW) {
- ip->bi_flags &= ~DSW_VOVERFLOW;
- ip->bi_flags |= DSW_FRECLAIM;
- }
- flags &= ~(DSW_OFFLINE | DSW_CFGOFFLINE | DSW_VOVERFLOW | DSW_OVERFLOW);
- if ((ip->bi_flags & DSW_BMPOFFLINE) == DSW_BMPOFFLINE) {
- /* free any overflow allocation */
- ii_overflow_free(ip, INIT_OVR);
- /* Bitmap now OK, so set up new bitmap header */
- (void) strncpy(bm_header->master_vol, ii_pathname(ip->bi_mstfd),
- DSW_NAMELEN);
- (void) strncpy(bm_header->shadow_vol, ii_pathname(ip->bi_shdfd),
- DSW_NAMELEN);
- (void) strncpy(bm_header->bitmap_vol, ii_pathname(ip->bi_bmpfd),
- DSW_NAMELEN);
- if (ip->bi_cluster) {
- (void) strncpy(bm_header->clstr_name, ip->bi_cluster,
- DSW_NAMELEN);
- }
- if (ip->bi_group) {
- (void) strncpy(bm_header->group_name, ip->bi_group,
- DSW_NAMELEN);
- }
- bm_header->ii_type = (flags & DSW_GOLDEN) ?
- DSW_GOLDEN_TYPE : DSW_QUICK_TYPE;
- bm_header->ii_magic = DSW_DIRTY;
- bm_header->ii_version = II_HEADER_VERSION;
- bm_header->ii_shdfba = DSW_SHD_BM_OFFSET;
- bm_header->ii_copyfba = DSW_COPY_BM_OFFSET;
- bm_header->ii_throttle_delay = ip->bi_throttle_delay;
- bm_header->ii_throttle_unit = ip->bi_throttle_unit;
- ip->bi_shdfba = bm_header->ii_shdfba;
- ip->bi_copyfba = bm_header->ii_copyfba;
- } else if ((ip->bi_flags & DSW_SHDOFFLINE) == DSW_SHDOFFLINE) {
- /* bitmap didn't go offline, but shadow did */
- if (ip->bi_overflow) {
- ii_overflow_free(ip, RECLAIM);
- }
- }
- _ii_lock_chunk(ip, II_NULLCHUNK);
- mutex_enter(&ip->bi_mutex);
- II_FLAG_ASSIGN(flags, ip);
-
- mutex_exit(&ip->bi_mutex);
- rc = ii_fill_copy_bmp(ip);
- if (rc == 0)
- rc = II_ZEROBM(ip);
- if (rc == 0) {
- if ((ip->bi_flags&(DSW_GOLDEN)) == 0) {
- /* just clear bitmaps for dependent copy */
- if (ip->bi_flags & DSW_TREEMAP) {
- bm_header->ii_state = ip->bi_flags;
- mutex_enter(&ip->bi_mutex);
- rc = _ii_bm_header_put(bm_header, ip, tmp);
- mutex_exit(&ip->bi_mutex);
- tmp = NULL;
- if (rc == 0) {
- rc = ii_tinit(ip);
- if (rc == 0) {
- mutex_enter(&ip->bi_mutex);
- bm_header =
- _ii_bm_header_get(ip, &tmp);
- mutex_exit(&ip->bi_mutex);
- }
- }
- }
-
- if (rc == 0)
- II_FLAG_CLRX(DSW_COPY_FLAGS, ip);
- /*
- * if copy flags were set, another process may be
- * waiting
- */
- if (rc == 0 && (flags & DSW_COPYINGP))
- cv_broadcast(&ip->bi_copydonecv);
-
- if (rc == 0)
- rc = II_COPYBM(ip);
- }
- }
- _ii_unlock_chunk(ip, II_NULLCHUNK);
- if (rc) {
- if (tmp)
- _ii_bm_header_free(bm_header, ip, tmp);
- mutex_enter(&ip->bi_mutex);
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- _ii_rlse_devs(ip, rtype);
- spcs_s_add(kstatus, rc);
- return (spcs_s_ocopyoutf(&kstatus, uparms.status, DSW_EHDRBMP));
- }
- bm_header->ii_state = ip->bi_flags;
- mutex_enter(&ip->bi_mutex);
- rc = _ii_bm_header_put(bm_header, ip, tmp);
- if (!II_SUCCESS(rc)) {
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- _ii_rlse_devs(ip, rtype);
- spcs_s_add(kstatus, rc);
- return (spcs_s_ocopyoutf(&kstatus, uparms.status, DSW_EHDRBMP));
- }
-
- /* check with RDC */
- if (ii_update_denied(ip, kstatus, (ip->bi_flags & DSW_COPYINGS) ?
- CV_SHD2MST : 0, 1)) {
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- _ii_rlse_devs(ip, rtype);
- return (spcs_s_ocopyoutf(&kstatus, uparms.status, rc));
- }
-
- /* don't perform copy for dependent shadows */
- if ((ip->bi_flags&(DSW_GOLDEN)) == 0) {
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- _ii_rlse_devs(ip, rtype);
- return (spcs_s_ocopyoutf(&kstatus, uparms.status, rc));
- }
-
- mutex_exit(&ip->bi_mutex);
- /* _ii_copyvol calls _ii_ioctl_done() */
- if (ip->bi_flags & DSW_COPYINGS)
- rc = _ii_copyvol(ip, CV_SHD2MST, rtype, kstatus, 1);
- else if (ip->bi_flags & DSW_COPYINGM)
- rc = _ii_copyvol(ip, 0, rtype, kstatus, 1);
- else {
- mutex_enter(&ip->bi_mutex);
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- }
-
- _ii_rlse_devs(ip, rtype);
-
- return (spcs_s_ocopyoutf(&kstatus, uparms.status, rc));
-}
-
-
-/*
- * _ii_version
- * Get version of the InstantImage module.
- *
- * Calling/Exit State:
- * Returns 0 on success, otherwise EFAULT is returned.
- * The major and minor revisions are copied out to the user if
- * successful.
- */
-/*ARGSUSED*/
-int
-_ii_version(intptr_t arg, int ilp32, int *rvp)
-{
- dsw_version_t uversion;
- dsw_version32_t uversion32;
-
- if (ilp32) {
- if (copyin((void *)arg, &uversion32, sizeof (uversion32)) < 0)
- return (EFAULT);
-
- uversion32.major = dsw_major_rev;
- uversion32.minor = dsw_minor_rev;
- uversion32.micro = dsw_micro_rev;
- uversion32.baseline = dsw_baseline_rev;
-
- if (copyout(&uversion32, (void *)arg, sizeof (uversion32)))
- return (EFAULT);
- } else {
- if (copyin((void *)arg, &uversion, sizeof (uversion)) < 0)
- return (EFAULT);
-
- uversion.major = dsw_major_rev;
- uversion.minor = dsw_minor_rev;
- uversion.micro = dsw_micro_rev;
- uversion.baseline = dsw_baseline_rev;
-
- if (copyout(&uversion, (void *)arg, sizeof (uversion)))
- return (EFAULT);
- }
-
- return (0);
-}
-
-/*
- * _ii_copyparm
- * Get and set copy parameters.
- *
- * Calling/Exit State:
- * Returns 0 on success, otherwise EFAULT is returned.
- * The previous values are returned to the user.
- */
-/*ARGSUSED*/
-int
-_ii_copyparm(intptr_t arg, int ilp32, int *rvp)
-{
- dsw_copyp_t copyp;
- dsw_copyp32_t copyp32;
- spcs_s_info_t kstatus;
- _ii_info_t *ip;
- int rc = 0;
- int tmp;
-
- if (ilp32) {
- if (copyin((void *)arg, &copyp32, sizeof (copyp32)) < 0)
- return (EFAULT);
- II_TAIL_COPY(copyp, copyp32, shadow_vol, dsw_copyp_t);
- copyp.status = (spcs_s_info_t)copyp32.status;
- } else if (copyin((void *)arg, &copyp, sizeof (copyp)) < 0)
- return (EFAULT);
-
- kstatus = spcs_s_kcreate();
- if (kstatus == NULL)
- return (ENOMEM);
-
- if (!copyp.shadow_vol[0])
- return (spcs_s_ocopyoutf(&kstatus, copyp.status, DSW_EEMPTY));
-
- mutex_enter(&_ii_info_mutex);
- ip = _ii_find_set(copyp.shadow_vol);
- mutex_exit(&_ii_info_mutex);
- if (ip == NULL)
- return (spcs_s_ocopyoutf(&kstatus, copyp.status,
- DSW_ENOTFOUND));
-
- tmp = ip->bi_throttle_delay;
- if (copyp.copy_delay != -1) {
- if (copyp.copy_delay >= MIN_THROTTLE_DELAY &&
- copyp.copy_delay <= MAX_THROTTLE_DELAY)
- ip->bi_throttle_delay = copyp.copy_delay;
- else {
- cmn_err(CE_WARN, "!ii: delay out of range %d",
- copyp.copy_delay);
- rc = EINVAL;
- }
- }
- copyp.copy_delay = tmp;
-
- tmp = ip->bi_throttle_unit;
- if (copyp.copy_unit != -1) {
- if (copyp.copy_unit >= MIN_THROTTLE_UNIT &&
- copyp.copy_unit <= MAX_THROTTLE_UNIT) {
- if (rc != EINVAL)
- ip->bi_throttle_unit = copyp.copy_unit;
- } else {
- cmn_err(CE_WARN, "!ii: unit out of range %d",
- copyp.copy_unit);
- if (rc != EINVAL) {
- rc = EINVAL;
- ip->bi_throttle_delay = copyp.copy_delay;
- }
- }
- }
- copyp.copy_unit = tmp;
-
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
-
- if (ilp32) {
- copyp32.copy_delay = copyp.copy_delay;
- copyp32.copy_unit = copyp.copy_unit;
- if (copyout(&copyp32, (void *)arg, sizeof (copyp32)) < 0)
- return (EFAULT);
- } else if (copyout(&copyp, (void *)arg, sizeof (copyp)))
- return (EFAULT);
-
- return (spcs_s_ocopyoutf(&kstatus, copyp.status, rc));
-}
-
-
-/*
- * _ii_suspend_vol
- * suspend an individual InstantImage group
- *
- * Calling/Exit State:
- * Returns 0 on success, nonzero otherwise
- */
-
-int
-_ii_suspend_vol(_ii_info_t *ip)
-{
- _ii_info_t **xip;
- int copy_flag;
- int rc;
- nsc_buf_t *tmp = NULL;
- ii_header_t *bm_header;
-
- copy_flag = ip->bi_flags & DSW_COPY_FLAGS;
-
- _ii_stopvol(ip);
- ASSERT(total_ref(ip) == 0);
-
- if ((rc = _ii_rsrv_devs(ip, BMP, II_INTERNAL)) != 0)
- return (rc);
-
- /* this rw_enter forces us to drain all active IO */
- rw_enter(&ip->bi_linkrw, RW_WRITER);
- rw_exit(&ip->bi_linkrw);
-
- mutex_enter(&_ii_info_mutex);
- for (xip = &_ii_info_top; *xip; xip = &(*xip)->bi_next) {
- if (ip == *xip)
- break;
- }
- *xip = ip->bi_next;
- mutex_exit(&_ii_info_mutex);
-
- rc = II_SAVE_BMP(ip, 1);
- mutex_enter(&ip->bi_mutex);
- if (rc == 0)
- bm_header = _ii_bm_header_get(ip, &tmp);
- if (rc == 0 && bm_header) {
- bm_header->ii_magic = DSW_CLEAN;
- bm_header->ii_state |= copy_flag;
- bm_header->ii_throttle_delay = ip->bi_throttle_delay;
- bm_header->ii_throttle_unit = ip->bi_throttle_unit;
- /* copy over the mtime */
- bm_header->ii_mtime = ip->bi_mtime;
- /* write it to disk */
- rc = _ii_bm_header_put(bm_header, ip, tmp);
- }
- --iigkstat.num_sets.value.ul;
- mutex_exit(&ip->bi_mutex);
-
- ii_overflow_free(ip, NO_RECLAIM);
- _ii_rlse_devs(ip, BMP);
-
- ii_sibling_free(ip);
-
- return (rc);
-}
-
-/*
- * _ii_suspend_cluster
- * Cluster resource group is switching over to another node, so
- * all shadowed volumes in that group are suspended.
- *
- * Returns 0 on success, or ESRCH if the name of the cluster resource
- * group couldn't be found.
- */
-int
-_ii_suspend_cluster(char *shadow_vol)
-{
- int found, last;
- uint64_t hash;
- _ii_info_t *ip;
- _ii_lsthead_t **cp, *xcp;
- _ii_lstinfo_t **np, *xnp;
-
- /* find appropriate cluster list */
- mutex_enter(&_ii_cluster_mutex);
- hash = nsc_strhash(shadow_vol);
- for (cp = &_ii_cluster_top; *cp; cp = &((*cp)->lst_next)) {
- if ((hash == (*cp)->lst_hash) && strncmp(shadow_vol,
- (*cp)->lst_name, DSW_NAMELEN) == 0)
- break;
- }
-
- if (!*cp) {
- mutex_exit(&_ii_cluster_mutex);
- return (DSW_ECNOTFOUND);
- }
-
- found = 1;
- last = 0;
- while (found && !last) {
- found = 0;
-
- mutex_enter(&_ii_info_mutex);
- for (np = &(*cp)->lst_start; *np; np = &((*np)->lst_next)) {
- ip = (*np)->lst_ip;
-
- if (ip->bi_disabled)
- continue;
-
- found++;
-
- ip->bi_disabled = 1;
- if (NSHADOWS(ip) && (ip->bi_master == ip)) {
- ip->bi_flags &= (~DSW_COPYING);
- ip->bi_state |= DSW_MULTIMST;
- }
- mutex_exit(&_ii_info_mutex);
-
- xnp = *np;
- *np = (*np)->lst_next;
- kmem_free(xnp, sizeof (_ii_lstinfo_t));
- ip->bi_cluster = NULL;
-
- (void) _ii_suspend_vol(ip);
- break;
- }
- if (found == 0)
- mutex_exit(&_ii_info_mutex);
- else if (!(*cp)->lst_start) {
- xcp = *cp;
- *cp = (*cp)->lst_next;
- kmem_free(xcp, sizeof (_ii_lsthead_t));
- last = 1;
- }
- }
- mutex_exit(&_ii_cluster_mutex);
-
- return (0);
-}
-
-/*
- * _ii_shutdown
- * System is shutting down, so all shadowed volumes are suspended.
- *
- * This always succeeds, so always returns 0.
- */
-
-/* ARGSUSED */
-
-int
-_ii_shutdown(intptr_t arg, int *rvp)
-{
- _ii_info_t **xip, *ip;
- int found;
-
- *rvp = 0;
-
- _ii_shutting_down = 1;
-
- /* Go through the list until only disabled entries are found */
-
- found = 1;
- while (found) {
- found = 0;
-
- mutex_enter(&_ii_info_mutex);
- for (xip = &_ii_info_top; *xip; xip = &(*xip)->bi_next) {
- ip = *xip;
- if (ip->bi_disabled) {
- /* Also covers not fully configured yet */
- continue;
- }
- found++;
-
- ip->bi_disabled = 1;
- mutex_exit(&_ii_info_mutex);
-
- (void) _ii_suspend_vol(ip);
-
- break;
- }
- if (found == 0)
- mutex_exit(&_ii_info_mutex);
- }
-
- _ii_shutting_down = 0;
-
- return (0);
-}
-
-/*
- * _ii_suspend
- * Suspend an InstantImage, saving its state to allow a subsequent resume.
- *
- * Calling/Exit State:
- * Returns 0 if the pair was suspended. Otherwise an error code
- * is returned and any additional error information is copied
- * out to the user.
- */
-
-/* ARGSUSED */
-
-int
-_ii_suspend(intptr_t arg, int ilp32, int *rvp)
-{
- dsw_ioctl_t uparms;
- dsw_ioctl32_t uparms32;
- _ii_info_t *ip;
- int rc;
- spcs_s_info_t kstatus;
-
- *rvp = 0;
-
- if (ilp32) {
- if (copyin((void *)arg, &uparms32, sizeof (uparms32)) < 0)
- return (EFAULT);
- II_TAIL_COPY(uparms, uparms32, shadow_vol, dsw_ioctl_t);
- uparms.status = (spcs_s_info_t)uparms32.status;
- } else if (copyin((void *)arg, &uparms, sizeof (uparms)) < 0)
- return (EFAULT);
-
- kstatus = spcs_s_kcreate();
- if (kstatus == NULL)
- return (ENOMEM);
-
- if (!uparms.shadow_vol[0])
- return (spcs_s_ocopyoutf(&kstatus, uparms.status, DSW_EEMPTY));
-
- if ((uparms.flags & CV_IS_CLUSTER) != 0) {
- rc = _ii_suspend_cluster(uparms.shadow_vol);
- } else {
- mutex_enter(&_ii_info_mutex);
- ip = _ii_find_set(uparms.shadow_vol);
- if (ip == NULL) {
- mutex_exit(&_ii_info_mutex);
- return (spcs_s_ocopyoutf(&kstatus, uparms.status,
- DSW_ENOTFOUND));
- }
-
- ip->bi_disabled = 1;
- if (NSHADOWS(ip) && (ip->bi_master == ip)) {
- ip->bi_flags &= (~DSW_COPYING);
- ip->bi_state |= DSW_MULTIMST;
- }
- mutex_exit(&_ii_info_mutex);
-
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
-
- rc = _ii_suspend_vol(ip);
- }
-
- return (spcs_s_ocopyoutf(&kstatus, uparms.status, rc));
-}
-
-
-/*
- * _ii_abort
- * Stop any copying process for shadow.
- *
- * Calling/Exit State:
- * Returns 0 if the abort succeeded. Otherwise an error code
- * is returned and any additional error information is copied
- * out to the user.
- */
-
-/* ARGSUSED */
-
-int
-_ii_abort(intptr_t arg, int ilp32, int *rvp)
-{
- dsw_ioctl_t uabort;
- dsw_ioctl32_t uabort32;
- _ii_info_t *ip;
- int rc;
- spcs_s_info_t kstatus;
-
- if (ilp32) {
- if (copyin((void *)arg, &uabort32, sizeof (uabort32)) < 0)
- return (EFAULT);
- II_TAIL_COPY(uabort, uabort32, shadow_vol, dsw_ioctl_t);
- uabort.status = (spcs_s_info_t)uabort32.status;
- } else if (copyin((void *)arg, &uabort, sizeof (uabort)) < 0)
- return (EFAULT);
-
- kstatus = spcs_s_kcreate();
- if (kstatus == NULL)
- return (ENOMEM);
-
- if (!uabort.shadow_vol[0])
- return (spcs_s_ocopyoutf(&kstatus, uabort.status, DSW_EEMPTY));
-
- mutex_enter(&_ii_info_mutex);
- ip = _ii_find_set(uabort.shadow_vol);
- mutex_exit(&_ii_info_mutex);
- if (ip == NULL)
- return (spcs_s_ocopyoutf(&kstatus, uabort.status,
- DSW_ENOTFOUND));
-
- mutex_exit(&ip->bi_mutex);
-
- rc = _ii_stopcopy(ip);
-
- mutex_enter(&ip->bi_mutex);
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
-
- return (spcs_s_ocopyoutf(&kstatus, uabort.status, rc));
-}
-
-
-/*
- * _ii_segment
- * Copy out II pair bitmaps (cpy, shd, idx) in segments
- *
- * Calling/Exit State:
- * Returns 0 if the operation succeeded. Otherwise an error code
- * is returned and any additional error information is copied
- * out to the user.
- *
- */
-int
-_ii_segment(intptr_t arg, int ilp32, int *rvp)
-{
- dsw_segment_t usegment;
- dsw_segment32_t usegment32;
- _ii_info_t *ip;
- int rc, size;
- spcs_s_info_t kstatus;
- int32_t bi_idxfba;
-
- *rvp = 0;
-
- if (ilp32) {
- if (copyin((void *)arg, &usegment32, sizeof (usegment32)))
- return (EFAULT);
- usegment.status = (spcs_s_info_t)usegment32.status;
- bcopy(usegment32.shadow_vol, usegment.shadow_vol, DSW_NAMELEN);
- usegment.seg_number = (unsigned)usegment32.seg_number;
- usegment.shd_bitmap =
- (unsigned char *)(unsigned long)usegment32.shd_bitmap;
- usegment.shd_size = usegment32.shd_size;
- usegment.cpy_bitmap =
- (unsigned char *)(unsigned long)usegment32.cpy_bitmap;
- usegment.cpy_size = usegment32.cpy_size;
- usegment.idx_bitmap =
- (unsigned char *)(unsigned long)usegment32.idx_bitmap;
- usegment.idx_size = usegment32.idx_size;
- } else if (copyin((void *)arg, &usegment, sizeof (usegment)))
- return (EFAULT);
-
- kstatus = spcs_s_kcreate();
- if (kstatus == NULL)
- return (ENOMEM);
-
- if (usegment.shadow_vol[0]) {
- mutex_enter(&_ii_info_mutex);
- ip = _ii_find_set(usegment.shadow_vol);
- mutex_exit(&_ii_info_mutex);
- if (ip == NULL)
- return (spcs_s_ocopyoutf(&kstatus, usegment.status,
- DSW_ENOTFOUND));
- } else
- return (spcs_s_ocopyoutf(&kstatus, usegment.status,
- DSW_EEMPTY));
-
- mutex_exit(&ip->bi_mutex);
-
- size = ((((ip->bi_size + (DSW_SIZE-1))
- / DSW_SIZE) + (DSW_BITS-1))) / DSW_BITS;
- bi_idxfba = ip->bi_copyfba + (ip->bi_copyfba - ip->bi_shdfba);
- if (((nsc_size_t)usegment.seg_number > DSW_BM_FBA_LEN(ip->bi_size)) ||
- (usegment.shd_size > size) ||
- (usegment.cpy_size > size) ||
- (!(ip->bi_flags & DSW_GOLDEN) && (usegment.idx_size > size*32))) {
- _ii_ioctl_done(ip);
- return (spcs_s_ocopyoutf(&kstatus, usegment.status,
- DSW_EMISMATCH));
- }
-
- if ((rc = _ii_rsrv_devs(ip, BMP, II_INTERNAL)) != 0) {
- mutex_enter(&ip->bi_mutex);
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- spcs_s_add(kstatus, rc);
- return (spcs_s_ocopyoutf(&kstatus, usegment.status,
- DSW_ERSRVFAIL));
- }
-
- if (usegment.shd_bitmap && usegment.shd_size > 0)
- rc = II_CO_BMP(ip, ip->bi_shdfba+usegment.seg_number,
- usegment.shd_bitmap, usegment.shd_size);
- if (rc == 0 && usegment.cpy_bitmap && usegment.cpy_size > 0)
- rc = II_CO_BMP(ip, ip->bi_copyfba+usegment.seg_number,
- usegment.cpy_bitmap, usegment.cpy_size);
- if (!(ip->bi_flags & DSW_GOLDEN)) {
- if (rc == 0 && usegment.idx_bitmap && usegment.idx_size > 0)
- rc = II_CO_BMP(ip, bi_idxfba+usegment.seg_number*32,
- usegment.idx_bitmap, usegment.idx_size);
- }
-
- _ii_rlse_devs(ip, BMP);
- mutex_enter(&ip->bi_mutex);
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- if (rc) {
- spcs_s_add(kstatus, rc);
- return (spcs_s_ocopyoutf(&kstatus, usegment.status, DSW_EIO));
- }
-
- spcs_s_kfree(kstatus);
- return (0);
-}
-
-
-/*
- * _ii_bitmap
- * Copy out II pair bitmaps to user program
- *
- * Calling/Exit State:
- * Returns 0 if the operation succeeded. Otherwise an error code
- * is returned and any additional error information is copied
- * out to the user.
- */
-
-int
-_ii_bitmap(intptr_t arg, int ilp32, int *rvp)
-{
- dsw_bitmap_t ubitmap;
- dsw_bitmap32_t ubitmap32;
- _ii_info_t *ip;
- int rc;
- spcs_s_info_t kstatus;
-
- *rvp = 0;
-
- if (ilp32) {
- if (copyin((void *)arg, &ubitmap32, sizeof (ubitmap32)))
- return (EFAULT);
- ubitmap.status = (spcs_s_info_t)ubitmap32.status;
- bcopy(ubitmap32.shadow_vol, ubitmap.shadow_vol, DSW_NAMELEN);
- ubitmap.shd_bitmap =
- (unsigned char *)(unsigned long)ubitmap32.shd_bitmap;
- ubitmap.shd_size = ubitmap32.shd_size;
- ubitmap.copy_bitmap =
- (unsigned char *)(unsigned long)ubitmap32.copy_bitmap;
- ubitmap.copy_size = ubitmap32.copy_size;
- } else if (copyin((void *)arg, &ubitmap, sizeof (ubitmap)))
- return (EFAULT);
-
- kstatus = spcs_s_kcreate();
- if (kstatus == NULL)
- return (ENOMEM);
-
- if (!ubitmap.shadow_vol[0])
- return (spcs_s_ocopyoutf(&kstatus, ubitmap.status, DSW_EEMPTY));
-
- mutex_enter(&_ii_info_mutex);
- ip = _ii_find_set(ubitmap.shadow_vol);
- mutex_exit(&_ii_info_mutex);
- if (ip == NULL)
- return (spcs_s_ocopyoutf(&kstatus, ubitmap.status,
- DSW_ENOTFOUND));
-
- mutex_exit(&ip->bi_mutex);
-
- if ((rc = _ii_rsrv_devs(ip, BMP, II_INTERNAL)) != 0) {
- mutex_enter(&ip->bi_mutex);
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- spcs_s_add(kstatus, rc);
- return (spcs_s_ocopyoutf(&kstatus, ubitmap.status,
- DSW_ERSRVFAIL));
- }
-
- if (ubitmap.shd_bitmap && ubitmap.shd_size > 0)
- rc = II_CO_BMP(ip, ip->bi_shdfba, ubitmap.shd_bitmap,
- ubitmap.shd_size);
- if (rc == 0 && ubitmap.copy_bitmap && ubitmap.copy_size > 0)
- rc = II_CO_BMP(ip, ip->bi_copyfba, ubitmap.copy_bitmap,
- ubitmap.copy_size);
- _ii_rlse_devs(ip, BMP);
- mutex_enter(&ip->bi_mutex);
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- if (rc) {
- spcs_s_add(kstatus, rc);
- return (spcs_s_ocopyoutf(&kstatus, ubitmap.status, DSW_EIO));
- }
-
- spcs_s_kfree(kstatus);
-
- return (0);
-}
-
-/*
- * _ii_export
- * Exports the shadow volume
- *
- * Calling/Exit State:
- * Returns 0 if the shadow was exported. Otherwise an error code
- * is returned and any additional error information is copied
- * out to the user.
- *
- * Description:
- */
-
-int
-_ii_export(intptr_t arg, int ilp32, int *rvp)
-{
- dsw_ioctl_t uparms;
- dsw_ioctl32_t uparms32;
- _ii_info_t *ip;
- nsc_fd_t *fd;
- int rc = 0;
- spcs_s_info_t kstatus;
-
- *rvp = 0;
-
- if (ilp32) {
- if (copyin((void *)arg, &uparms32, sizeof (uparms32)) < 0)
- return (EFAULT);
- II_TAIL_COPY(uparms, uparms32, shadow_vol, dsw_ioctl_t);
- uparms.status = (spcs_s_info_t)uparms32.status;
- } else if (copyin((void *)arg, &uparms, sizeof (uparms)) < 0)
- return (EFAULT);
-
- kstatus = spcs_s_kcreate();
- if (kstatus == NULL)
- return (ENOMEM);
-
- if (!uparms.shadow_vol[0])
- return (spcs_s_ocopyoutf(&kstatus, uparms.status, DSW_EEMPTY));
-
- mutex_enter(&_ii_info_mutex);
- ip = _ii_find_set(uparms.shadow_vol);
- mutex_exit(&_ii_info_mutex);
- if (ip == NULL)
- return (spcs_s_ocopyoutf(&kstatus, uparms.status,
- DSW_ENOTFOUND));
-
- if ((ip->bi_flags & DSW_GOLDEN) == 0 ||
- ((ip->bi_flags & (DSW_COPYING|DSW_SHDEXPORT|DSW_SHDIMPORT)) != 0)) {
- /*
- * Cannot export a dependent copy or while still copying or
- * the shadow is already in an exported state
- */
- rc = ip->bi_flags & (DSW_SHDEXPORT|DSW_SHDIMPORT)
- ? DSW_EALREADY : DSW_EDEPENDENCY;
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- return (spcs_s_ocopyoutf(&kstatus, uparms.status, rc));
- }
- if ((rc = _ii_rsrv_devs(ip, BMP, II_INTERNAL)) != 0) {
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- spcs_s_add(kstatus, rc);
- return (spcs_s_ocopyoutf(&kstatus, uparms.status,
- DSW_ERSRVFAIL));
- }
- II_FLAG_SET(DSW_SHDEXPORT, ip);
-
- mutex_exit(&ip->bi_mutex);
-
- /* this rw_enter forces us to drain all active IO */
- rw_enter(&ip->bi_linkrw, RW_WRITER);
- rw_exit(&ip->bi_linkrw);
-
- mutex_enter(&ip->bi_mutex);
-
- _ii_rlse_devs(ip, BMP);
-
- /* Shut shadow volume. */
- if (ip->bi_shdfd) {
- if (ip->bi_shdrsrv) {
- nsc_release(ip->bi_shdfd);
- ip->bi_shdrsrv = NULL;
- }
- fd = ip->bi_shdfd;
- ip->bi_shdfd = NULL;
- mutex_exit(&ip->bi_mutex);
- (void) nsc_close(fd);
- mutex_enter(&ip->bi_mutex);
- }
-
- if (ip->bi_shdrfd) {
- if (ip->bi_shdrrsrv) {
- nsc_release(ip->bi_shdrfd);
- ip->bi_shdrrsrv = NULL;
- }
- fd = ip->bi_shdrfd;
- ip->bi_shdrfd = NULL;
- mutex_exit(&ip->bi_mutex);
- (void) nsc_close(fd);
- mutex_enter(&ip->bi_mutex);
- }
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
-
- (void) _ii_reserve_begin(ip);
- if (ip->bi_shd_tok) {
- (void) _ii_unregister_path(ip->bi_shd_tok, 0, "shadow");
- ip->bi_shd_tok = NULL;
- }
-
- if (ip->bi_shdr_tok) {
- (void) _ii_unregister_path(ip->bi_shdr_tok, 0,
- "raw shadow");
- ip->bi_shdr_tok = NULL;
- }
- _ii_reserve_end(ip);
-
- spcs_s_kfree(kstatus);
-
- return (0);
-}
-
-/*
- * _ii_join
- * Rejoins the shadow volume
- *
- * Calling/Exit State:
- * Returns 0 if the shadow was exported. Otherwise an error code
- * is returned and any additional error information is copied
- * out to the user.
- *
- * Description:
- */
-
-int
-_ii_join(intptr_t arg, int ilp32, int *rvp)
-{
- dsw_bitmap_t ubitmap;
- dsw_bitmap32_t ubitmap32;
- _ii_info_t *ip;
- uint64_t bm_size;
- int rc = 0;
- int rtype = 0;
- spcs_s_info_t kstatus;
-
- *rvp = 0;
-
- if (ilp32) {
- if (copyin((void *)arg, &ubitmap32, sizeof (ubitmap32)) < 0)
- return (EFAULT);
- II_TAIL_COPY(ubitmap, ubitmap32, shadow_vol, dsw_bitmap_t);
- ubitmap.status = (spcs_s_info_t)ubitmap32.status;
- ubitmap.shd_bitmap =
- (unsigned char *)(unsigned long)ubitmap32.shd_bitmap;
- ubitmap.shd_size = ubitmap32.shd_size;
- } else if (copyin((void *)arg, &ubitmap, sizeof (ubitmap)) < 0)
- return (EFAULT);
-
- kstatus = spcs_s_kcreate();
- if (kstatus == NULL)
- return (ENOMEM);
-
- if (!ubitmap.shadow_vol[0])
- return (spcs_s_ocopyoutf(&kstatus, ubitmap.status, DSW_EEMPTY));
-
- mutex_enter(&_ii_info_mutex);
- ip = _ii_find_set(ubitmap.shadow_vol);
- mutex_exit(&_ii_info_mutex);
- if (ip == NULL)
- return (spcs_s_ocopyoutf(&kstatus, ubitmap.status,
- DSW_ENOTFOUND));
-
- /*
- * Check that group has shadow exported.
- */
- if ((ip->bi_flags & DSW_SHDEXPORT) == 0) {
- /*
- * Cannot join if the shadow isn't exported.
- */
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- return (spcs_s_ocopyoutf(&kstatus, ubitmap.status,
- DSW_ENOTEXPORTED));
- }
- /* check bitmap is at least large enough for master volume size */
- bm_size = FBA_SIZE(DSW_BM_FBA_LEN(ip->bi_size));
- if (ubitmap.shd_size < bm_size) {
- /* bitmap is to small */
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- return (spcs_s_ocopyoutf(&kstatus, ubitmap.status,
- DSW_EINVALBMP));
- }
- /* read in bitmap and or with differences bitmap */
- rtype = BMP;
- if ((rc = _ii_rsrv_devs(ip, rtype, II_INTERNAL)) != 0) {
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- spcs_s_add(kstatus, rc);
- return (spcs_s_ocopyoutf(&kstatus, ubitmap.status,
- DSW_ERSRVFAIL));
- }
- rc = II_CI_BMP(ip, ip->bi_shdfba, ubitmap.shd_bitmap,
- ubitmap.shd_size);
- /* open up shadow */
- if ((rc = ii_open_shadow(ip, ip->bi_keyname)) != 0) {
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- spcs_s_add(kstatus, rc);
- _ii_rlse_devs(ip, rtype);
- return (spcs_s_ocopyoutf(&kstatus, ubitmap.status, DSW_EOPEN));
- }
- ii_register_shd(ip);
- if (!rc)
- II_FLAG_CLR(DSW_SHDEXPORT, ip);
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- _ii_rlse_devs(ip, rtype);
-
- if (rc) {
- spcs_s_add(kstatus, rc);
- return (spcs_s_ocopyoutf(&kstatus, ubitmap.status, DSW_EIO));
- }
-
- spcs_s_kfree(kstatus);
-
- return (0);
-}
-
-
-/*
- * _ii_ocreate
- * Configures a volume suitable for use as an overflow volume.
- *
- * Calling/Exit State:
- * Returns 0 if the volume was configured successfully. Otherwise
- * an error code is returned and any additional error information
- * is copied out to the user.
- *
- * Description:
- */
-
-int
-_ii_ocreate(intptr_t arg, int ilp32, int *rvp)
-{
- dsw_ioctl_t uioctl;
- dsw_ioctl32_t uioctl32;
- _ii_overflow_t ov;
- _ii_overflow_t *op = &ov;
- int rc = 0;
- nsc_fd_t *fd;
- nsc_iodev_t *iodev;
- nsc_size_t vol_size;
- char *overflow_vol;
- spcs_s_info_t kstatus;
-
- *rvp = 0;
-
- if (ilp32) {
- if (copyin((void *)arg, &uioctl32, sizeof (uioctl32)) < 0)
- return (EFAULT);
- II_TAIL_COPY(uioctl, uioctl32, shadow_vol, dsw_ioctl_t);
- uioctl.status = (spcs_s_info_t)uioctl32.status;
- } else if (copyin((void *)arg, &uioctl, sizeof (uioctl)) < 0)
- return (EFAULT);
-
- overflow_vol = uioctl.shadow_vol;
- kstatus = spcs_s_kcreate();
- if (kstatus == NULL)
- return (ENOMEM);
-
- if (!overflow_vol[0])
- return (spcs_s_ocopyoutf(&kstatus, uioctl.status, DSW_EEMPTY));
-
- if (ii_volume(overflow_vol, 0) != NONE)
- return (spcs_s_ocopyoutf(&kstatus, uioctl.status, DSW_EINUSE));
-
- fd = nsc_open(overflow_vol,
- NSC_IIR_ID|NSC_FILE|NSC_RDWR, NULL, (blind_t)&(iodev), &rc);
- if (!fd)
- fd = nsc_open(uioctl.shadow_vol,
- NSC_IIR_ID|NSC_DEVICE|NSC_RDWR, NULL,
- (blind_t)&(iodev), &rc);
- if (fd == NULL) {
- spcs_s_add(kstatus, rc);
- return (spcs_s_ocopyoutf(&kstatus, uioctl.status, DSW_EIO));
- }
- if ((rc = nsc_reserve(fd, 0)) != 0) {
- spcs_s_add(kstatus, rc);
- (void) nsc_close(fd);
- return (spcs_s_ocopyoutf(&kstatus, uioctl.status,
- DSW_ERSRVFAIL));
- }
- /* setup magic number etc; */
- rc = nsc_partsize(fd, &vol_size);
- if (rc) {
- spcs_s_add(kstatus, rc);
- (void) nsc_close(fd);
- return (spcs_s_ocopyoutf(&kstatus, uioctl.status, DSW_EIO));
- }
- op->ii_hmagic = II_OMAGIC;
- /* take 1 off as chunk 0 contains header */
- op->ii_nchunks = (vol_size / DSW_SIZE) -1;
- op->ii_drefcnt = 0;
- op->ii_used = 1; /* we have used the header */
- op->ii_unused = op->ii_nchunks - op->ii_used;
- op->ii_freehead = II_NULLNODE;
- op->ii_hversion = OV_HEADER_VERSION;
- op->ii_flags = 0;
- op->ii_urefcnt = 0;
- (void) strncpy(op->ii_volname, uioctl.shadow_vol, DSW_NAMELEN);
- rc = _ii_nsc_io(0, KS_NA, fd, NSC_WRBUF, II_OHEADER_FBA,
- (unsigned char *)&op->ii_do, sizeof (op->ii_do));
- (void) nsc_release(fd);
- (void) nsc_close(fd);
- if (rc) {
- spcs_s_add(kstatus, rc);
- return (spcs_s_ocopyoutf(&kstatus, uioctl.status, DSW_EIO));
- }
-
- spcs_s_kfree(kstatus);
-
- return (0);
-}
-
-
-/*
- * _ii_oattach
- * Attaches the volume in the "bitmap_vol" field as an overflow volume.
- *
- * Calling/Exit State:
- * Returns 0 if the volume was attached. Fails if the shadow group
- * is of the wrong type (eg independent) or already has an overflow
- * volume attached.
- *
- * Description:
- */
-
-int
-_ii_oattach(intptr_t arg, int ilp32, int *rvp)
-{
- dsw_config_t uconfig;
- dsw_config32_t uconfig32;
- _ii_info_t *ip;
- int rc = 0;
- int rtype = 0;
- ii_header_t *bm_header;
- nsc_buf_t *tmp = NULL;
- spcs_s_info_t kstatus;
-
- *rvp = 0;
-
- if (ilp32) {
- if (copyin((void *)arg, &uconfig32, sizeof (uconfig32)) < 0)
- return (EFAULT);
- II_TAIL_COPY(uconfig, uconfig32, shadow_vol, dsw_config_t);
- uconfig.status = (spcs_s_info_t)uconfig32.status;
- } else if (copyin((void *)arg, &uconfig, sizeof (uconfig)) < 0)
- return (EFAULT);
-
- kstatus = spcs_s_kcreate();
- if (kstatus == NULL)
- return (ENOMEM);
-
- if (!uconfig.shadow_vol[0])
- return (spcs_s_ocopyoutf(&kstatus, uconfig.status, DSW_EEMPTY));
-
- switch (ii_volume(uconfig.bitmap_vol, 0)) {
- case NONE:
- case OVR:
- break;
- default:
- return (spcs_s_ocopyoutf(&kstatus, uconfig.status, DSW_EINUSE));
- }
- mutex_enter(&_ii_info_mutex);
- ip = _ii_find_set(uconfig.shadow_vol);
- mutex_exit(&_ii_info_mutex);
- if (ip == NULL)
- return (spcs_s_ocopyoutf(&kstatus, uconfig.status,
- DSW_ENOTFOUND));
-
- /* check shadow doesn't already have an overflow volume */
- if (ip->bi_overflow) {
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- return (spcs_s_ocopyoutf(&kstatus, uconfig.status,
- DSW_EALREADY));
- }
- /* check shadow is mapped so can have an overflow */
- if ((ip->bi_flags&DSW_TREEMAP) == 0) {
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- return (spcs_s_ocopyoutf(&kstatus, uconfig.status,
- DSW_EWRONGTYPE));
- }
- rtype = BMP;
- if ((rc = _ii_rsrv_devs(ip, rtype, II_INTERNAL)) != 0) {
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- spcs_s_add(kstatus, rc);
- return (spcs_s_ocopyoutf(&kstatus, uconfig.status,
- DSW_ERSRVFAIL));
- }
- /* attach volume */
- if ((rc = ii_overflow_attach(ip, uconfig.bitmap_vol, 1)) != 0) {
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- _ii_rlse_devs(ip, rtype);
- return (spcs_s_ocopyoutf(&kstatus, uconfig.status, rc));
- }
-
- /* re-write header so shadow can be restarted with overflow volume */
-
- bm_header = _ii_bm_header_get(ip, &tmp);
- if (bm_header == NULL) {
- /* detach volume */
- ii_overflow_free(ip, RECLAIM);
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- _ii_rlse_devs(ip, rtype);
- return (spcs_s_ocopyoutf(&kstatus, uconfig.status,
- DSW_EHDRBMP));
- }
- (void) strncpy(bm_header->overflow_vol, uconfig.bitmap_vol,
- DSW_NAMELEN);
- (void) _ii_bm_header_put(bm_header, ip, tmp);
- _ii_rlse_devs(ip, rtype);
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
-
- spcs_s_kfree(kstatus);
-
- return (0);
-}
-
-
-/*
- * _ii_odetach
- * Breaks the link with the overflow volume.
- *
- * Calling/Exit State:
- * Returns 0 if the overflow volume was detached. Otherwise an error code
- * is returned and any additional error information is copied
- * out to the user.
- *
- * Description:
- */
-
-int
-_ii_odetach(intptr_t arg, int ilp32, int *rvp)
-{
- dsw_bitmap_t ubitmap;
- dsw_bitmap32_t ubitmap32;
- _ii_info_t *ip;
- int rc = 0;
- int rtype = 0;
- ii_header_t *bm_header;
- nsc_buf_t *tmp = NULL;
- spcs_s_info_t kstatus;
-
- *rvp = 0;
-
- if (ilp32) {
- if (copyin((void *)arg, &ubitmap32, sizeof (ubitmap32)) < 0)
- return (EFAULT);
- II_TAIL_COPY(ubitmap, ubitmap32, shadow_vol, dsw_bitmap_t);
- ubitmap.status = (spcs_s_info_t)ubitmap32.status;
- } else if (copyin((void *)arg, &ubitmap, sizeof (ubitmap)) < 0)
- return (EFAULT);
-
- kstatus = spcs_s_kcreate();
- if (kstatus == NULL)
- return (ENOMEM);
-
- if (!ubitmap.shadow_vol[0])
- return (spcs_s_ocopyoutf(&kstatus, ubitmap.status, DSW_EEMPTY));
-
- mutex_enter(&_ii_info_mutex);
- ip = _ii_find_set(ubitmap.shadow_vol);
- mutex_exit(&_ii_info_mutex);
- if (ip == NULL)
- return (spcs_s_ocopyoutf(&kstatus, ubitmap.status,
- DSW_ENOTFOUND));
-
- if ((ip->bi_flags&DSW_VOVERFLOW) != 0) {
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- return (spcs_s_ocopyoutf(&kstatus, ubitmap.status,
- DSW_EODEPENDENCY));
- }
- rtype = BMP;
- if ((rc = _ii_rsrv_devs(ip, rtype, II_INTERNAL)) != 0) {
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- spcs_s_add(kstatus, rc);
- return (spcs_s_ocopyoutf(&kstatus, ubitmap.status,
- DSW_ERSRVFAIL));
- }
- ii_overflow_free(ip, RECLAIM);
- /* re-write header to break link with overflow volume */
-
- bm_header = _ii_bm_header_get(ip, &tmp);
- if (bm_header == NULL) {
- _ii_rlse_devs(ip, rtype);
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- return (spcs_s_ocopyoutf(&kstatus, ubitmap.status,
- DSW_EHDRBMP));
- }
- bzero(bm_header->overflow_vol, DSW_NAMELEN);
- (void) _ii_bm_header_put(bm_header, ip, tmp);
-
- _ii_rlse_devs(ip, rtype);
- _ii_ioctl_done(ip);
-
- mutex_exit(&ip->bi_mutex);
- if (rc) {
- spcs_s_add(kstatus, rc);
- return (spcs_s_ocopyoutf(&kstatus, ubitmap.status, DSW_EIO));
- }
-
- spcs_s_kfree(kstatus);
-
- --iigkstat.assoc_over.value.ul;
-
- return (0);
-}
-
-
-/*
- * _ii_gc_list
- * Returns a list of all lists, or all entries in a list
- *
- */
-int
-_ii_gc_list(intptr_t arg, int ilp32, int *rvp, kmutex_t *mutex,
- _ii_lsthead_t *lst)
-{
- dsw_aioctl_t ulist;
- dsw_aioctl32_t ulist32;
- size_t name_offset;
- int i;
- spcs_s_info_t kstatus;
- char *carg = (char *)arg;
- uint64_t hash;
- _ii_lsthead_t *cp;
- _ii_lstinfo_t *np;
-
- *rvp = 0;
- name_offset = offsetof(dsw_aioctl_t, shadow_vol[0]);
- if (ilp32) {
- if (copyin((void *) arg, &ulist32, sizeof (ulist32)) < 0)
- return (EFAULT);
- II_TAIL_COPY(ulist, ulist32, flags, dsw_aioctl_t);
- ulist.status = (spcs_s_info_t)ulist32.status;
- name_offset = offsetof(dsw_aioctl32_t, shadow_vol[0]);
- } else if (copyin((void *) arg, &ulist, sizeof (ulist)) < 0)
- return (EFAULT);
-
- kstatus = spcs_s_kcreate();
- if (kstatus == NULL)
- return (ENOMEM);
-
- mutex_enter(mutex);
- if (ulist.shadow_vol[ 0 ] != 0) {
- /* search for specific list */
- hash = nsc_strhash(ulist.shadow_vol);
- for (cp = lst; cp; cp = cp->lst_next) {
- if ((hash == cp->lst_hash) && strncmp(ulist.shadow_vol,
- cp->lst_name, DSW_NAMELEN) == 0) {
- break;
- }
- }
- if (cp) {
- for (i = 0, np = cp->lst_start; i < ulist.count && np;
- np = np->lst_next, carg += DSW_NAMELEN, i++) {
- if (copyout(np->lst_ip->bi_keyname,
- carg + name_offset, DSW_NAMELEN)) {
- mutex_exit(mutex);
- return (spcs_s_ocopyoutf(&kstatus,
- ulist.status, EFAULT));
- }
- }
- } else {
- i = 0;
- }
- } else {
- /* return full list */
- for (i = 0, cp = lst; i < ulist.count && cp;
- carg += DSW_NAMELEN, i++, cp = cp->lst_next) {
- if (copyout(cp->lst_name, carg + name_offset,
- DSW_NAMELEN)) {
- mutex_exit(mutex);
- return (spcs_s_ocopyoutf(&kstatus, ulist.status,
- EFAULT));
- }
- }
- }
- mutex_exit(mutex);
- ulist32.count = ulist.count = i;
-
- if (ilp32) {
- if (copyout(&ulist32, (void *) arg, name_offset))
- return (EFAULT);
- } else {
- if (copyout(&ulist, (void*) arg, name_offset))
- return (EFAULT);
- }
-
- return (spcs_s_ocopyoutf(&kstatus, ulist.status, 0));
-}
-
-/*
- * _ii_olist
- * Breaks the link with the overflow volume.
- *
- * Calling/Exit State:
- * Returns 0 if the overflow volume was detached. Otherwise an error code
- * is returned and any additional error information is copied
- * out to the user.
- *
- * Description:
- */
-
-int
-_ii_olist(intptr_t arg, int ilp32, int *rvp)
-{
- dsw_aioctl_t ulist;
- dsw_aioctl32_t ulist32;
- _ii_overflow_t *op;
- size_t name_offset;
- int rc = 0;
- int i;
- char *carg = (char *)arg;
- spcs_s_info_t kstatus;
-
- *rvp = 0;
-
- name_offset = offsetof(dsw_aioctl_t, shadow_vol[0]);
- if (ilp32) {
- if (copyin((void *)arg, &ulist32, sizeof (ulist32)) < 0)
- return (EFAULT);
- II_TAIL_COPY(ulist, ulist32, flags, dsw_aioctl_t);
- ulist.status = (spcs_s_info_t)ulist32.status;
- name_offset = offsetof(dsw_aioctl32_t, shadow_vol[0]);
- } else if (copyin((void *)arg, &ulist, sizeof (ulist)) < 0)
- return (EFAULT);
-
- kstatus = spcs_s_kcreate();
- if (kstatus == NULL)
- return (ENOMEM);
-
- i = 0;
-
- mutex_enter(&_ii_overflow_mutex);
- for (op = _ii_overflow_top; i < ulist.count && op;
- carg += DSW_NAMELEN) {
- if (copyout(op->ii_volname, carg+name_offset, DSW_NAMELEN)) {
- mutex_exit(&_ii_overflow_mutex);
- return (spcs_s_ocopyoutf(&kstatus, ulist.status,
- EFAULT));
- }
- i++;
- op = op->ii_next;
- }
- mutex_exit(&_ii_overflow_mutex);
- ulist32.count = ulist.count = i;
- /* return count of items listed to user */
- if (ilp32) {
- if (copyout(&ulist32, (void *)arg, name_offset))
- return (EFAULT);
- } else {
- if (copyout(&ulist, (void *)arg, name_offset))
- return (EFAULT);
- }
-
- return (spcs_s_ocopyoutf(&kstatus, ulist.status, rc));
-}
-
-/*
- * _ii_ostat
- * Breaks the link with the overflow volume.
- *
- * Calling/Exit State:
- * Returns 0 if the overflow volume was detached. Otherwise an error code
- * is returned and any additional error information is copied
- * out to the user.
- *
- * Description:
- */
-
-int
-_ii_ostat(intptr_t arg, int ilp32, int *rvp, int is_iost_2)
-{
- dsw_ostat_t ustat;
- dsw_ostat32_t ustat32;
- _ii_overflow_t *op;
- spcs_s_info_t kstatus;
-
- *rvp = 0;
-
- if (ilp32) {
- if (copyin((void *)arg, &ustat32, sizeof (ustat32)) < 0)
- return (EFAULT);
- II_TAIL_COPY(ustat, ustat32, overflow_vol, dsw_ostat_t);
- ustat.status = (spcs_s_info_t)ustat32.status;
- } else if (copyin((void *)arg, &ustat, sizeof (ustat)) < 0)
- return (EFAULT);
-
- kstatus = spcs_s_kcreate();
- if (kstatus == NULL)
- return (ENOMEM);
- if (!ustat.overflow_vol[0])
- return (spcs_s_ocopyoutf(&kstatus, ustat.status, DSW_EEMPTY));
-
- op = _ii_find_overflow(ustat.overflow_vol);
- if (op == NULL)
- return (spcs_s_ocopyoutf(&kstatus, ustat.status,
- DSW_ENOTFOUND));
-
- ustat.nchunks = op->ii_nchunks;
- ustat.used = op->ii_used;
- ustat.unused = op->ii_unused;
- ustat.drefcnt = op->ii_drefcnt;
- ustat.crefcnt = op->ii_crefcnt;
- if (is_iost_2) {
- ustat.hversion = op->ii_hversion;
- ustat.flags = op->ii_flags;
- ustat.hmagic = op->ii_hmagic;
- }
-
- spcs_s_kfree(kstatus);
- if (ilp32) {
- ustat32.nchunks = ustat.nchunks;
- ustat32.used = ustat.used;
- ustat32.unused = ustat.unused;
- ustat32.drefcnt = ustat.drefcnt;
- ustat32.crefcnt = ustat.crefcnt;
- if (is_iost_2) {
- ustat32.hversion = ustat.hversion;
- ustat32.flags = ustat.flags;
- ustat32.hmagic = ustat.hmagic;
- }
- if (copyout(&ustat32, (void *)arg, sizeof (ustat32)))
- return (EFAULT);
- } else {
- if (copyout(&ustat, (void *)arg, sizeof (ustat)))
- return (EFAULT);
- }
- return (0);
-}
-
-/*
- * _ii_move_grp()
- * Move a set from one group to another, possibly creating the new
- * group.
- */
-
-int
-_ii_move_grp(intptr_t arg, int ilp32, int *rvp)
-{
- dsw_movegrp_t umove;
- dsw_movegrp32_t umove32;
- spcs_s_info_t kstatus;
- _ii_info_t *ip;
- int rc = 0;
- nsc_buf_t *tmp;
- ii_header_t *bm_header;
-
- *rvp = 0;
-
- if (ilp32) {
- if (copyin((void *)arg, &umove32, sizeof (umove32)) < 0)
- return (EFAULT);
- II_TAIL_COPY(umove, umove32, shadow_vol, dsw_movegrp_t);
- umove.status = (spcs_s_info_t)umove32.status;
- } else if (copyin((void *)arg, &umove, sizeof (umove)) < 0)
- return (EFAULT);
-
- kstatus = spcs_s_kcreate();
- if (kstatus == NULL)
- return (ENOMEM);
-
- if (!umove.shadow_vol[0])
- return (spcs_s_ocopyoutf(&kstatus, umove.status, DSW_EEMPTY));
-
- mutex_enter(&_ii_info_mutex);
- ip = _ii_find_set(umove.shadow_vol);
- mutex_exit(&_ii_info_mutex);
-
- if (!ip)
- return (spcs_s_ocopyoutf(&kstatus, umove.status,
- DSW_ENOTFOUND));
-
- if (!umove.new_group[0]) {
- /* are we clearing the group association? */
- if (ip->bi_group) {
- DTRACE_PROBE2(_ii_move_grp1, char *, ip->bi_keyname,
- char *, ip->bi_group);
- rc = II_UNLINK_GROUP(ip);
- }
- } else if (!ip->bi_group) {
- rc = II_LINK_GROUP(ip, umove.new_group);
- DTRACE_PROBE2(_ii_move_grp2, char *, ip->bi_keyname,
- char *, ip->bi_group);
- } else {
- /* remove it from one group and add it to the other */
- DTRACE_PROBE3(_ii_move_grp, char *, ip->bi_keyname,
- char *, ip->bi_group, char *, umove.new_group);
- rc = II_UNLINK_GROUP(ip);
- if (!rc)
- rc = II_LINK_GROUP(ip, umove.new_group);
- }
-
- /* ** BEGIN UPDATE BITMAP HEADER ** */
- if ((rc = _ii_rsrv_devs(ip, BMP, II_INTERNAL)) != 0) {
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- spcs_s_add(kstatus, rc);
- return (spcs_s_ocopyoutf(&kstatus, umove.status,
- DSW_ERSRVFAIL));
- }
- bm_header = _ii_bm_header_get(ip, &tmp);
- if (bm_header) {
- (void) strncpy(bm_header->group_name, umove.new_group,
- DSW_NAMELEN);
- (void) _ii_bm_header_put(bm_header, ip, tmp);
- }
- _ii_rlse_devs(ip, BMP);
- /* ** END UPDATE BITMAP HEADER ** */
-
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
-
- return (spcs_s_ocopyoutf(&kstatus, umove.status, rc));
-}
-
-/*
- * _ii_change_tag()
- * Move a set from one group to another, possibly creating the new
- * group.
- */
-
-int
-_ii_change_tag(intptr_t arg, int ilp32, int *rvp)
-{
- dsw_movegrp_t umove;
- dsw_movegrp32_t umove32;
- spcs_s_info_t kstatus;
- _ii_info_t *ip;
- int rc = 0;
- nsc_buf_t *tmp;
- ii_header_t *bm_header;
-
- *rvp = 0;
-
- if (ilp32) {
- if (copyin((void *)arg, &umove32, sizeof (umove32)) < 0)
- return (EFAULT);
- II_TAIL_COPY(umove, umove32, shadow_vol, dsw_movegrp_t);
- umove.status = (spcs_s_info_t)umove32.status;
- } else if (copyin((void *)arg, &umove, sizeof (umove)) < 0)
- return (EFAULT);
-
- kstatus = spcs_s_kcreate();
- if (kstatus == NULL)
- return (ENOMEM);
-
- if (!umove.shadow_vol[0])
- return (spcs_s_ocopyoutf(&kstatus, umove.status, DSW_EEMPTY));
-
- mutex_enter(&_ii_info_mutex);
- ip = _ii_find_set(umove.shadow_vol);
- mutex_exit(&_ii_info_mutex);
-
- if (!ip)
- return (spcs_s_ocopyoutf(&kstatus, umove.status,
- DSW_ENOTFOUND));
-
- if (!umove.new_group[0]) {
- /* are we clearing the group association? */
- if (ip->bi_cluster) {
- DTRACE_PROBE2(_ii_change_tag, char *, ip->bi_keyname,
- char *, ip->bi_cluster);
- rc = II_UNLINK_CLUSTER(ip);
- }
- } else if (!ip->bi_cluster) {
- /* are we adding it to a group for the first time? */
- rc = II_LINK_CLUSTER(ip, umove.new_group);
- DTRACE_PROBE2(_ii_change_tag, char *, ip->bi_keyname,
- char *, ip->bi_cluster);
- } else {
- /* remove it from one group and add it to the other */
- DTRACE_PROBE3(_ii_change_tag_2, char *, ip->bi_keyname,
- char *, ip->bi_cluster, char *, umove.new_group);
- rc = II_UNLINK_CLUSTER(ip);
- if (!rc)
- rc = II_LINK_CLUSTER(ip, umove.new_group);
- }
-
- /* ** BEGIN UPDATE BITMAP HEADER ** */
- if ((rc = _ii_rsrv_devs(ip, BMP, II_INTERNAL)) != 0) {
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- spcs_s_add(kstatus, rc);
- return (spcs_s_ocopyoutf(&kstatus, umove.status,
- DSW_ERSRVFAIL));
- }
- bm_header = _ii_bm_header_get(ip, &tmp);
- if (bm_header) {
- (void) strncpy(bm_header->clstr_name, umove.new_group,
- DSW_NAMELEN);
- (void) _ii_bm_header_put(bm_header, ip, tmp);
- }
- _ii_rlse_devs(ip, BMP);
- /* ** END UPDATE BITMAP HEADER ** */
-
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
-
- return (spcs_s_ocopyoutf(&kstatus, umove.status, rc));
-}
-
-
-/*
- * _ii_spcs_s_ocopyoutf()
- * Wrapper for spcs_s_ocopyoutf() used by _ii_chk_copy() which permits
- * the spcs_s_info_t argument to be NULL. _ii_chk_copy() requires this
- * functionality as it is sometimes called by _ii_control_copy() which
- * has no user context to copy any errors into. At all other times a NULL
- * spcs_s_info_t argument would indicate a bug in the calling function.
- */
-
-static int
-_ii_spcs_s_ocopyoutf(spcs_s_info_t *kstatusp, spcs_s_info_t ustatus, int err)
-{
- if (ustatus)
- return (spcs_s_ocopyoutf(kstatusp, ustatus, err));
- spcs_s_kfree(*kstatusp);
- return (err);
-}
-
-static int
-_ii_chk_copy(_ii_info_t *ip, int flags, spcs_s_info_t *kstatusp, pid_t pid,
- spcs_s_info_t ustatus)
-{
- _ii_info_t *xip;
- int rc;
- int rtype;
-
- if ((ip->bi_flags & DSW_COPYINGP) != 0) {
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- return (_ii_spcs_s_ocopyoutf(kstatusp, ustatus, DSW_ECOPYING));
- }
-
- if (ip->bi_flags & DSW_OFFLINE) {
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- return (_ii_spcs_s_ocopyoutf(kstatusp, ustatus, DSW_EOFFLINE));
- }
-
- if ((ip->bi_flags & (DSW_SHDIMPORT|DSW_SHDEXPORT)) != 0) {
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- return (_ii_spcs_s_ocopyoutf(kstatusp, ustatus,
- DSW_EISEXPORTED));
- }
-
- if ((flags & CV_SHD2MST) == CV_SHD2MST) {
- if ((ip->bi_flags & DSW_COPYINGM) != 0) {
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- return (_ii_spcs_s_ocopyoutf(kstatusp, ustatus,
- DSW_ECOPYING));
- }
- /* check if any sibling shadow is copying towards this master */
- for (xip = ip->bi_head; xip; xip = xip->bi_sibling) {
- if (ip != xip && (xip->bi_flags & DSW_COPYINGS) != 0) {
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- return (_ii_spcs_s_ocopyoutf(kstatusp, ustatus,
- DSW_ECOPYING));
- }
- }
- }
-
- if (((flags & CV_SHD2MST) == 0) &&
- ((ip->bi_flags & DSW_COPYINGS) != 0)) {
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- return (_ii_spcs_s_ocopyoutf(kstatusp, ustatus, DSW_ECOPYING));
- }
-
- if (ip->bi_flags & DSW_TREEMAP) {
- if ((ip->bi_flags & DSW_OVERFLOW) && (flags & CV_SHD2MST)) {
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- return (_ii_spcs_s_ocopyoutf(kstatusp, ustatus,
- DSW_EINCOMPLETE));
- }
- }
-
- /* Assure that no other PID owns this copy/update */
- if (ip->bi_locked_pid == 0) {
- if (flags & CV_LOCK_PID)
- ip->bi_locked_pid = pid;
- } else if (ip->bi_locked_pid != pid) {
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- return (spcs_s_ocopyoutf(kstatusp, ustatus, DSW_EINUSE));
- }
-
- mutex_exit(&ip->bi_mutex);
-
- rtype = MSTR|SHDR|BMP;
- if ((rc = _ii_rsrv_devs(ip, rtype, II_INTERNAL)) != 0) {
- mutex_enter(&ip->bi_mutex);
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- spcs_s_add(*kstatusp, rc);
- return (_ii_spcs_s_ocopyoutf(kstatusp, ustatus,
- DSW_ERSRVFAIL));
- }
-
- if (ii_update_denied(ip, *kstatusp, flags & CV_SHD2MST, 0)) {
- mutex_enter(&ip->bi_mutex);
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- _ii_rlse_devs(ip, rtype);
- return (_ii_spcs_s_ocopyoutf(kstatusp, ustatus,
- DSW_EOPACKAGE));
- }
-
- return (0);
-}
-
-static int
-_ii_do_copy(_ii_info_t *ip, int flags, spcs_s_info_t kstatus, int waitflag)
-{
- int rc = 0;
- int rtype = MSTR|SHDR|BMP;
- _ii_overflow_t *op;
- int quick_update = 0;
-
- waitflag = (waitflag != 0);
- /*
- * a copy of a tree-mapped device must be downgraded to
- * an update.
- */
- if (ip->bi_flags & DSW_TREEMAP)
- flags |= CV_BMP_ONLY;
-
- /*
- * If we want to update the dependent shadow we only need to zero
- * the shadow bitmap.
- */
-
- if (((ip->bi_flags & DSW_GOLDEN) == 0) &&
- (flags & (CV_BMP_ONLY|CV_SHD2MST)) == CV_BMP_ONLY) {
-
- DTRACE_PROBE(DEPENDENT);
-
- /* assign updating time */
- ip->bi_mtime = ddi_get_time();
-
- if (ip->bi_flags & DSW_TREEMAP) {
- DTRACE_PROBE(COMPACT_DEPENDENT);
-
- if (ip->bi_overflow &&
- (ip->bi_overflow->ii_flags & IIO_VOL_UPDATE) == 0) {
- /* attempt to do a quick update */
- quick_update = 1;
- ip->bi_overflow->ii_flags |= IIO_VOL_UPDATE;
- ip->bi_overflow->ii_detachcnt = 1;
- }
-
- rc = ii_tinit(ip);
-
- if (quick_update && ip->bi_overflow) {
- /* clean up */
- ip->bi_overflow->ii_flags &= ~(IIO_VOL_UPDATE);
- ip->bi_overflow->ii_detachcnt = 0;
- }
- }
-
- if (rc == 0)
- rc = II_ZEROBM(ip); /* update copy of shadow */
- if (((op = ip->bi_overflow) != NULL) &&
- (op->ii_hversion >= 1) && (op->ii_hmagic == II_OMAGIC)) {
- mutex_enter(&_ii_overflow_mutex);
- if (ip->bi_flags & DSW_OVRHDRDRTY) {
- mutex_enter(&ip->bi_mutex);
- ip->bi_flags &= ~DSW_OVRHDRDRTY;
- mutex_exit(&ip->bi_mutex);
- ASSERT(op->ii_urefcnt > 0);
- op->ii_urefcnt--;
- }
- if (op->ii_urefcnt == 0) {
- op->ii_flags &= ~IIO_CNTR_INVLD;
- op->ii_unused = op->ii_nchunks - 1;
- }
- mutex_exit(&_ii_overflow_mutex);
- }
- mutex_enter(&ip->bi_mutex);
- II_FLAG_CLR(DSW_OVERFLOW, ip);
- mutex_exit(&ip->bi_mutex);
-
- _ii_unlock_chunk(ip, II_NULLCHUNK);
- mutex_enter(&ip->bi_mutex);
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- _ii_rlse_devs(ip, rtype);
- if (rc) {
- spcs_s_add(kstatus, rc);
- return (DSW_EIO);
- } else {
- DTRACE_PROBE(_ii_do_copy_end);
- return (0);
- }
- }
-
- /*
- * need to perform an actual copy.
- */
-
- /*
- * Perform bitmap copy if asked or from dependent shadow to master.
- */
- if ((flags & CV_BMP_ONLY) ||
- ((flags & CV_SHD2MST) &&
- ((ip->bi_flags & DSW_GOLDEN) == 0))) {
- DTRACE_PROBE(INDEPENDENT_fast);
- rc = II_ORBM(ip); /* save shadow bits for copy */
- } else {
- DTRACE_PROBE(INDEPENDENT_slow);
- rc = ii_fill_copy_bmp(ip); /* set bits for independent copy */
- }
- if (rc == 0)
- rc = II_ZEROBM(ip);
- _ii_unlock_chunk(ip, II_NULLCHUNK);
- if (rc == 0) {
- mutex_enter(&ip->bi_mutex);
- if (ip->bi_flags & (DSW_COPYINGP | DSW_SHDEXPORT)) {
- rc = (ip->bi_flags & DSW_COPYINGP)
- ? DSW_ECOPYING : DSW_EISEXPORTED;
-
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- _ii_rlse_devs(ip, rtype);
- return (rc);
- }
-
- /* assign copying time */
- ip->bi_mtime = ddi_get_time();
-
- if (flags & CV_SHD2MST)
- II_FLAG_SET(DSW_COPYINGS | DSW_COPYINGP, ip);
- else
- II_FLAG_SET(DSW_COPYINGM | DSW_COPYINGP, ip);
- mutex_exit(&ip->bi_mutex);
- rc = _ii_copyvol(ip, (flags & CV_SHD2MST),
- rtype, kstatus, waitflag);
- } else {
- mutex_enter(&ip->bi_mutex);
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- }
-
- if (waitflag)
- _ii_rlse_devs(ip, rtype);
-
- return (rc);
-}
-
-/*
- * _ii_copy
- * Copy or update (take snapshot) II volume.
- *
- * Calling/Exit State:
- * Returns 0 if the operation succeeded. Otherwise an error code
- * is returned and any additional error information is copied
- * out to the user.
- */
-
-int
-_ii_copy(intptr_t arg, int ilp32, int *rvp)
-{
- dsw_ioctl_t ucopy;
- dsw_ioctl32_t ucopy32;
- _ii_info_t *ip;
- int rc = 0;
- spcs_s_info_t kstatus;
-
- *rvp = 0;
-
- if (ilp32) {
- if (copyin((void *)arg, &ucopy32, sizeof (ucopy32)) < 0)
- return (EFAULT);
- II_TAIL_COPY(ucopy, ucopy32, shadow_vol, dsw_ioctl_t);
- ucopy.status = (spcs_s_info_t)ucopy32.status;
- } else if (copyin((void *)arg, &ucopy, sizeof (ucopy)) < 0)
- return (EFAULT);
-
- kstatus = spcs_s_kcreate();
- if (kstatus == NULL)
- return (ENOMEM);
-
- if (!ucopy.shadow_vol[0])
- return (spcs_s_ocopyoutf(&kstatus, ucopy.status, DSW_EEMPTY));
-
- mutex_enter(&_ii_info_mutex);
- ip = _ii_find_set(ucopy.shadow_vol);
- mutex_exit(&_ii_info_mutex);
- if (ip == NULL)
- return (spcs_s_ocopyoutf(&kstatus, ucopy.status,
- DSW_ENOTFOUND));
-
- /* Check that the copy/update makes sense */
- if ((rc = _ii_chk_copy(ip, ucopy.flags, &kstatus, ucopy.pid,
- ucopy.status)) == 0) {
- /* perform the copy */
- _ii_lock_chunk(ip, II_NULLCHUNK);
- /* _ii_do_copy() calls _ii_ioctl_done() */
- rc = _ii_do_copy(ip, ucopy.flags, kstatus, 1);
- return (spcs_s_ocopyoutf(&kstatus, ucopy.status, rc));
- }
-
- return (rc);
-}
-
-/*
- * _ii_mass_copy
- * Copies/updates the sets pointed to in the ipa array.
- *
- * Calling/Exit State:
- * Returns 0 if the operations was successful. Otherwise an
- * error code.
- */
-int
-_ii_mass_copy(_ii_info_t **ipa, dsw_aioctl_t *ucopy, int wait)
-{
- int i;
- int rc = 0;
- int failed;
- int rtype = MSTR|SHDR|BMP;
- _ii_info_t *ip;
- spcs_s_info_t kstatus;
-
- kstatus = spcs_s_kcreate();
- if (kstatus == NULL)
- return (ENOMEM);
-
- /* Check copy validitity */
- for (i = 0; i < ucopy->count; i++) {
- ip = ipa[i];
-
- rc = _ii_chk_copy(ip, ucopy->flags, &kstatus, ucopy->pid,
- ucopy->status);
-
- if (rc) {
- /* Clean up the mess */
-
- DTRACE_PROBE1(_ii_mass_copy_end1, int, rc);
-
- /*
- * The array ipa now looks like:
- * 0..(i-1): needs mutex_enter/ioctl_done/mutex_exit
- * i: needs nothing (_ii_chk_copy does cleanup)
- * (i+1)..n: needs just ioctl_done/mutex_exit
- */
-
- failed = i;
-
- for (i = 0; i < failed; i++) {
- mutex_enter(&(ipa[i]->bi_mutex));
- _ii_ioctl_done(ipa[i]);
- mutex_exit(&(ipa[i]->bi_mutex));
- _ii_rlse_devs(ipa[i], rtype);
- }
-
- /* skip 'failed', start with failed + 1 */
-
- for (i = failed + 1; i < ucopy->count; i++) {
- _ii_ioctl_done(ipa[i]);
- mutex_exit(&(ipa[i]->bi_mutex));
- }
-
- return (rc);
- }
- }
-
- /* Check for duplicate shadows in same II group */
- if (ucopy->flags & CV_SHD2MST) {
- /* Reset the state of all masters */
- for (i = 0; i < ucopy->count; i++) {
- ip = ipa[i];
- ip->bi_master->bi_state &= ~DSW_MSTTARGET;
- }
-
- for (i = 0; i < ucopy->count; i++) {
- ip = ipa[i];
- /*
- * Check the state of the master. If DSW_MSTTARGET is
- * set, it's because this master is attached to another
- * shadow within this set.
- */
- if (ip->bi_master->bi_state & DSW_MSTTARGET) {
- rc = EINVAL;
- break;
- }
-
- /*
- * Set the DSW_MSTTARGET bit on the master associated
- * with this shadow. This will allow us to detect
- * multiple shadows pointing to this master within
- * this loop.
- */
- ip->bi_master->bi_state |= DSW_MSTTARGET;
- }
- }
-
- /* Handle error */
- if (rc) {
- DTRACE_PROBE1(_ii_mass_copy_end2, int, rc);
- for (i = 0; i < ucopy->count; i++) {
- ip = ipa[i];
-
- _ii_rlse_devs(ip, rtype);
-
- mutex_enter(&ip->bi_mutex);
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- }
-
- return (spcs_s_ocopyoutf(&kstatus, ucopy->status, rc));
- }
-
- /* Lock bitmaps & prepare counts */
- for (i = 0; i < ucopy->count; i++) {
- ip = ipa[i];
- _ii_lock_chunk(ip, II_NULLCHUNK);
- if (ip->bi_overflow) {
- ip->bi_overflow->ii_detachcnt = 0;
- }
- }
-
- /* determine which volumes we're dealing with */
- for (i = 0; i < ucopy->count; i++) {
- ip = ipa[i];
- if (ip->bi_overflow) {
- ip->bi_overflow->ii_flags |= IIO_VOL_UPDATE;
- if ((ucopy->flags & (CV_BMP_ONLY|CV_SHD2MST)) ==
- CV_BMP_ONLY) {
- ++ip->bi_overflow->ii_detachcnt;
- }
- }
- }
-
- /* Perform copy */
- for (i = 0; i < ucopy->count; i++) {
- ip = ipa[i];
- rc = _ii_do_copy(ip, ucopy->flags, kstatus, wait);
- /* Hum... what to do if one of these fails? */
- }
-
- /* clear out flags so as to prevent any accidental reuse */
- for (i = 0; i < ucopy->count; i++) {
- ip = ipa[i];
- if (ip->bi_overflow)
- ip->bi_overflow->ii_flags &= ~(IIO_VOL_UPDATE);
- }
-
- /*
- * We can only clean up the kstatus structure if there are
- * no waiters. If someone's waiting for the information,
- * _ii_copyvolp() uses spcs_s_add to write to kstatus. Panic
- * would ensue if we freed it up now.
- */
- if (!wait)
- rc = spcs_s_ocopyoutf(&kstatus, ucopy->status, rc);
-
- return (rc);
-}
-
-/*
- * _ii_list_copy
- * Retrieve a list from a character array and use _ii_mass_copy to
- * initiate a copy/update operation on all of the specified sets.
- *
- * Calling/Exit State:
- * Returns 0 if the operations was successful. Otherwise an
- * error code.
- */
-int
-_ii_list_copy(char *list, dsw_aioctl_t *ucopy, int wait)
-{
- int i;
- int rc = 0;
- char *name;
- _ii_info_t *ip;
- _ii_info_t **ipa;
-
- ipa = kmem_zalloc(sizeof (_ii_info_t *) * ucopy->count, KM_SLEEP);
-
- /* Reserve devices */
- name = list;
- mutex_enter(&_ii_info_mutex);
- for (i = 0; i < ucopy->count; i++, name += DSW_NAMELEN) {
- ip = _ii_find_set(name);
-
- if (ip == NULL) {
- rc = DSW_ENOTFOUND;
- break;
- }
-
- ipa[i] = ip;
- }
-
- if (rc != 0) {
- /* Failed to find all sets, release those we do have */
- while (i-- > 0) {
- ip = ipa[i];
- mutex_enter(&ip->bi_mutex);
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- }
- } else {
- /* Begin copy operation */
- rc = _ii_mass_copy(ipa, ucopy, wait);
- }
-
- mutex_exit(&_ii_info_mutex);
-
- kmem_free(ipa, sizeof (_ii_info_t *) * ucopy->count);
-
- return (rc);
-}
-
-/*
- * _ii_group_copy
- * Retrieve list of sets in a group and use _ii_mass_copy to initiate
- * a copy/update of all of them.
- *
- * Calling/Exit State:
- * Returns 0 if the operations was successful. Otherwise an
- * error code.
- */
-int
-_ii_group_copy(char *name, dsw_aioctl_t *ucopy, int wait)
-{
- int i;
- int rc;
- uint64_t hash;
- _ii_info_t **ipa;
- _ii_lsthead_t *head;
- _ii_lstinfo_t *np;
-
- /* find group */
- hash = nsc_strhash(name);
-
- mutex_enter(&_ii_group_mutex);
-
- for (head = _ii_group_top; head; head = head->lst_next) {
- if (hash == head->lst_hash && strncmp(head->lst_name,
- name, DSW_NAMELEN) == 0)
- break;
- }
-
- if (!head) {
- mutex_exit(&_ii_group_mutex);
- DTRACE_PROBE(_ii_group_copy);
- return (DSW_EGNOTFOUND);
- }
-
- /* Count entries */
- for (ucopy->count = 0, np = head->lst_start; np; np = np->lst_next)
- ++ucopy->count;
-
- if (ucopy->count == 0) {
- mutex_exit(&_ii_group_mutex);
- return (DSW_EGNOTFOUND);
- }
-
- ipa = kmem_zalloc(sizeof (_ii_info_t *) * ucopy->count, KM_SLEEP);
- if (ipa == NULL) {
- mutex_exit(&_ii_group_mutex);
- return (ENOMEM);
- }
-
- /* Create list */
- mutex_enter(&_ii_info_mutex);
- np = head->lst_start;
- for (i = 0; i < ucopy->count; i++) {
- ASSERT(np != 0);
-
- ipa[i] = np->lst_ip;
-
- mutex_enter(&ipa[i]->bi_mutex);
- ipa[i]->bi_ioctl++;
-
- np = np->lst_next;
- }
-
- /* Begin copy operation */
- rc = _ii_mass_copy(ipa, ucopy, wait);
-
- mutex_exit(&_ii_info_mutex);
- mutex_exit(&_ii_group_mutex);
-
- kmem_free(ipa, sizeof (_ii_info_t *) * ucopy->count);
-
- return (rc);
-}
-
-/*
- * _ii_acopy
- * Copy or update (take snapshot) II multiple volumes.
- *
- * Calling/Exit State:
- * Returns 0 if the operation succeeded. Otherwise an error code
- * is returned and any additional error information is copied
- * out to the user.
- */
-int
-_ii_acopy(intptr_t arg, int ilp32, int *rvp)
-{
- int rc;
- size_t name_offset;
- char *list;
- char *nptr;
- char name[DSW_NAMELEN];
- dsw_aioctl_t ucopy;
- dsw_aioctl32_t ucopy32;
- spcs_s_info_t kstatus;
-
- *rvp = 0;
-
- name_offset = offsetof(dsw_aioctl_t, shadow_vol[0]);
-
- if (ilp32) {
- if (copyin((void *)arg, &ucopy32, sizeof (ucopy32)) < 0)
- return (EFAULT);
- II_TAIL_COPY(ucopy, ucopy32, flags, dsw_ioctl_t);
- ucopy.status = (spcs_s_info_t)ucopy32.status;
- name_offset = offsetof(dsw_aioctl32_t, shadow_vol[0]);
- } else if (copyin((void *)arg, &ucopy, sizeof (ucopy)) < 0)
- return (EFAULT);
-
- kstatus = spcs_s_kcreate();
-
- if (kstatus == NULL)
- return (ENOMEM);
-
- nptr = (char *)arg + name_offset;
- rc = 0;
-
- if (ucopy.flags & CV_IS_GROUP) {
- if (copyin(nptr, name, DSW_NAMELEN) < 0)
- return (spcs_s_ocopyoutf(&kstatus, ucopy.status,
- EFAULT));
-
- /* kstatus information is handled within _ii_group_copy */
- rc = _ii_group_copy(name, &ucopy, 0);
- } else if (ucopy.count > 0) {
- list = kmem_alloc(DSW_NAMELEN * ucopy.count, KM_SLEEP);
-
- if (list == NULL)
- return (spcs_s_ocopyoutf(&kstatus, ucopy.status,
- ENOMEM));
-
- if (copyin(nptr, list, DSW_NAMELEN * ucopy.count) < 0)
- return (spcs_s_ocopyoutf(&kstatus, ucopy.status,
- EFAULT));
-
- rc = _ii_list_copy(list, &ucopy, 0);
- kmem_free(list, DSW_NAMELEN * ucopy.count);
- }
-
- return (spcs_s_ocopyoutf(&kstatus, ucopy.status, rc));
-}
-
-/*
- * _ii_bitsset
- * Copy out II pair bitmaps to user program
- *
- * Calling/Exit State:
- * Returns 0 if the operation succeeded. Otherwise an error code
- * is returned and any additional error information is copied
- * out to the user.
- */
-int
-_ii_bitsset(intptr_t arg, int ilp32, int cmd, int *rvp)
-{
- dsw_bitsset_t ubitsset;
- dsw_bitsset32_t ubitsset32;
- nsc_size_t nbitsset;
- _ii_info_t *ip;
- int rc;
- spcs_s_info_t kstatus;
- int bitmap_size;
-
- *rvp = 0;
-
- if (ilp32) {
- if (copyin((void *)arg, &ubitsset32, sizeof (ubitsset32)))
- return (EFAULT);
- ubitsset.status = (spcs_s_info_t)ubitsset32.status;
- bcopy(ubitsset32.shadow_vol, ubitsset.shadow_vol, DSW_NAMELEN);
- } else if (copyin((void *)arg, &ubitsset, sizeof (ubitsset)))
- return (EFAULT);
-
- kstatus = spcs_s_kcreate();
- if (kstatus == NULL)
- return (ENOMEM);
-
- if (!ubitsset.shadow_vol[0])
- return (spcs_s_ocopyoutf(&kstatus, ubitsset.status,
- DSW_EEMPTY));
-
- mutex_enter(&_ii_info_mutex);
- ip = _ii_find_set(ubitsset.shadow_vol);
- mutex_exit(&_ii_info_mutex);
- if (ip == NULL)
- return (spcs_s_ocopyoutf(&kstatus, ubitsset.status,
- DSW_ENOTFOUND));
-
- mutex_exit(&ip->bi_mutex);
-
- if ((rc = _ii_rsrv_devs(ip, BMP, II_INTERNAL)) != 0) {
- mutex_enter(&ip->bi_mutex);
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- spcs_s_add(kstatus, rc);
- return (spcs_s_ocopyoutf(&kstatus, ubitsset.status,
- DSW_ERSRVFAIL));
- }
-
- ubitsset.tot_size = ip->bi_size / DSW_SIZE;
- if ((ip->bi_size % DSW_SIZE) != 0)
- ++ubitsset.tot_size;
- bitmap_size = (ubitsset.tot_size + 7) / 8;
- if (cmd == DSWIOC_SBITSSET)
- rc = II_CNT_BITS(ip, ip->bi_shdfba, &nbitsset, bitmap_size);
- else
- rc = II_CNT_BITS(ip, ip->bi_copyfba, &nbitsset, bitmap_size);
- ubitsset.tot_set = nbitsset;
- _ii_rlse_devs(ip, BMP);
- mutex_enter(&ip->bi_mutex);
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- if (rc) {
- spcs_s_add(kstatus, rc);
- return (spcs_s_ocopyoutf(&kstatus, ubitsset.status, DSW_EIO));
- }
-
- spcs_s_kfree(kstatus);
- /* return the fetched names to the user */
- if (ilp32) {
- ubitsset32.status = (spcs_s_info32_t)ubitsset.status;
- ubitsset32.tot_size = ubitsset.tot_size;
- ubitsset32.tot_set = ubitsset.tot_set;
- rc = copyout(&ubitsset32, (void *)arg, sizeof (ubitsset32));
- } else {
- rc = copyout(&ubitsset, (void *)arg, sizeof (ubitsset));
- }
-
- return (rc);
-}
-
-/*
- * _ii_stopvol
- * Stop any copying process for shadow, and stop shadowing
- *
- */
-
-static void
-_ii_stopvol(_ii_info_t *ip)
-{
- nsc_path_t *mst_tok;
- nsc_path_t *mstr_tok;
- nsc_path_t *shd_tok;
- nsc_path_t *shdr_tok;
- nsc_path_t *bmp_tok;
- int rc;
-
- while (_ii_stopcopy(ip) == EINTR)
- ;
-
- DTRACE_PROBE(_ii_stopvol);
-
- mutex_enter(&ip->bi_mutex);
- mst_tok = ip->bi_mst_tok;
- mstr_tok = ip->bi_mstr_tok;
- shd_tok = ip->bi_shd_tok;
- shdr_tok = ip->bi_shdr_tok;
- bmp_tok = ip->bi_bmp_tok;
- ip->bi_shd_tok = 0;
- ip->bi_shdr_tok = 0;
- if (!NSHADOWS(ip)) {
- ip->bi_mst_tok = 0;
- ip->bi_mstr_tok = 0;
- }
- ip->bi_bmp_tok = 0;
-
- /* Wait for any _ii_open() calls to complete */
-
- while (ip->bi_ioctl) {
- ip->bi_state |= DSW_IOCTL;
- cv_wait(&ip->bi_ioctlcv, &ip->bi_mutex);
- }
- mutex_exit(&ip->bi_mutex);
-
- rc = _ii_reserve_begin(ip);
- if (rc) {
- cmn_err(CE_WARN, "!_ii_stopvol: _ii_reserve_begin %d", rc);
- }
- if (!NSHADOWS(ip)) {
- if (mst_tok) {
- rc = _ii_unregister_path(mst_tok, NSC_PCATCH,
- "master");
- if (rc)
- cmn_err(CE_WARN, "!ii: unregister master %d",
- rc);
- }
-
- if (mstr_tok) {
- rc = _ii_unregister_path(mstr_tok, NSC_PCATCH,
- "raw master");
- if (rc)
- cmn_err(CE_WARN, "!ii: unregister raw "
- "master %d", rc);
- }
- }
-
- if (shd_tok) {
- rc = _ii_unregister_path(shd_tok, NSC_PCATCH, "shadow");
- if (rc)
- cmn_err(CE_WARN, "!ii: unregister shadow %d", rc);
- }
-
- if (shdr_tok) {
- rc = _ii_unregister_path(shdr_tok, NSC_PCATCH, "raw shadow");
- if (rc)
- cmn_err(CE_WARN, "!ii: unregister raw shadow %d", rc);
- }
-
- if (bmp_tok) {
- rc = _ii_unregister_path(bmp_tok, NSC_PCATCH, "bitmap");
- if (rc)
- cmn_err(CE_WARN, "!ii: unregister bitmap %d", rc);
- }
- _ii_reserve_end(ip);
-
- /* Wait for all necessary _ii_close() calls to complete */
- mutex_enter(&ip->bi_mutex);
-
- while (total_ref(ip) != 0) {
- ip->bi_state |= DSW_CLOSING;
- cv_wait(&ip->bi_closingcv, &ip->bi_mutex);
- }
- if (!NSHADOWS(ip)) {
- nsc_set_owner(ip->bi_mstfd, NULL);
- nsc_set_owner(ip->bi_mstrfd, NULL);
- }
- nsc_set_owner(ip->bi_shdfd, NULL);
- nsc_set_owner(ip->bi_shdrfd, NULL);
- mutex_exit(&ip->bi_mutex);
-
-}
-
-
-/*
- * _ii_ioctl_done
- * If this is the last one to complete, wakeup all processes waiting
- * for ioctls to complete
- *
- */
-
-static void
-_ii_ioctl_done(_ii_info_t *ip)
-{
- ASSERT(ip->bi_ioctl > 0);
- ip->bi_ioctl--;
- if (ip->bi_ioctl == 0 && (ip->bi_state & DSW_IOCTL)) {
- ip->bi_state &= ~DSW_IOCTL;
- cv_broadcast(&ip->bi_ioctlcv);
- }
-
-}
-
-/*
- * _ii_find_vol
- * Search the configured shadows list for the supplied volume.
- * If found, flag an ioctl in progress and return the locked _ii_info_t.
- *
- * The caller must check to see if the bi_disable flag is set and
- * treat it appropriately.
- *
- * ASSUMPTION:
- * _ii_info_mutex must be locked prior to calling this function
- *
- */
-
-static _ii_info_t *
-_ii_find_vol(char *volume, int vol)
-{
- _ii_info_t **xip, *ip;
-
- for (xip = &_ii_info_top; *xip; xip = &(*xip)->bi_next) {
- if ((*xip)->bi_disabled)
- continue;
- if (strcmp(volume, vol == MST ? ii_pathname((*xip)->bi_mstfd) :
- (*xip)->bi_keyname) == 0) {
- break;
- }
- }
-
- if (!*xip) {
- DTRACE_PROBE(VolNotFound);
- return (NULL);
- }
-
- ip = *xip;
- if (!ip->bi_shd_tok && ((ip->bi_flags & DSW_SHDEXPORT) == 0)) {
- /* Not fully configured until bi_shd_tok is set */
- DTRACE_PROBE(SetNotConfiged);
- return (NULL);
-
- }
- mutex_enter(&ip->bi_mutex);
- ip->bi_ioctl++;
-
- return (ip);
-}
-
-static _ii_info_t *
-_ii_find_set(char *volume)
-{
- return (_ii_find_vol(volume, SHD));
-}
-
-/*
- * _ii_find_overflow
- * Search the configured shadows list for the supplied overflow volume.
- *
- */
-
-static _ii_overflow_t *
-_ii_find_overflow(char *volume)
-{
- _ii_overflow_t **xop, *op;
-
- mutex_enter(&_ii_overflow_mutex);
-
- DTRACE_PROBE(_ii_find_overflowmutex);
-
- for (xop = &_ii_overflow_top; *xop; xop = &(*xop)->ii_next) {
- if (strcmp(volume, (*xop)->ii_volname) == 0) {
- break;
- }
- }
-
- if (!*xop) {
- mutex_exit(&_ii_overflow_mutex);
- return (NULL);
- }
-
- op = *xop;
- mutex_exit(&_ii_overflow_mutex);
-
- return (op);
-}
-
-/*
- * _ii_bm_header_get
- * Fetch the bitmap volume header
- *
- */
-
-ii_header_t *
-_ii_bm_header_get(_ii_info_t *ip, nsc_buf_t **tmp)
-{
- ii_header_t *hdr;
- nsc_off_t read_fba;
- int rc;
-
- ASSERT(ip->bi_bmprsrv); /* assert bitmap is reserved */
- ASSERT(MUTEX_HELD(&ip->bi_mutex));
-
- if ((ip->bi_flags & DSW_BMPOFFLINE) != 0)
- return (NULL);
-
- *tmp = NULL;
- read_fba = 0;
-
- II_READ_START(ip, bitmap);
- rc = nsc_alloc_buf(ip->bi_bmpfd, read_fba,
- FBA_LEN(sizeof (ii_header_t)), NSC_RDWRBUF, tmp);
- II_READ_END(ip, bitmap, rc, FBA_LEN(sizeof (ii_header_t)));
- if (!II_SUCCESS(rc)) {
- if (ii_debug > 2)
- cmn_err(CE_WARN, "!ii: nsc_alloc_buf returned 0x%x",
- rc);
- if (*tmp)
- (void) nsc_free_buf(*tmp);
- *tmp = NULL;
- mutex_exit(&ip->bi_mutex);
- _ii_error(ip, DSW_BMPOFFLINE);
- mutex_enter(&ip->bi_mutex);
- return (NULL);
- }
-
- hdr = (ii_header_t *)(*tmp)->sb_vec[0].sv_addr;
-
- return (hdr);
-}
-
-
-/*
- * _ii_bm_header_free
- * Free the bitmap volume header
- *
- */
-
-/* ARGSUSED */
-
-void
-_ii_bm_header_free(ii_header_t *hdr, _ii_info_t *ip, nsc_buf_t *tmp)
-{
- (void) nsc_free_buf(tmp);
-
-}
-
-/*
- * _ii_bm_header_put
- * Write out the modified bitmap volume header and free it
- *
- */
-
-/* ARGSUSED */
-
-int
-_ii_bm_header_put(ii_header_t *hdr, _ii_info_t *ip, nsc_buf_t *tmp)
-{
- nsc_off_t write_fba;
- int rc;
-
- ASSERT(MUTEX_HELD(&ip->bi_mutex));
-
- write_fba = 0;
-
- II_NSC_WRITE(ip, bitmap, rc, tmp, write_fba,
- FBA_LEN(sizeof (ii_header_t)), 0);
-
- (void) nsc_free_buf(tmp);
- if (!II_SUCCESS(rc)) {
- mutex_exit(&ip->bi_mutex);
- _ii_error(ip, DSW_BMPOFFLINE);
- mutex_enter(&ip->bi_mutex);
- DTRACE_PROBE(_ii_bm_header_put);
- return (rc);
- } else {
- DTRACE_PROBE(_ii_bm_header_put_end);
- return (0);
- }
-}
-
-/*
- * _ii_flag_op
- * Clear or set a flag in bi_flags and dsw_state.
- * This relies on the ownership of the header block's nsc_buf
- * for locking.
- *
- */
-
-void
-_ii_flag_op(and, or, ip, update)
-int and, or;
-_ii_info_t *ip;
-int update;
-{
- ii_header_t *bm_header;
- nsc_buf_t *tmp;
-
- ip->bi_flags &= and;
- ip->bi_flags |= or;
-
- if (update == TRUE) {
-
- /*
- * No point trying to access bitmap header if it's offline
- * or has been disassociated from set via DSW_HANGING
- */
- if ((ip->bi_flags & (DSW_BMPOFFLINE|DSW_HANGING)) == 0) {
- bm_header = _ii_bm_header_get(ip, &tmp);
- if (bm_header == NULL) {
- if (tmp)
- (void) nsc_free_buf(tmp);
- DTRACE_PROBE(_ii_flag_op_end);
- return;
- }
- bm_header->ii_state &= and;
- bm_header->ii_state |= or;
- /* copy over the mtime */
- bm_header->ii_mtime = ip->bi_mtime;
- (void) _ii_bm_header_put(bm_header, ip, tmp);
- }
- }
-
-}
-
-/*
- * _ii_nsc_io
- * Perform read or write on an underlying nsc device
- * fd - nsc file descriptor
- * flag - nsc io direction and characteristics flag
- * fba_pos - offset from beginning of device in FBAs
- * io_addr - pointer to data buffer
- * io_len - length of io in bytes
- */
-
-int
-_ii_nsc_io(_ii_info_t *ip, int ks, nsc_fd_t *fd, int flag, nsc_off_t fba_pos,
- unsigned char *io_addr, nsc_size_t io_len)
-{
- nsc_buf_t *tmp = NULL;
- nsc_vec_t *vecp;
- uchar_t *vaddr;
- size_t copy_len;
- int64_t vlen;
- int rc;
- nsc_size_t fba_req, fba_len;
- nsc_size_t maxfbas = 0;
- nsc_size_t tocopy;
- unsigned char *toaddr;
-
- rc = nsc_maxfbas(fd, 0, &maxfbas);
- if (!II_SUCCESS(rc)) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!_ii_nsc_io: maxfbas failed (%d)", rc);
-#endif
- maxfbas = DSW_CBLK_FBA;
- }
-
- toaddr = io_addr;
- fba_req = FBA_LEN(io_len);
-
-#ifdef DEBUG_SPLIT_IO
- cmn_err(CE_NOTE, "!_ii_nsc_io: maxfbas = %08x", maxfbas);
- cmn_err(CE_NOTE, "!_ii_nsc_io: toaddr=%08x, io_len=%08x, fba_req=%08x",
- toaddr, io_len, fba_req);
-#endif
-
-loop:
- tmp = NULL;
- fba_len = min(fba_req, maxfbas);
- tocopy = min(io_len, FBA_SIZE(fba_len));
-
- DTRACE_PROBE2(_ii_nsc_io_buffer, nsc_off_t, fba_pos,
- nsc_size_t, fba_len);
-
-#ifdef DEBUG_SPLIT_IO
- cmn_err(CE_NOTE, "!_ii_nsc_io: fba_pos=%08x, fba_len=%08x",
- fba_pos, fba_len);
-#endif
-
-#ifndef DISABLE_KSTATS
- if (flag & NSC_READ) {
- switch (ks) {
- case KS_MST:
- II_READ_START(ip, master);
- break;
- case KS_SHD:
- II_READ_START(ip, shadow);
- break;
- case KS_BMP:
- II_READ_START(ip, bitmap);
- break;
- case KS_OVR:
- II_READ_START(ip, overflow);
- break;
- default:
- cmn_err(CE_WARN, "!Invalid kstats type %d", ks);
- break;
- }
- }
-#endif
-
- rc = nsc_alloc_buf(fd, fba_pos, fba_len, flag, &tmp);
-
-#ifndef DISABLE_KSTATS
- if (flag & NSC_READ) {
- switch (ks) {
- case KS_MST:
- II_READ_END(ip, master, rc, fba_len);
- break;
- case KS_SHD:
- II_READ_END(ip, shadow, rc, fba_len);
- break;
- case KS_BMP:
- II_READ_END(ip, bitmap, rc, fba_len);
- break;
- case KS_OVR:
- II_READ_END(ip, overflow, rc, fba_len);
- break;
- }
- }
-#endif
-
- if (!II_SUCCESS(rc)) {
- if (tmp) {
- (void) nsc_free_buf(tmp);
- }
-
- return (EIO);
- }
-
- if ((flag & (NSC_WRITE|NSC_READ)) == NSC_WRITE &&
- (FBA_OFF(io_len) != 0)) {
- /*
- * Not overwriting all of the last FBA, so read in the
- * old contents now before we overwrite it with the new
- * data.
- */
-#ifdef DEBUG_SPLIT_IO
- cmn_err(CE_NOTE, "!_ii_nsc_io: Read-B4-Write %08x",
- fba_pos+FBA_NUM(io_len));
-#endif
-
-#ifdef DISABLE_KSTATS
- rc = nsc_read(tmp, fba_pos+FBA_NUM(io_len), 1, 0);
-#else
- switch (ks) {
- case KS_MST:
- II_NSC_READ(ip, master, rc, tmp,
- fba_pos+FBA_NUM(io_len), 1, 0);
- break;
- case KS_SHD:
- II_NSC_READ(ip, shadow, rc, tmp,
- fba_pos+FBA_NUM(io_len), 1, 0);
- break;
- case KS_BMP:
- II_NSC_READ(ip, bitmap, rc, tmp,
- fba_pos+FBA_NUM(io_len), 1, 0);
- break;
- case KS_OVR:
- II_NSC_READ(ip, overflow, rc, tmp,
- fba_pos+FBA_NUM(io_len), 1, 0);
- break;
- case KS_NA:
- rc = nsc_read(tmp, fba_pos+FBA_NUM(io_len), 1, 0);
- break;
- default:
- cmn_err(CE_WARN, "!Invalid kstats type %d", ks);
- rc = nsc_read(tmp, fba_pos+FBA_NUM(io_len), 1, 0);
- break;
- }
-#endif
- if (!II_SUCCESS(rc)) {
- (void) nsc_free_buf(tmp);
- return (EIO);
- }
- }
-
- vecp = tmp->sb_vec;
- vlen = vecp->sv_len;
- vaddr = vecp->sv_addr;
-
- while (tocopy > 0) {
- if (vecp->sv_addr == 0 || vecp->sv_len == 0) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!_ii_nsc_io: ran off end of handle");
-#endif
- break;
- }
-
- copy_len = (size_t)min(vlen, tocopy);
-
- DTRACE_PROBE1(_ii_nsc_io_bcopy, size_t, copy_len);
-
- if (flag & NSC_WRITE)
- bcopy(io_addr, vaddr, copy_len);
- else
- bcopy(vaddr, io_addr, copy_len);
-
- toaddr += copy_len;
- tocopy -= copy_len;
- io_addr += copy_len;
- io_len -= copy_len;
- vaddr += copy_len;
- vlen -= copy_len;
-
- if (vlen <= 0) {
- vecp++;
- vaddr = vecp->sv_addr;
- vlen = vecp->sv_len;
- }
- }
-
- if (flag & NSC_WRITE) {
-#ifdef DISABLE_KSTATS
- rc = nsc_write(tmp, tmp->sb_pos, tmp->sb_len, 0);
-#else
- switch (ks) {
- case KS_MST:
- II_NSC_WRITE(ip, master, rc, tmp, tmp->sb_pos,
- tmp->sb_len, 0);
- break;
- case KS_SHD:
- II_NSC_WRITE(ip, shadow, rc, tmp, tmp->sb_pos,
- tmp->sb_len, 0);
- break;
- case KS_BMP:
- II_NSC_WRITE(ip, bitmap, rc, tmp, tmp->sb_pos,
- tmp->sb_len, 0);
- break;
- case KS_OVR:
- II_NSC_WRITE(ip, overflow, rc, tmp, tmp->sb_pos,
- tmp->sb_len, 0);
- break;
- case KS_NA:
- rc = nsc_write(tmp, tmp->sb_pos, tmp->sb_len, 0);
- break;
- default:
- cmn_err(CE_WARN, "!Invalid kstats type %d", ks);
- rc = nsc_write(tmp, tmp->sb_pos, tmp->sb_len, 0);
- break;
- }
-#endif
- if (!II_SUCCESS(rc)) {
- (void) nsc_free_buf(tmp);
- return (rc);
- }
- }
-
- (void) nsc_free_buf(tmp);
-
- fba_pos += fba_len;
- fba_req -= fba_len;
- if (fba_req > 0)
- goto loop;
-
- return (0);
-}
-
-
-/*
- * ii_overflow_attach
- */
-static int
-ii_overflow_attach(_ii_info_t *ip, char *name, int first)
-{
- _ii_overflow_t *op;
- int rc = 0;
- int reserved = 0;
- int mutex_set = 0;
- int II_OLD_OMAGIC = 0x426c7565; /* "Blue" */
-
- mutex_enter(&_ii_overflow_mutex);
- /* search for name in list */
- for (op = _ii_overflow_top; op; op = op->ii_next) {
- if (strncmp(op->ii_volname, name, DSW_NAMELEN) == 0)
- break;
- }
- if (op) {
- ip->bi_overflow = op;
- op->ii_crefcnt++;
- op->ii_drefcnt++;
- if ((op->ii_flags & IIO_CNTR_INVLD) && (op->ii_hversion >= 1)) {
- if (!first)
- mutex_enter(&ip->bi_mutex);
- ip->bi_flags |= DSW_OVRHDRDRTY;
- if (!first)
- mutex_exit(&ip->bi_mutex);
- op->ii_urefcnt++;
- }
-#ifndef DISABLE_KSTATS
- ip->bi_kstat_io.overflow = op->ii_overflow;
- (void) strlcpy(ip->bi_kstat_io.ovrio, op->ii_ioname,
- KSTAT_DATA_CHAR_LEN);
-#endif
- /* write header */
- if (!(rc = nsc_reserve(op->ii_dev->bi_fd, NSC_MULTI))) {
- rc = _ii_nsc_io(ip, KS_OVR, op->ii_dev->bi_fd,
- NSC_WRBUF, II_OHEADER_FBA,
- (unsigned char *)&op->ii_do, sizeof (op->ii_do));
- (void) nsc_release(op->ii_dev->bi_fd);
- ++iigkstat.assoc_over.value.ul;
- }
- mutex_exit(&_ii_overflow_mutex);
- return (rc);
- }
- if ((op = kmem_zalloc(sizeof (*op), KM_SLEEP)) == NULL) {
- mutex_exit(&_ii_overflow_mutex);
- return (ENOMEM);
- }
- if ((op->ii_dev = kmem_zalloc(sizeof (_ii_info_dev_t), KM_SLEEP))
- == NULL) {
- kmem_free(op, sizeof (*op));
- mutex_exit(&_ii_overflow_mutex);
- return (ENOMEM);
- }
-#ifndef DISABLE_KSTATS
- if ((op->ii_overflow = _ii_overflow_kstat_create(ip, op))) {
- ip->bi_kstat_io.overflow = op->ii_overflow;
- (void) strlcpy(op->ii_ioname, ip->bi_kstat_io.ovrio,
- KSTAT_DATA_CHAR_LEN);
- } else {
- goto fail;
- }
-#endif
- /* open overflow volume */
- op->ii_dev->bi_fd = nsc_open(name, NSC_IIR_ID|NSC_FILE|NSC_RDWR, NULL,
- (blind_t)&(op->ii_dev->bi_iodev), &rc);
- if (!op->ii_dev->bi_fd)
- op->ii_dev->bi_fd = nsc_open(name,
- NSC_IIR_ID|NSC_DEVICE|NSC_RDWR, NULL,
- (blind_t)&(op->ii_dev->bi_iodev), &rc);
- if (op->ii_dev->bi_fd == NULL) {
- goto fail;
- }
- if ((rc = nsc_reserve(op->ii_dev->bi_fd, 0)) != 0)
- goto fail;
- reserved = 1;
- /* register path */
- op->ii_dev->bi_tok = _ii_register_path(name, NSC_DEVICE,
- _ii_ior);
- if (!op->ii_dev->bi_tok) {
- goto fail;
- }
- /* read header */
- rc = _ii_nsc_io(ip, KS_OVR, op->ii_dev->bi_fd, NSC_RDBUF,
- II_OHEADER_FBA, (unsigned char *)&op->ii_do, sizeof (op->ii_do));
- if (!II_SUCCESS(rc)) {
- _ii_error(ip, DSW_OVROFFLINE);
- goto fail;
- }
- /* On resume, check for old hmagic */
- if (strncmp(op->ii_volname, name, DSW_NAMELEN) ||
- ((op->ii_hmagic != II_OLD_OMAGIC) &&
- (op->ii_hmagic != II_OMAGIC))) {
- rc = DSW_EOMAGIC;
- goto fail;
- }
- /* set up counts */
- op->ii_crefcnt = 1;
- op->ii_drefcnt = 0;
- op->ii_urefcnt = 0;
- op->ii_hmagic = II_OMAGIC;
- if (!first) {
- /* if header version > 0, check if header written */
- if (((op->ii_flags & IIO_HDR_WRTN) == 0) &&
- (op->ii_hversion >= 1)) {
- op->ii_flags |= IIO_CNTR_INVLD;
- mutex_enter(&ip->bi_mutex);
- ip->bi_flags |= DSW_OVRHDRDRTY;
- mutex_exit(&ip->bi_mutex);
- op->ii_urefcnt++;
- }
- }
- op->ii_flags &= ~IIO_HDR_WRTN;
- op->ii_drefcnt++;
- /* write header */
- rc = _ii_nsc_io(ip, KS_OVR, op->ii_dev->bi_fd, NSC_WRBUF,
- II_OHEADER_FBA, (unsigned char *)&op->ii_do, sizeof (op->ii_do));
- nsc_release(op->ii_dev->bi_fd);
- reserved = 0;
- if (!II_SUCCESS(rc)) {
- _ii_error(ip, DSW_OVROFFLINE);
- goto fail;
- }
-
- mutex_init(&op->ii_mutex, NULL, MUTEX_DRIVER, NULL);
- mutex_set++;
-
- /* link onto list */
- op->ii_next = _ii_overflow_top;
- _ii_overflow_top = op;
- ip->bi_overflow = op;
-
- ++iigkstat.assoc_over.value.ul;
- mutex_exit(&_ii_overflow_mutex);
-
- DTRACE_PROBE(_ii_overflow_attach_end);
- return (0);
-fail:
-#ifndef DISABLE_KSTATS
- /* Clean-up kstat stuff */
- if (op->ii_overflow) {
- kstat_delete(op->ii_overflow);
- mutex_destroy(&op->ii_kstat_mutex);
- }
-#endif
- /* clean up mutex if we made it that far */
- if (mutex_set) {
- mutex_destroy(&op->ii_mutex);
- }
-
- if (op->ii_dev) {
- if (op->ii_dev->bi_tok) {
- (void) _ii_unregister_path(op->ii_dev->bi_tok, 0,
- "overflow");
- }
- if (reserved)
- (void) nsc_release(op->ii_dev->bi_fd);
- if (op->ii_dev->bi_fd)
- (void) nsc_close(op->ii_dev->bi_fd);
- kmem_free(op->ii_dev, sizeof (_ii_info_dev_t));
- }
- kmem_free(op, sizeof (*op));
- mutex_exit(&_ii_overflow_mutex);
-
- return (rc);
-}
-
-/*
- * ii_overflow_free
- * Assumes that ip is locked for I/O
- */
-static void
-ii_overflow_free(_ii_info_t *ip, int reclaim)
-{
- _ii_overflow_t *op, **xp;
-
- if ((op = ip->bi_overflow) == NULL)
- return;
- ip->bi_kstat_io.overflow = NULL;
- mutex_enter(&_ii_overflow_mutex);
- switch (reclaim) {
- case NO_RECLAIM:
- if (--(op->ii_drefcnt) == 0) {
- /* indicate header written */
- op->ii_flags |= IIO_HDR_WRTN;
- /* write out header */
- ASSERT(op->ii_dev->bi_fd);
- (void) nsc_reserve(op->ii_dev->bi_fd, NSC_MULTI);
- (void) _ii_nsc_io(ip, KS_OVR, op->ii_dev->bi_fd,
- NSC_WRBUF, II_OHEADER_FBA,
- (unsigned char *)&op->ii_do,
- sizeof (op->ii_do));
- nsc_release(op->ii_dev->bi_fd);
- }
- break;
- case RECLAIM:
- ii_reclaim_overflow(ip);
- /* FALLTHRU */
- case INIT_OVR:
- if (--(op->ii_drefcnt) == 0) {
- /* reset to new condition, c.f. _ii_ocreate() */
- op->ii_used = 1;
- op->ii_unused = op->ii_nchunks - op->ii_used;
- op->ii_freehead = II_NULLNODE;
- }
-
- /* write out header */
- ASSERT(op->ii_dev->bi_fd);
- (void) nsc_reserve(op->ii_dev->bi_fd, NSC_MULTI);
- (void) _ii_nsc_io(ip, KS_OVR, op->ii_dev->bi_fd, NSC_WRBUF,
- II_OHEADER_FBA, (unsigned char *)&op->ii_do,
- sizeof (op->ii_do));
- nsc_release(op->ii_dev->bi_fd);
- }
-
- if (--(op->ii_crefcnt) == 0) {
- /* Close fd and unlink from active chain; */
-
- (void) _ii_unregister_path(op->ii_dev->bi_tok, 0, "overflow");
- (void) nsc_close(op->ii_dev->bi_fd);
-
- for (xp = &_ii_overflow_top; *xp && *xp != op;
- xp = &((*xp)->ii_next))
- /* NULL statement */;
- *xp = op->ii_next;
-
- if (op->ii_overflow) {
- kstat_delete(op->ii_overflow);
- }
-
- /* Clean up ii_overflow_t mutexs */
- mutex_destroy(&op->ii_kstat_mutex);
- mutex_destroy(&op->ii_mutex);
-
- if (op->ii_dev)
- kmem_free(op->ii_dev, sizeof (_ii_info_dev_t));
- kmem_free(op, sizeof (*op));
- }
- ip->bi_overflow = NULL;
- --iigkstat.assoc_over.value.ul;
- mutex_exit(&_ii_overflow_mutex);
-
-}
-
-/*
- * ii_sibling_free
- * Free resources and unlink the sibling chains etc.
- */
-
-static void
-ii_sibling_free(_ii_info_t *ip)
-{
- _ii_info_t *hip, *yip;
-
- if (!ip)
- return;
-
- if (ip->bi_shdr_tok)
- (void) _ii_unregister_path(ip->bi_shdr_tok, 0, "raw shadow");
-
- if (ip->bi_shd_tok)
- (void) _ii_unregister_path(ip->bi_shd_tok, 0, "shadow");
-
- rw_enter(&ip->bi_linkrw, RW_WRITER);
-
- ip->bi_shd_tok = NULL;
- ip->bi_shdr_tok = NULL;
-
- if (NSHADOWS(ip)) {
- mutex_enter(&_ii_info_mutex);
- if (ip->bi_head == ip) { /* removing head of list */
- hip = ip->bi_sibling;
- for (yip = hip; yip; yip = yip->bi_sibling)
- yip->bi_head = hip;
-
- } else { /* removing member of list */
- hip = ip->bi_head;
- for (yip = ip->bi_head; yip; yip = yip->bi_sibling) {
- if (yip->bi_sibling == ip) {
- yip->bi_sibling = ip->bi_sibling;
- break;
- }
- }
- }
- hip->bi_master->bi_head = hip;
- if (ip->bi_master == ip) { /* master I/O goes through this */
- mutex_exit(&_ii_info_mutex);
- _ii_info_freeshd(ip);
- rw_exit(&ip->bi_linkrw);
- return;
- }
- mutex_exit(&_ii_info_mutex);
- } else {
- if (ip->bi_master != ip) /* last ref to master side ip */
- _ii_info_free(ip->bi_master); /* ==A== */
- }
-
- if (ip->bi_master != ip) { /* info_free ==A== will close these */
- /*
- * Null out any pointers to shared master side resources
- * that should only be freed once when the last reference
- * to this master is freed and calls _ii_info_free().
- */
- ip->bi_mstdev = NULL;
- ip->bi_mstrdev = NULL;
- ip->bi_kstat_io.master = NULL;
- }
- rw_exit(&ip->bi_linkrw);
- _ii_info_free(ip);
-
-}
-
-/*
- * _ii_info_freeshd
- * Free shadow side resources
- *
- * Calling/Exit State:
- * No mutexes should be held on entry to this function.
- *
- * Description:
- * Frees the system resources associated with the shadow
- * access, leaving the master side alone. This allows the
- * original master side to continue in use while there are
- * outstanding references to this _ii_info_t.
- */
-
-static void
-_ii_info_freeshd(_ii_info_t *ip)
-{
- if (!ip)
- return;
- if ((ip->bi_flags&DSW_HANGING) == DSW_HANGING)
- return; /* this work has already been completed */
-
- II_FLAG_SETX(DSW_HANGING, ip);
-
- if (ip->bi_cluster)
- (void) II_UNLINK_CLUSTER(ip);
- if (ip->bi_group)
- (void) II_UNLINK_GROUP(ip);
-
- if (ip->bi_shdfd && ip->bi_shdrsrv)
- nsc_release(ip->bi_shdfd);
- if (ip->bi_shdrfd && ip->bi_shdrrsrv)
- nsc_release(ip->bi_shdrfd);
- if (ip->bi_bmpfd && ip->bi_bmprsrv)
- nsc_release(ip->bi_bmpfd);
-
- if (ip->bi_bmp_tok)
- (void) _ii_unregister_path(ip->bi_bmp_tok, 0, "bitmap");
-
- if (ip->bi_shdr_tok)
- (void) _ii_unregister_path(ip->bi_shdr_tok, 0, "raw shadow");
-
- if (ip->bi_shd_tok)
- (void) _ii_unregister_path(ip->bi_shd_tok, 0, "shadow");
- ip->bi_shd_tok = NULL;
- ip->bi_shdr_tok = NULL;
-
- if (ip->bi_shdfd)
- (void) nsc_close(ip->bi_shdfd);
-
- if (ip->bi_shdrfd)
- (void) nsc_close(ip->bi_shdrfd);
-
- if (ip->bi_bmpfd)
- (void) nsc_close(ip->bi_bmpfd);
-
- ip->bi_shdfd = NULL;
- ip->bi_shdrfd = NULL;
- ip->bi_bmpfd = NULL;
-
- if (ip->bi_busy)
- kmem_free(ip->bi_busy,
- 1 + (ip->bi_size / (DSW_SIZE * DSW_BITS)));
- ip->bi_busy = NULL;
-
- if (ip->bi_kstat_io.shadow) {
- kstat_delete(ip->bi_kstat_io.shadow);
- ip->bi_kstat_io.shadow = NULL;
- }
- if (ip->bi_kstat_io.bitmap) {
- kstat_delete(ip->bi_kstat_io.bitmap);
- ip->bi_kstat_io.bitmap = NULL;
- }
- if (ip->bi_kstat) {
- kstat_delete(ip->bi_kstat);
- ip->bi_kstat = NULL;
- }
-
-}
-
-/*
- * _ii_info_free
- * Free resources
- *
- * Calling/Exit State:
- * No mutexes should be held on entry to this function.
- *
- * Description:
- * Frees the system resources associated with the specified
- * II information structure.
- */
-
-static void
-_ii_info_free(_ii_info_t *ip)
-{
- _ii_info_t **xip;
-
- if (!ip)
- return;
-
- mutex_enter(&_ii_info_mutex);
- for (xip = &_ii_mst_top; *xip; xip = &((*xip)->bi_nextmst)) {
- if (ip == *xip) {
- *xip = ip->bi_nextmst;
- break;
- }
- }
- mutex_exit(&_ii_info_mutex);
-
- /* this rw_enter forces us to wait until all nsc_buffers are freed */
- rw_enter(&ip->bi_linkrw, RW_WRITER);
- if (ip->bi_mstdev && ip->bi_mstfd && ip->bi_mstrsrv)
- nsc_release(ip->bi_mstfd);
- if (ip->bi_mstrdev && ip->bi_mstrfd && ip->bi_mstrrsrv)
- nsc_release(ip->bi_mstrfd);
-
- if (ip->bi_mstdev && ip->bi_mst_tok)
- (void) _ii_unregister_path(ip->bi_mst_tok, 0, "master");
- if (ip->bi_mstrdev && ip->bi_mstr_tok)
- (void) _ii_unregister_path(ip->bi_mstr_tok, 0, "raw master");
-
- if (ip->bi_mstdev && ip->bi_mstfd)
- (void) nsc_close(ip->bi_mstfd);
- if (ip->bi_mstrdev && ip->bi_mstrfd)
- (void) nsc_close(ip->bi_mstrfd);
- rw_exit(&ip->bi_linkrw);
-
- if (ip->bi_mstdev) {
- nsc_kmem_free(ip->bi_mstdev, sizeof (*ip->bi_mstdev));
- }
- if (ip->bi_mstrdev) {
- nsc_kmem_free(ip->bi_mstrdev, sizeof (*ip->bi_mstrdev));
- }
-
- if (ip->bi_kstat_io.master) {
- kstat_delete(ip->bi_kstat_io.master);
- }
- if (ip->bi_kstat_io.shadow) {
- kstat_delete(ip->bi_kstat_io.shadow);
- ip->bi_kstat_io.shadow = 0;
- }
- if (ip->bi_kstat_io.bitmap) {
- kstat_delete(ip->bi_kstat_io.bitmap);
- ip->bi_kstat_io.bitmap = 0;
- }
- if (ip->bi_kstat) {
- kstat_delete(ip->bi_kstat);
- ip->bi_kstat = NULL;
- }
-
- /* this rw_enter forces us to wait until all nsc_buffers are freed */
- rw_enter(&ip->bi_linkrw, RW_WRITER);
- rw_exit(&ip->bi_linkrw);
-
- mutex_destroy(&ip->bi_mutex);
- mutex_destroy(&ip->bi_rsrvmutex);
- mutex_destroy(&ip->bi_rlsemutex);
- mutex_destroy(&ip->bi_bmpmutex);
- mutex_destroy(&ip->bi_chksmutex);
- cv_destroy(&ip->bi_copydonecv);
- cv_destroy(&ip->bi_reservecv);
- cv_destroy(&ip->bi_releasecv);
- cv_destroy(&ip->bi_ioctlcv);
- cv_destroy(&ip->bi_closingcv);
- cv_destroy(&ip->bi_busycv);
- rw_destroy(&ip->bi_busyrw);
- rw_destroy(&ip->bi_linkrw);
-
- _ii_info_freeshd(ip);
-
-#ifdef DEBUG
- ip->bi_head = (_ii_info_t *)0xdeadbeef;
-#endif
-
- nsc_kmem_free(ip, sizeof (*ip));
-
-}
-
-/*
- * _ii_copy_chunks
- * Perform a copy of some chunks
- *
- * Calling/Exit State:
- * Returns 0 if the data was copied successfully, otherwise
- * error code.
- *
- * Description:
- * flag is set to CV_SHD2MST if the data is to be copied from the shadow
- * to the master, 0 if it is to be copied from the master to the shadow.
- */
-
-static int
-_ii_copy_chunks(_ii_info_t *ip, int flag, chunkid_t chunk_num, int nchunks)
-{
- int mst_flag;
- int shd_flag;
- int ovr_flag;
- nsc_off_t pos;
- nsc_size_t len;
- int rc;
- nsc_off_t shd_pos;
- chunkid_t shd_chunk;
- nsc_buf_t *mst_tmp = NULL;
- nsc_buf_t *shd_tmp = NULL;
-
- if (ip->bi_flags & DSW_MSTOFFLINE) {
- DTRACE_PROBE(_ii_copy_chunks_end);
- return (EIO);
- }
-
- if (ip->bi_flags & (DSW_SHDOFFLINE|DSW_SHDEXPORT|DSW_SHDIMPORT)) {
- DTRACE_PROBE(_ii_copy_chunks_end);
- return (EIO);
- }
-
- if (flag == CV_SHD2MST) {
- mst_flag = NSC_WRBUF|NSC_WRTHRU;
- shd_flag = NSC_RDBUF;
- } else {
- shd_flag = NSC_WRBUF|NSC_WRTHRU;
- mst_flag = NSC_RDBUF;
- }
-
- pos = DSW_CHK2FBA(chunk_num);
- len = DSW_SIZE * nchunks;
- if (pos + len > ip->bi_size)
- len = ip->bi_size - pos;
- if (ip->bi_flags & DSW_TREEMAP) {
- ASSERT(nchunks == 1);
- shd_chunk = ii_tsearch(ip, chunk_num);
- if (shd_chunk == II_NULLNODE) {
- /* shadow is full */
- mutex_enter(&ip->bi_mutex);
- II_FLAG_SET(DSW_OVERFLOW, ip);
- mutex_exit(&ip->bi_mutex);
- DTRACE_PROBE(_ii_copy_chunks_end);
- return (EIO);
- }
-
- ovr_flag = II_ISOVERFLOW(shd_chunk);
- shd_pos = DSW_CHK2FBA((ovr_flag) ?
- II_2OVERFLOW(shd_chunk) : shd_chunk);
- } else {
- ovr_flag = FALSE;
- shd_chunk = chunk_num;
- shd_pos = pos;
- }
-
- /*
- * Always allocate the master side before the shadow to
- * avoid deadlocks on the same chunk.
- */
-
- DTRACE_PROBE2(_ii_copy_chunks_alloc, nsc_off_t, pos, nsc_size_t, len);
-
- II_ALLOC_BUF(ip, master, rc, MSTFD(ip), pos, len, mst_flag, &mst_tmp);
- if (!II_SUCCESS(rc)) {
- if (mst_tmp)
- (void) nsc_free_buf(mst_tmp);
- _ii_error(ip, DSW_MSTOFFLINE);
- DTRACE_PROBE(_ii_copy_chunks_end);
- return (rc);
- }
-
- if (ovr_flag) {
- /* use overflow volume */
- (void) nsc_reserve(OVRFD(ip), NSC_MULTI);
- II_ALLOC_BUF(ip, overflow, rc, OVRFD(ip), shd_pos, len,
- shd_flag, &shd_tmp);
- } else {
- II_ALLOC_BUF(ip, shadow, rc, SHDFD(ip), shd_pos, len, shd_flag,
- &shd_tmp);
- }
- if (!II_SUCCESS(rc)) {
- (void) nsc_free_buf(mst_tmp);
- if (shd_tmp)
- (void) nsc_free_buf(shd_tmp);
- if (ovr_flag)
- nsc_release(OVRFD(ip));
- _ii_error(ip, DSW_SHDOFFLINE);
- if (ovr_flag)
- _ii_error(ip, DSW_OVROFFLINE);
- DTRACE_PROBE(_ii_copy_chunks_end);
- return (rc);
- }
-
- /*
- * The direction of copy is determined by the mst_flag.
- */
- DTRACE_PROBE2(_ii_copy_chunks_copy, kstat_named_t, ii_copy_direct,
- int, mst_flag);
-
- if (ii_copy_direct) {
- if (mst_flag & NSC_WRBUF) {
- if (ovr_flag) {
- II_NSC_COPY_DIRECT(ip, overflow, master, rc,
- shd_tmp, mst_tmp, shd_pos, pos, len)
- } else {
- II_NSC_COPY_DIRECT(ip, shadow, master, rc,
- shd_tmp, mst_tmp, shd_pos, pos, len)
- }
- if (!II_SUCCESS(rc)) {
- /* A copy has failed - something is wrong */
- _ii_error(ip, DSW_MSTOFFLINE);
- _ii_error(ip, DSW_SHDOFFLINE);
- if (ovr_flag)
- _ii_error(ip, DSW_OVROFFLINE);
- }
- } else {
- if (ovr_flag) {
- II_NSC_COPY_DIRECT(ip, master, overflow, rc,
- mst_tmp, shd_tmp, pos, shd_pos, len);
- } else {
- II_NSC_COPY_DIRECT(ip, master, shadow, rc,
- mst_tmp, shd_tmp, pos, shd_pos, len);
- }
- if (!II_SUCCESS(rc)) {
- /*
- * A failure has occurred during the above copy.
- * The macro calls nsc_copy_direct, which will
- * never return a read failure, only a write
- * failure. With this assumption, we should
- * take only the target volume offline.
- */
- _ii_error(ip, DSW_SHDOFFLINE);
- if (ovr_flag)
- _ii_error(ip, DSW_OVROFFLINE);
- }
- }
- } else {
- if (mst_flag & NSC_WRBUF) {
- rc = nsc_copy(shd_tmp, mst_tmp, shd_pos, pos, len);
- if (II_SUCCESS(rc)) {
- II_NSC_WRITE(ip, master, rc, mst_tmp, pos, len,
- 0);
- if (!II_SUCCESS(rc))
- _ii_error(ip, DSW_MSTOFFLINE);
- } else {
- /* A copy has failed - something is wrong */
- _ii_error(ip, DSW_MSTOFFLINE);
- _ii_error(ip, DSW_SHDOFFLINE);
- }
- } else {
- rc = nsc_copy(mst_tmp, shd_tmp, pos, shd_pos, len);
- if (II_SUCCESS(rc)) {
- if (ovr_flag) {
- II_NSC_WRITE(ip, overflow, rc, shd_tmp,
- shd_pos, len, 0);
- } else {
- II_NSC_WRITE(ip, shadow, rc, shd_tmp,
- shd_pos, len, 0);
- }
- if (!II_SUCCESS(rc)) {
- _ii_error(ip, DSW_SHDOFFLINE);
- if (ovr_flag)
- _ii_error(ip, DSW_OVROFFLINE);
- }
- } else {
- /* A copy has failed - something is wrong */
- _ii_error(ip, DSW_MSTOFFLINE);
- _ii_error(ip, DSW_SHDOFFLINE);
- }
- }
- }
-
- (void) nsc_free_buf(mst_tmp);
- (void) nsc_free_buf(shd_tmp);
- if (ovr_flag)
- nsc_release(OVRFD(ip));
-
- DTRACE_PROBE(_ii_copy_chunks);
-
- if (II_SUCCESS(rc)) {
- (void) II_CLR_COPY_BITS(ip, chunk_num, nchunks);
- rc = 0;
- }
-
- return (rc);
-}
-
-
-/*
- * _ii_copy_on_write
- *
- * Calling/Exit State:
- * Returns 0 on success, otherwise error code.
- *
- * Description:
- * Determines if a copy on write is necessary, and performs it.
- * A copy on write is necessary in the following cases:
- * - No copy is in progress and the shadow bit is clear, which
- * means this is the first write to this track.
- * - A copy is in progress and the copy bit is set, which means
- * that a track copy is required.
- * If a copy to the master is to be done, make a recursive call to this
- * function to do any necessary copy on write on other InstantImage groups
- * that share the same master volume.
- */
-
-static int
-_ii_copy_on_write(_ii_info_t *ip, int flag, chunkid_t chunk_num, int nchunks)
-{
- int rc = 0;
- int rtype;
- int hanging = (ip->bi_flags&DSW_HANGING);
-
- if (hanging ||
- (flag & (CV_SIBLING|CV_SHD2MST)) == CV_SHD2MST && NSHADOWS(ip)) {
- _ii_info_t *xip;
- /*
- * Preserve copy of master for all other shadows of this master
- * before writing our data onto the master.
- */
-
- /*
- * Avoid deadlock with COW on same chunk of sibling shadow
- * by unlocking this chunk before copying all other sibling
- * chunks.
- */
-
- /*
- * Only using a single chunk when copying to master avoids
- * complex code here.
- */
-
- ASSERT(nchunks == 1);
- if (!hanging)
- _ii_unlock_chunk(ip, chunk_num);
- for (xip = ip->bi_head; xip; xip = xip->bi_sibling) {
- if (xip == ip) /* don't copy ourselves again */
- continue;
-
- DTRACE_PROBE(_ii_copy_on_write);
-
- rw_enter(&xip->bi_linkrw, RW_READER);
- mutex_enter(&xip->bi_mutex);
- if (xip->bi_disabled) {
- mutex_exit(&xip->bi_mutex);
- rw_exit(&xip->bi_linkrw);
- continue; /* this set is stopping */
- }
- xip->bi_shdref++;
- mutex_exit(&xip->bi_mutex);
- /* don't waste time asking for MST as ip shares it */
- rtype = SHDR|BMP;
- (void) _ii_rsrv_devs(xip, rtype, II_INTERNAL);
- _ii_lock_chunk(xip, chunk_num);
- rc = _ii_copy_on_write(xip, flag | CV_SIBLING,
- chunk_num, 1);
-
- /*
- * See comments in _ii_shadow_write()
- */
- if (rc == 0 ||
- (rc == EIO && (xip->bi_flags&DSW_OVERFLOW) != 0))
- (void) II_SET_SHD_BIT(xip, chunk_num);
-
- _ii_unlock_chunk(xip, chunk_num);
- _ii_rlse_devs(xip, rtype);
- mutex_enter(&xip->bi_mutex);
- xip->bi_shdref--;
- if (xip->bi_state & DSW_CLOSING) {
- if (total_ref(xip) == 0) {
- cv_signal(&xip->bi_closingcv);
- }
- }
- mutex_exit(&xip->bi_mutex);
- rw_exit(&xip->bi_linkrw);
- }
- if (hanging) {
- DTRACE_PROBE(_ii_copy_on_write_end);
- return (0);
- }
- /*
- * Reacquire chunk lock and check that a COW by a sibling
- * has not already copied this chunk.
- */
- _ii_lock_chunk(ip, chunk_num);
- rc = II_TST_SHD_BIT(ip, chunk_num);
- if (rc < 0) {
- DTRACE_PROBE(_ii_copy_on_write_end);
- return (EIO);
- }
- if (rc != 0) {
- DTRACE_PROBE(_ii_copy_on_write_end);
- return (0);
- }
- }
-
- if ((ip->bi_flags & DSW_COPYING) == 0) {
- /* Not copying at all */
-
- if ((ip->bi_flags & DSW_GOLDEN) == DSW_GOLDEN) {
- /* No copy-on-write as it is independent */
- DTRACE_PROBE(_ii_copy_on_write_end);
- return (0);
- }
-
- /* Dependent, so depends on shadow bit */
-
- if ((flag == CV_SHD2MST) &&
- ((ip->bi_flags & DSW_SHDOFFLINE) != 0)) {
- /*
- * Writing master but shadow is offline, so
- * no need to copy on write or set shadow bit
- */
- DTRACE_PROBE(_ii_copy_on_write_end);
- return (0);
- }
- if (ip->bi_flags & DSW_BMPOFFLINE) {
- DTRACE_PROBE(_ii_copy_on_write_end);
- return (EIO);
- }
- rc = II_TST_SHD_BIT(ip, chunk_num);
- if (rc < 0) {
- DTRACE_PROBE(_ii_copy_on_write_end);
- return (EIO);
- }
- if (rc == 0) {
- /* Shadow bit clear, copy master to shadow */
- rc = _ii_copy_chunks(ip, 0, chunk_num, nchunks);
- }
- } else {
- /* Copying one way or the other */
- if (ip->bi_flags & DSW_BMPOFFLINE) {
- DTRACE_PROBE(_ii_copy_on_write_end);
- return (EIO);
- }
- rc = II_TST_COPY_BIT(ip, chunk_num);
- if (rc < 0) {
- DTRACE_PROBE(_ii_copy_on_write_end);
- return (EIO);
- }
- if (rc) {
- /* Copy bit set, do a copy */
- if ((ip->bi_flags & DSW_COPYINGS) == 0) {
- /* Copy master to shadow */
- rc = _ii_copy_chunks(ip, 0, chunk_num, nchunks);
- } else {
- /* Copy shadow to master */
- rc = _ii_copy_chunks(ip, CV_SHD2MST, chunk_num,
- nchunks);
- }
- }
- }
- return (rc);
-}
-
-#ifdef DEBUG
-int ii_maxchunks = 0;
-#endif
-
-/*
- * _ii_copyvolp()
- * Copy volume process.
- *
- * Calling/Exit State:
- * Passes 0 back to caller when the copy is complete or has been aborted,
- * otherwise error code.
- *
- * Description:
- * According to the flag, copy the master to the shadow volume or the
- * shadow to the master volume. Upon return wakeup all processes waiting
- * for this copy.
- *
- */
-
-static void
-_ii_copyvolp(struct copy_args *ca)
-{
- chunkid_t chunk_num;
- int rc = 0;
- chunkid_t max_chunk;
- nsc_size_t nc_max;
- int nc_try, nc_got;
- nsc_size_t mst_max, shd_max;
- _ii_info_t *ip;
- int flag;
- nsc_size_t bitmap_size;
- nsc_size_t shadow_set, copy_set;
- int chunkcount = 0;
- int rsrv = 1;
- spcs_s_info_t kstatus;
-
- ip = ca->ip;
- flag = ca->flag;
- kstatus = ca->kstatus;
-
- if (ip->bi_disabled) {
- rc = DSW_EABORTED;
- goto skip;
- }
- max_chunk = ip->bi_size / DSW_SIZE;
- if ((ip->bi_size % DSW_SIZE) != 0)
- ++max_chunk;
- if ((ip->bi_flags&DSW_TREEMAP))
- nc_max = 1;
- else {
- mst_max = shd_max = 0;
- (void) nsc_maxfbas(MSTFD(ip), 0, &mst_max);
- (void) nsc_maxfbas(SHDFD(ip), 0, &shd_max);
- nc_max = (mst_max < shd_max) ? mst_max : shd_max;
- nc_max /= DSW_SIZE;
- ASSERT(nc_max > 0 && nc_max < 1000);
- }
-#ifdef DEBUG
- if (ii_maxchunks > 0)
- nc_max = ii_maxchunks;
-#endif
- for (chunk_num = nc_got = 0; /* CSTYLED */; /* CSTYLED */) {
- if ((flag & CV_SHD2MST) && NSHADOWS(ip))
- nc_try = 1;
- else
- nc_try = (int)nc_max;
- chunk_num = II_NEXT_COPY_BIT(ip, chunk_num + nc_got,
- max_chunk, nc_try, &nc_got);
-
- if (chunk_num >= max_chunk) /* loop complete */
- break;
- if (ip->bi_flags & DSW_COPYINGX) {
- /* request to abort copy */
- _ii_unlock_chunks(ip, chunk_num, nc_got);
- rc = DSW_EABORTED;
- break;
- }
-
- sema_p(&_ii_concopy_sema);
- rc = _ii_copy_on_write(ip, (flag & CV_SHD2MST), chunk_num,
- nc_got);
- sema_v(&_ii_concopy_sema);
- if (ip->bi_flags & DSW_TREEMAP)
- ii_tdelete(ip, chunk_num);
- _ii_unlock_chunks(ip, chunk_num, nc_got);
- if (!II_SUCCESS(rc)) {
- if (ca->wait)
- spcs_s_add(kstatus, rc);
- rc = DSW_EIO;
- break;
- }
- if (ip->bi_release ||
- (++chunkcount % ip->bi_throttle_unit) == 0) {
- _ii_rlse_devs(ip, (ca->rtype&(~BMP)));
- rsrv = 0;
- delay(ip->bi_throttle_delay);
- ca->rtype = MSTR|SHDR|(ca->rtype&BMP);
- if ((rc = _ii_rsrv_devs(ip, (ca->rtype&(~BMP)),
- II_INTERNAL)) != 0) {
- if (ca->wait)
- spcs_s_add(kstatus, rc);
- rc = DSW_EIO;
- break;
- }
- rsrv = 1;
- if (nc_max > 1) {
- /*
- * maxfbas could have changed during the
- * release/reserve, so recalculate the size
- * of transfer we can do.
- */
- (void) nsc_maxfbas(MSTFD(ip), 0, &mst_max);
- (void) nsc_maxfbas(SHDFD(ip), 0, &shd_max);
- nc_max = (mst_max < shd_max) ?
- mst_max : shd_max;
- nc_max /= DSW_SIZE;
- }
- }
- }
-skip:
- mutex_enter(&ip->bi_mutex);
- if (ip->bi_flags & DSW_COPYINGX)
- II_FLAG_CLR(DSW_COPYINGP|DSW_COPYINGX, ip);
- else
- II_FLAG_CLR(DSW_COPY_FLAGS, ip);
-
- if ((ip->bi_flags & DSW_TREEMAP) && (flag & CV_SHD2MST) &&
- (ip->bi_flags & DSW_VOVERFLOW)) {
- int rs;
- bitmap_size = ip->bi_size / DSW_SIZE;
- if ((ip->bi_size % DSW_SIZE) != 0)
- ++bitmap_size;
- bitmap_size += 7;
- bitmap_size /= 8;
-
- /* Count the number of copy bits set */
- rs = II_CNT_BITS(ip, ip->bi_copyfba, &copy_set, bitmap_size);
- if ((rs == 0) && (copy_set == 0)) {
- /*
- * If we counted successfully and completed the copy
- * see if any writes have forced the set into the
- * overflow
- */
- rs = II_CNT_BITS(ip, ip->bi_shdfba, &shadow_set,
- bitmap_size);
- if ((rs == 0) && (shadow_set <
- (nsc_size_t)ip->bi_shdchks)) {
- II_FLAG_CLR(DSW_VOVERFLOW, ip);
- --iigkstat.spilled_over.value.ul;
- }
- }
- }
-
- ca->rc = rc;
- cv_broadcast(&ip->bi_copydonecv);
- mutex_exit(&ip->bi_mutex);
- if (!ca->wait) {
- if (rsrv)
- _ii_rlse_devs(ip, ca->rtype);
- kmem_free(ca, sizeof (*ca));
- }
-
-}
-
-/*
- * _ii_copyvol()
- * Copy a volume.
- *
- * Calling/Exit State:
- * Returns 0 when the copy is complete or has been aborted,
- * otherwise error code.
- *
- * Description:
- * According to the flag, copy the master to the shadow volume or the
- * shadow to the master volume. Upon return wakeup all processes waiting
- * for this copy. Uses a separate process (_ii_copyvolp) to allow the
- * caller to be interrupted.
- */
-
-static int
-_ii_copyvol(_ii_info_t *ip, int flag, int rtype, spcs_s_info_t kstatus,
- int wait)
-{
- struct copy_args *ca;
- int rc;
-
- /*
- * start copy in separate process.
- */
-
- ca = (struct copy_args *)kmem_alloc(sizeof (*ca), KM_SLEEP);
- ca->ip = ip;
- ca->flag = flag;
- ca->rtype = rtype;
- ca->kstatus = kstatus;
- ca->wait = wait;
- ca->rc = 0;
-
- if (rc = nsc_create_process((void (*)(void *))_ii_copyvolp,
- (void *)ca, FALSE)) {
- mutex_enter(&ip->bi_mutex);
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- cmn_err(CE_NOTE, "!Can't create II copy process");
- kmem_free(ca, sizeof (*ca));
- return (rc);
- }
- mutex_enter(&ip->bi_mutex);
- if (wait == 0) {
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- return (0);
- }
- while (ip->bi_flags & DSW_COPYINGP) {
- (void) cv_wait_sig(&ip->bi_copydonecv, &ip->bi_mutex);
- }
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
- rc = ca->rc;
- kmem_free(ca, sizeof (*ca));
-
- return (rc);
-}
-
-/*
- * _ii_stopcopy
- * Stops any copy process on ip.
- *
- * Calling/Exit State:
- * Returns 0 if the copy was stopped, otherwise error code.
- *
- * Description:
- * Stop an in-progress copy by setting the DSW_COPYINGX flag, then
- * wait for the copy to complete.
- */
-
-static int
-_ii_stopcopy(_ii_info_t *ip)
-{
- mutex_enter(&ip->bi_mutex);
- DTRACE_PROBE1(_ii_stopcopy_flags,
- uint_t, ip->bi_flags);
-
- while (ip->bi_flags & DSW_COPYINGP) {
-
- DTRACE_PROBE(_ii_stopcopy);
-
- II_FLAG_SET(DSW_COPYINGX, ip);
-
- if (cv_wait_sig(&ip->bi_copydonecv, &ip->bi_mutex) == 0) {
- /* Awoken by a signal */
- mutex_exit(&ip->bi_mutex);
- DTRACE_PROBE(_ii_stopcopy);
- return (EINTR);
- }
- }
-
- mutex_exit(&ip->bi_mutex);
-
- return (0);
-}
-
-/*
- * _ii_error
- * Given the error type that occurred, and the current state of the
- * shadowing, set the appropriate error condition(s).
- *
- */
-
-void
-_ii_error(_ii_info_t *ip, int error_type)
-{
- int copy_flags;
- int golden;
- int flags;
- int recursive_call = (error_type & DSW_OVERFLOW) != 0;
- int offline_bits = DSW_OFFLINE;
- _ii_info_t *xip;
- int rc;
-
- error_type &= ~DSW_OVERFLOW;
-
- mutex_enter(&ip->bi_mutex);
- flags = (ip->bi_flags) & offline_bits;
- if ((flags ^ error_type) == 0) {
- /* nothing new offline */
- mutex_exit(&ip->bi_mutex);
- return;
- }
-
- if (error_type == DSW_BMPOFFLINE &&
- (ip->bi_flags & DSW_BMPOFFLINE) == 0) {
- /* first, let nskerd know */
- rc = _ii_report_bmp(ip);
- if (rc) {
- if (ii_debug > 0) {
- cmn_err(CE_WARN, "!Unable to mark bitmap bad in"
- " config DB; rc = %d", rc);
- }
- ip->bi_flags |= DSW_CFGOFFLINE;
- }
- }
-
- flags = ip->bi_flags;
- golden = ((flags & DSW_GOLDEN) == DSW_GOLDEN);
- copy_flags = flags & DSW_COPYING;
-
- switch (error_type) {
-
- case DSW_BMPOFFLINE:
- /* prevent further use of bitmap */
- flags |= DSW_BMPOFFLINE;
- if (ii_debug > 0)
- cmn_err(CE_NOTE, "!ii: Bitmap offline");
-
- switch (copy_flags) {
-
- case DSW_COPYINGM:
- /* Bitmap offline, copying master to shadow */
- flags |= DSW_SHDOFFLINE;
- if (ii_debug > 0)
- cmn_err(CE_NOTE, "!ii: Implied shadow offline");
- break;
-
- case DSW_COPYINGS:
- /* Bitmap offline, copying shadow to master */
- if (golden) {
- /* Shadow is still usable */
- if (ii_debug > 0)
- cmn_err(CE_NOTE,
- "!ii: Implied master offline");
- flags |= DSW_MSTOFFLINE;
- } else {
- /*
- * Snapshot restore from shadow to master
- * is a dumb thing to do anyway. Lose both.
- */
- flags |= DSW_SHDOFFLINE | DSW_MSTOFFLINE;
- if (ii_debug > 0)
- cmn_err(CE_NOTE,
- "ii: Implied master and "
- "shadow offline");
- }
- break;
-
- case 0:
- /* Bitmap offline, no copying in progress */
- if (!golden) {
- if (ii_debug > 0)
- cmn_err(CE_NOTE,
- "!ii: Implied shadow offline");
- flags |= DSW_SHDOFFLINE;
- }
- break;
- }
- break;
-
- case DSW_OVROFFLINE:
- flags |= DSW_OVROFFLINE;
- ASSERT(ip->bi_overflow);
- if (ii_debug > 0)
- cmn_err(CE_NOTE, "!ii: Overflow offline");
- /* FALLTHRU */
- case DSW_SHDOFFLINE:
- flags |= DSW_SHDOFFLINE;
- if (ii_debug > 0)
- cmn_err(CE_NOTE, "!ii: Shadow offline");
-
- if (copy_flags == DSW_COPYINGS) {
- /* Shadow offline, copying shadow to master */
- if (ii_debug > 0)
- cmn_err(CE_NOTE, "!ii: Implied master offline");
- flags |= DSW_MSTOFFLINE;
- }
- break;
-
- case DSW_MSTOFFLINE:
- flags |= DSW_MSTOFFLINE;
- if (ii_debug > 0)
- cmn_err(CE_NOTE, "!ii: Master offline");
-
- switch (copy_flags) {
-
- case DSW_COPYINGM:
- /* Master offline, copying master to shadow */
- flags |= DSW_SHDOFFLINE;
- if (ii_debug > 0)
- cmn_err(CE_NOTE, "!ii: Implied shadow offline");
- break;
-
- case DSW_COPYINGS:
- /* Master offline, copying shadow to master */
- if (!golden) {
- flags |= DSW_SHDOFFLINE;
- if (ii_debug > 0)
- cmn_err(CE_NOTE,
- "!ii: Implied shadow offline");
- }
- break;
-
- case 0:
- /* Master offline, no copying in progress */
- if (!golden) {
- flags |= DSW_SHDOFFLINE;
- if (ii_debug > 0)
- cmn_err(CE_NOTE,
- "!ii: Implied shadow offline");
- }
- break;
- }
- break;
-
- default:
- break;
- }
-
- II_FLAG_SET(flags, ip);
- mutex_exit(&ip->bi_mutex);
-
- if (!recursive_call &&
- NSHADOWS(ip) && (flags&DSW_MSTOFFLINE) == DSW_MSTOFFLINE) {
- /* take master offline for all other sibling shadows */
- for (xip = ip->bi_head; xip; xip = xip->bi_sibling) {
- if (xip == ip)
- continue;
- if (_ii_rsrv_devs(xip, BMP, II_INTERNAL) != 0)
- continue;
- /* overload DSW_OVERFLOW */
- _ii_error(xip, DSW_MSTOFFLINE|DSW_OVERFLOW);
- _ii_rlse_devs(xip, BMP);
- }
- }
-
-}
-
-
-/*
- * _ii_lock_chunk
- * Locks access to the specified chunk
- *
- */
-
-static void
-_ii_lock_chunk(_ii_info_t *ip, chunkid_t chunk)
-{
- if (chunk == II_NULLCHUNK) {
-
- DTRACE_PROBE(_ii_lock_chunk_type);
-
- rw_enter(&ip->bi_busyrw, RW_WRITER);
-
- } else {
-
- DTRACE_PROBE(_ii_lock_chunk_type);
-
- if (ip->bi_busy == NULL) {
- DTRACE_PROBE(_ii_lock_chunk_end);
- return;
- }
-
- rw_enter(&ip->bi_busyrw, RW_READER);
- mutex_enter(&ip->bi_mutex);
- while (DSW_BIT_ISSET(ip->bi_busy[chunk / DSW_BITS],
- chunk % DSW_BITS))
- cv_wait(&ip->bi_busycv, &ip->bi_mutex);
- DSW_BIT_SET(ip->bi_busy[chunk / DSW_BITS], chunk % DSW_BITS);
- mutex_exit(&ip->bi_mutex);
- }
-
-}
-
-
-/*
- * _ii_trylock_chunk
- * Tries to lock access to the specified chunk
- * Returns non-zero on success.
- *
- */
-
-static int
-_ii_trylock_chunk(_ii_info_t *ip, chunkid_t chunk)
-{
- int rc;
-
- ASSERT(chunk != II_NULLCHUNK);
- if (rw_tryenter(&ip->bi_busyrw, RW_READER) == 0) {
- DTRACE_PROBE(_ii_trylock_chunk);
- return (0);
- }
-
- if (ip->bi_busy == NULL) {
- DTRACE_PROBE(_ii_trylock_chunk_end);
- return (0);
- }
-
- mutex_enter(&ip->bi_mutex);
- if (DSW_BIT_ISSET(ip->bi_busy[chunk / DSW_BITS], chunk % DSW_BITS)) {
- rw_exit(&ip->bi_busyrw); /* RW_READER */
- rc = 0;
- } else {
- DSW_BIT_SET(ip->bi_busy[chunk / DSW_BITS], chunk % DSW_BITS);
- rc = 1;
- }
- mutex_exit(&ip->bi_mutex);
-
- return (rc);
-}
-
-/*
- * _ii_unlock_chunks
- * Unlocks access to the specified chunks
- *
- */
-
-static void
-_ii_unlock_chunks(_ii_info_t *ip, chunkid_t chunk, int n)
-{
- if (chunk == II_NULLCHUNK) {
-
- DTRACE_PROBE(_ii_unlock_chunks);
-
- rw_exit(&ip->bi_busyrw); /* RW_WRITER */
-
- } else {
-
- if (ip->bi_busy == NULL) {
- DTRACE_PROBE(_ii_unlock_chunks_end);
- return;
- }
- mutex_enter(&ip->bi_mutex);
-
- DTRACE_PROBE(_ii_unlock_chunks);
-
- for (; n-- > 0; chunk++) {
- ASSERT(DSW_BIT_ISSET(ip->bi_busy[chunk / DSW_BITS],
- chunk % DSW_BITS));
- DSW_BIT_CLR(ip->bi_busy[chunk / DSW_BITS],
- chunk % DSW_BITS);
- rw_exit(&ip->bi_busyrw); /* RW_READER */
- }
- cv_broadcast(&ip->bi_busycv);
- mutex_exit(&ip->bi_mutex);
-
- }
-}
-
-/*
- * Copyout the bit map.
- */
-static int
-_ii_ab_co_bmp(_ii_info_t *ip, nsc_off_t bm_offset, unsigned char *user_bm,
- int user_bm_size)
-{
- nsc_off_t last_fba;
- nsc_buf_t *tmp;
- nsc_vec_t *nsc_vecp;
- nsc_off_t fba_pos;
- int buf_fba_len;
- int buf_byte_len;
- size_t co_len;
- int rc;
-
- DTRACE_PROBE2(_ii_ab_co_bmp_start, nsc_off_t, bm_offset,
- nsc_size_t, user_bm_size);
-
- if (ip->bi_flags & DSW_BMPOFFLINE)
- return (EIO);
-
- /* First calculate the size of the shadow and copy bitmaps */
- co_len = DSW_BM_FBA_LEN(ip->bi_size);
- ASSERT((ip->bi_copyfba - ip->bi_shdfba) == co_len);
-
- /* Are we in the ranges of the various bitmaps/indexes? */
- if (bm_offset < ip->bi_shdfba)
- return (EIO);
- else if (bm_offset < (last_fba = ip->bi_shdfba + co_len))
- /*EMPTY*/;
- else if (bm_offset < (last_fba = ip->bi_copyfba + co_len))
- /*EMPTY*/;
- else if ((ip->bi_flags & DSW_TREEMAP) &&
- (bm_offset < (last_fba = last_fba + (co_len * 32))))
- /*EMPTY*/;
- else return (EIO);
-
- /* Are we within the size of the segment being copied? */
- if (FBA_LEN(user_bm_size) > last_fba - bm_offset)
- return (EIO);
-
- for (fba_pos = bm_offset; fba_pos < last_fba && user_bm_size > 0;
- fba_pos += DSW_CBLK_FBA) {
- tmp = NULL;
- buf_fba_len = fba_pos + DSW_CBLK_FBA < last_fba ?
- DSW_CBLK_FBA : last_fba - fba_pos;
- II_READ_START(ip, bitmap);
- rc = nsc_alloc_buf(ip->bi_bmpfd, fba_pos, buf_fba_len,
- NSC_RDBUF, &tmp);
- II_READ_END(ip, bitmap, rc, buf_fba_len);
- if (!II_SUCCESS(rc)) {
- if (tmp)
- (void) nsc_free_buf(tmp);
-
- _ii_error(ip, DSW_BMPOFFLINE);
- return (EIO);
- }
-
- /* copyout each nsc_vec's worth of data */
- buf_byte_len = FBA_SIZE(buf_fba_len);
- for (nsc_vecp = tmp->sb_vec;
- buf_byte_len > 0 && user_bm_size > 0;
- nsc_vecp++) {
- co_len = (user_bm_size > nsc_vecp->sv_len) ?
- nsc_vecp->sv_len : user_bm_size;
- if (copyout(nsc_vecp->sv_addr, user_bm, co_len)) {
- (void) nsc_free_buf(tmp);
- return (EFAULT);
- }
- user_bm += co_len;
- user_bm_size -= co_len;
- buf_byte_len -= co_len;
- }
-
-
- (void) nsc_free_buf(tmp);
- }
-
- return (0);
-}
-
-/*
- * Copyin a bit map and or with differences bitmap.
- */
-static int
-_ii_ab_ci_bmp(_ii_info_t *ip, nsc_off_t bm_offset, unsigned char *user_bm,
-int user_bm_size)
-{
- nsc_off_t last_fba;
- nsc_buf_t *tmp;
- nsc_vec_t *nsc_vecp;
- nsc_off_t fba_pos;
- int buf_fba_len;
- int buf_byte_len;
- size_t ci_len;
- int rc;
- int n;
- unsigned char *tmp_buf, *tmpp, *tmpq;
-
- DTRACE_PROBE2(_ii_ab_ci_bmp_start, nsc_off_t, bm_offset,
- nsc_size_t, user_bm_size);
-
- if (ip->bi_flags & DSW_BMPOFFLINE)
- return (EIO);
-
- tmp_buf = NULL;
- last_fba = bm_offset + DSW_BM_FBA_LEN(ip->bi_size);
-
- for (fba_pos = bm_offset; fba_pos < last_fba && user_bm_size > 0;
- fba_pos += DSW_CBLK_FBA) {
- tmp = NULL;
- buf_fba_len = fba_pos + DSW_CBLK_FBA < last_fba ?
- DSW_CBLK_FBA : last_fba - fba_pos;
- II_READ_START(ip, bitmap);
- rc = nsc_alloc_buf(ip->bi_bmpfd, fba_pos, buf_fba_len,
- NSC_RDWRBUF, &tmp);
- II_READ_END(ip, bitmap, rc, buf_fba_len);
- if (!II_SUCCESS(rc)) {
- if (tmp)
- (void) nsc_free_buf(tmp);
-
- _ii_error(ip, DSW_BMPOFFLINE);
- return (EIO);
- }
-
- /* copyin each nsc_vec's worth of data */
- buf_byte_len = FBA_SIZE(buf_fba_len);
- for (nsc_vecp = tmp->sb_vec;
- buf_byte_len > 0 && user_bm_size > 0;
- nsc_vecp++) {
- ci_len = (user_bm_size > nsc_vecp->sv_len) ?
- nsc_vecp->sv_len : user_bm_size;
- tmpp = tmp_buf = kmem_alloc(ci_len, KM_SLEEP);
- tmpq = nsc_vecp->sv_addr;
- if (copyin(user_bm, tmpp, ci_len)) {
- (void) nsc_free_buf(tmp);
- kmem_free(tmp_buf, ci_len);
- return (EFAULT);
- }
- for (n = ci_len; n-- > 0; /* CSTYLED */)
- *tmpq++ |= *tmpp++;
- user_bm += ci_len;
- user_bm_size -= ci_len;
- buf_byte_len -= ci_len;
- kmem_free(tmp_buf, ci_len);
- }
-
- II_NSC_WRITE(ip, bitmap, rc, tmp, fba_pos, buf_fba_len, 0);
- if (!II_SUCCESS(rc)) {
- (void) nsc_free_buf(tmp);
- _ii_error(ip, DSW_BMPOFFLINE);
- return (EIO);
- }
-
- (void) nsc_free_buf(tmp);
- }
-
- ip->bi_state |= (DSW_CNTSHDBITS|DSW_CNTCPYBITS);
-
- return (0);
-}
-
-/*
- * Completely zero the bit map.
- *
- * Returns 0 if no error
- * Returns non-zero if there was an error
- */
-static int
-_ii_ab_zerobm(_ii_info_t *ip)
-{
- nsc_off_t fba_pos;
- int rc;
- nsc_size_t len;
- nsc_size_t size;
- nsc_buf_t *tmp;
-
- size = DSW_BM_FBA_LEN(ip->bi_size) + ip->bi_shdfba;
- for (fba_pos = ip->bi_shdfba; fba_pos < size; fba_pos += DSW_CBLK_FBA) {
- tmp = NULL;
- len = fba_pos + DSW_CBLK_FBA < size ?
- DSW_CBLK_FBA : size - fba_pos;
- II_READ_START(ip, bitmap);
- rc = nsc_alloc_buf(ip->bi_bmpfd, fba_pos, len, NSC_RDWRBUF,
- &tmp);
- II_READ_END(ip, bitmap, rc, len);
- if (!II_SUCCESS(rc)) {
- if (tmp)
- (void) nsc_free_buf(tmp);
-
- _ii_error(ip, DSW_BMPOFFLINE);
- return (rc);
- }
-
- rc = nsc_zero(tmp, fba_pos, len, 0);
- if (II_SUCCESS(rc)) {
- II_NSC_WRITE(ip, bitmap, rc, tmp, fba_pos, len, 0);
- }
-
- (void) nsc_free_buf(tmp);
- if (!II_SUCCESS(rc)) {
- _ii_error(ip, DSW_BMPOFFLINE);
- return (rc);
- }
- }
-
- ip->bi_state |= (DSW_CNTSHDBITS|DSW_CNTCPYBITS);
-
- return (0);
-}
-
-
-/*
- * Copy shadow bitmap to copy bitmap
- */
-static int
-_ii_ab_copybm(_ii_info_t *ip)
-{
- nsc_off_t copy_fba_pos, shd_fba_pos;
- int rc;
- nsc_size_t len;
- nsc_off_t size;
- nsc_buf_t *copy_tmp, *shd_tmp;
-
- size = DSW_BM_FBA_LEN(ip->bi_size) + ip->bi_shdfba;
- copy_fba_pos = ip->bi_copyfba;
- for (shd_fba_pos = ip->bi_shdfba; shd_fba_pos < size;
- copy_fba_pos += DSW_CBLK_FBA, shd_fba_pos += DSW_CBLK_FBA) {
- shd_tmp = NULL;
- len = shd_fba_pos + DSW_CBLK_FBA < size ?
- DSW_CBLK_FBA : size - shd_fba_pos;
- II_READ_START(ip, bitmap);
- rc = nsc_alloc_buf(ip->bi_bmpfd, shd_fba_pos, len, NSC_RDBUF,
- &shd_tmp);
- II_READ_END(ip, bitmap, rc, len);
- if (!II_SUCCESS(rc)) {
- if (shd_tmp)
- (void) nsc_free_buf(shd_tmp);
-
- _ii_error(ip, DSW_BMPOFFLINE);
- if (ii_debug > 1)
- cmn_err(CE_NOTE, "!ii: copybm failed 1 rc %d",
- rc);
-
- return (rc);
- }
-
- copy_tmp = NULL;
- rc = nsc_alloc_buf(ip->bi_bmpfd, copy_fba_pos, len, NSC_WRBUF,
- &copy_tmp);
- if (!II_SUCCESS(rc)) {
- (void) nsc_free_buf(shd_tmp);
- if (copy_tmp)
- (void) nsc_free_buf(copy_tmp);
-
- _ii_error(ip, DSW_BMPOFFLINE);
- if (ii_debug > 1)
- cmn_err(CE_NOTE, "!ii: copybm failed 2 rc %d",
- rc);
-
- return (rc);
- }
- rc = nsc_copy(shd_tmp, copy_tmp, shd_fba_pos, copy_fba_pos,
- len);
- if (II_SUCCESS(rc)) {
- II_NSC_WRITE(ip, bitmap, rc, copy_tmp, copy_fba_pos,
- len, 0);
- }
-
- (void) nsc_free_buf(shd_tmp);
- (void) nsc_free_buf(copy_tmp);
- if (!II_SUCCESS(rc)) {
- if (ii_debug > 1)
- cmn_err(CE_NOTE, "!ii: copybm failed 4 rc %d",
- rc);
- _ii_error(ip, DSW_BMPOFFLINE);
- return (rc);
- }
- }
-
- ip->bi_state |= (DSW_CNTSHDBITS|DSW_CNTCPYBITS);
-
- return (0);
-}
-
-
-/*
- * stolen from nsc_copy_h()
- */
-
-static int
-_ii_nsc_or(nsc_buf_t *h1, nsc_buf_t *h2, nsc_off_t pos1, nsc_off_t pos2,
- nsc_size_t len)
-{
- unsigned char *a1, *a2;
- unsigned char *b1, *b2;
- nsc_vec_t *v1, *v2;
- int i, sz, l1, l2;
-
- if (pos1 < h1->sb_pos || pos1 + len > h1->sb_pos + h1->sb_len ||
- pos2 < h2->sb_pos || pos2 + len > h2->sb_pos + h2->sb_len)
- return (EINVAL);
-
- if (!len)
- return (0);
-
- /* find starting point in "from" vector */
-
- v1 = h1->sb_vec;
- pos1 -= h1->sb_pos;
-
- for (; pos1 >= FBA_NUM(v1->sv_len); v1++)
- pos1 -= FBA_NUM(v1->sv_len);
-
- a1 = v1->sv_addr + FBA_SIZE(pos1);
- l1 = v1->sv_len - FBA_SIZE(pos1);
-
- /* find starting point in "to" vector */
-
- v2 = h2->sb_vec;
- pos2 -= h2->sb_pos;
-
- for (; pos2 >= FBA_NUM(v2->sv_len); v2++)
- pos2 -= FBA_NUM(v2->sv_len);
-
- a2 = v2->sv_addr + FBA_SIZE(pos2);
- l2 = v2->sv_len - FBA_SIZE(pos2);
-
- /* copy required data */
-
- len = FBA_SIZE(len);
-
- while (len) {
- sz = min(l1, l2);
- sz = (int)min((nsc_size_t)sz, len);
-
- b1 = a1;
- b2 = a2;
- for (i = sz; i-- > 0; /* CSTYLED */)
- *b2++ |= *b1++;
-
- l1 -= sz;
- l2 -= sz;
- a1 += sz;
- a2 += sz;
- len -= sz;
-
- if (!l1) {
- a1 = (++v1)->sv_addr;
- l1 = v1->sv_len;
- }
- if (!l2) {
- a2 = (++v2)->sv_addr;
- l2 = v2->sv_len;
- }
- }
-
- return (0);
-}
-
-
-/*
- * Or the shadow bitmap in to the copy bitmap, clear the
- * shadow bitmap.
- */
-static int
-_ii_ab_orbm(_ii_info_t *ip)
-{
- nsc_off_t copy_fba_pos, shd_fba_pos;
- int rc;
- nsc_size_t len;
- size_t size;
- nsc_buf_t *copy_tmp, *shd_tmp;
-
- if (ip->bi_flags & DSW_BMPOFFLINE)
- return (EIO);
-
- size = DSW_BM_FBA_LEN(ip->bi_size) + ip->bi_shdfba;
- copy_fba_pos = ip->bi_copyfba;
- for (shd_fba_pos = ip->bi_shdfba; shd_fba_pos < size;
- copy_fba_pos += DSW_CBLK_FBA, shd_fba_pos += DSW_CBLK_FBA) {
- shd_tmp = NULL;
- len = shd_fba_pos + DSW_CBLK_FBA < size ?
- DSW_CBLK_FBA : size - shd_fba_pos;
- II_READ_START(ip, bitmap);
- rc = nsc_alloc_buf(ip->bi_bmpfd, shd_fba_pos, len,
- NSC_RDBUF|NSC_WRBUF, &shd_tmp);
- II_READ_END(ip, bitmap, rc, len);
- if (!II_SUCCESS(rc)) {
- if (shd_tmp)
- (void) nsc_free_buf(shd_tmp);
-
- _ii_error(ip, DSW_BMPOFFLINE);
- return (rc);
- }
-
- copy_tmp = NULL;
- II_READ_START(ip, bitmap);
- rc = nsc_alloc_buf(ip->bi_bmpfd, copy_fba_pos, len,
- NSC_RDBUF|NSC_WRBUF, &copy_tmp);
- II_READ_END(ip, bitmap, rc, len);
- if (!II_SUCCESS(rc)) {
- (void) nsc_free_buf(shd_tmp);
- if (copy_tmp)
- (void) nsc_free_buf(copy_tmp);
-
- _ii_error(ip, DSW_BMPOFFLINE);
- return (rc);
- }
- rc = _ii_nsc_or(shd_tmp, copy_tmp, shd_fba_pos, copy_fba_pos,
- len);
- if (II_SUCCESS(rc)) {
- II_NSC_WRITE(ip, bitmap, rc, copy_tmp, copy_fba_pos,
- len, 0);
- }
- if (II_SUCCESS(rc))
- rc = nsc_zero(shd_tmp, shd_fba_pos, len, 0);
- if (II_SUCCESS(rc)) {
- II_NSC_WRITE(ip, bitmap, rc, shd_tmp, shd_fba_pos, len,
- 0);
- }
-
- (void) nsc_free_buf(shd_tmp);
- (void) nsc_free_buf(copy_tmp);
- if (!II_SUCCESS(rc)) {
- _ii_error(ip, DSW_BMPOFFLINE);
- return (rc);
- }
- }
-
- ip->bi_state |= (DSW_CNTSHDBITS|DSW_CNTCPYBITS);
-
- return (0);
-}
-
-/*
- * _ii_ab_tst_shd_bit
- * Determine if a chunk has been copied to the shadow device
- * Relies on the alloc_buf/free_buf semantics for locking.
- *
- * Calling/Exit State:
- * Returns 1 if the modified bit has been set for the shadow device,
- * Returns 0 if the modified bit has not been set for the shadow device,
- * Returns -1 if there was an error
- */
-
-static int
-_ii_ab_tst_shd_bit(_ii_info_t *ip, chunkid_t chunk)
-{
- int rc;
- nsc_off_t fba;
- nsc_buf_t *tmp = NULL;
-
- if (ip->bi_flags & DSW_BMPOFFLINE)
- return (EIO);
-
- fba = ip->bi_shdfba + chunk / (FBA_SIZE(1) * DSW_BITS);
- chunk %= FBA_SIZE(1) * DSW_BITS;
- II_READ_START(ip, bitmap);
- rc = nsc_alloc_buf(ip->bi_bmpfd, fba, 1, NSC_RDBUF, &tmp);
- II_READ_END(ip, bitmap, rc, 1);
- if (!II_SUCCESS(rc)) {
- _ii_error(ip, DSW_BMPOFFLINE);
- if (tmp)
- (void) nsc_free_buf(tmp);
- return (-1);
- }
- rc = DSW_BIT_ISSET(tmp->sb_vec->sv_addr[chunk/DSW_BITS],
- chunk%DSW_BITS);
- (void) nsc_free_buf(tmp);
-
- return (rc);
-}
-
-
-/*
- * _ii_ab_set_shd_bit
- * Records that a chunk has been copied to the shadow device
- *
- * Returns non-zero if an error is encountered
- * Returns 0 if no error
- */
-
-static int
-_ii_ab_set_shd_bit(_ii_info_t *ip, chunkid_t chunk)
-{
- int rc;
- nsc_off_t fba;
- nsc_buf_t *tmp = NULL;
-
- if (ip->bi_flags & DSW_BMPOFFLINE)
- return (EIO);
-
- fba = ip->bi_shdfba + chunk / (FBA_SIZE(1) * DSW_BITS);
- chunk %= FBA_SIZE(1) * DSW_BITS;
- II_READ_START(ip, bitmap);
- rc = nsc_alloc_buf(ip->bi_bmpfd, fba, 1, NSC_RDBUF|NSC_WRBUF, &tmp);
- II_READ_END(ip, bitmap, rc, 1);
- if (!II_SUCCESS(rc)) {
- _ii_error(ip, DSW_BMPOFFLINE);
- if (tmp)
- (void) nsc_free_buf(tmp);
- return (rc);
- }
- if (DSW_BIT_ISSET(tmp->sb_vec->sv_addr[chunk/DSW_BITS],
- chunk%DSW_BITS) == 0) {
- DSW_BIT_SET(tmp->sb_vec->sv_addr[chunk/DSW_BITS],
- chunk%DSW_BITS);
- II_NSC_WRITE(ip, bitmap, rc, tmp, fba, 1, 0);
- if ((ip->bi_state & DSW_CNTSHDBITS) == 0)
- ip->bi_shdbits++;
- }
- (void) nsc_free_buf(tmp);
- if (!II_SUCCESS(rc)) {
- _ii_error(ip, DSW_BMPOFFLINE);
- return (rc);
- }
-
- return (0);
-}
-
-
-/*
- * _ii_ab_tst_copy_bit
- * Determine if a chunk needs to be copied during updates.
- *
- * Calling/Exit State:
- * Returns 1 if the copy bit for the chunk is set
- * Returns 0 if the copy bit for the chunk is not set
- * Returns -1 if an error is encountered
- */
-
-static int
-_ii_ab_tst_copy_bit(_ii_info_t *ip, chunkid_t chunk)
-{
- int rc;
- nsc_off_t fba;
- nsc_buf_t *tmp = NULL;
-
- if (ip->bi_flags & DSW_BMPOFFLINE)
- return (-1);
-
- fba = ip->bi_copyfba + chunk / (FBA_SIZE(1) * DSW_BITS);
- chunk %= FBA_SIZE(1) * DSW_BITS;
- II_READ_START(ip, bitmap);
- rc = nsc_alloc_buf(ip->bi_bmpfd, fba, 1, NSC_RDBUF, &tmp);
- II_READ_END(ip, bitmap, rc, 1);
- if (!II_SUCCESS(rc)) {
- if (tmp)
- (void) nsc_free_buf(tmp);
- _ii_error(ip, DSW_BMPOFFLINE);
- return (-1);
- }
- rc = DSW_BIT_ISSET(tmp->sb_vec->sv_addr[chunk/DSW_BITS],
- chunk%DSW_BITS);
- (void) nsc_free_buf(tmp);
-
- return (rc);
-}
-
-
-/*
- * _ii_ab_set_copy_bit
- * Records that a chunk has been copied to the shadow device
- *
- * Returns non-zero if an error is encountered
- * Returns 0 if no error
- */
-
-static int
-_ii_ab_set_copy_bit(_ii_info_t *ip, chunkid_t chunk)
-{
- int rc;
- nsc_off_t fba;
- nsc_buf_t *tmp = NULL;
-
- if (ip->bi_flags & DSW_BMPOFFLINE)
- return (EIO);
-
- fba = ip->bi_copyfba + chunk / (FBA_SIZE(1) * DSW_BITS);
- chunk %= FBA_SIZE(1) * DSW_BITS;
- II_READ_START(ip, bitmap);
- rc = nsc_alloc_buf(ip->bi_bmpfd, fba, 1, NSC_RDBUF|NSC_WRBUF, &tmp);
- II_READ_END(ip, bitmap, rc, 1);
- if (!II_SUCCESS(rc)) {
- if (tmp)
- (void) nsc_free_buf(tmp);
- _ii_error(ip, DSW_BMPOFFLINE);
- return (rc);
- }
- if (DSW_BIT_ISSET(tmp->sb_vec->sv_addr[chunk/DSW_BITS],
- chunk%DSW_BITS) == 0) {
- DSW_BIT_SET(tmp->sb_vec->sv_addr[chunk/DSW_BITS],
- chunk%DSW_BITS);
- if ((ip->bi_state & DSW_CNTCPYBITS) == 0)
- ip->bi_copybits++;
-
- II_NSC_WRITE(ip, bitmap, rc, tmp, fba, 1, 0);
- }
- (void) nsc_free_buf(tmp);
- if (!II_SUCCESS(rc)) {
- _ii_error(ip, DSW_BMPOFFLINE);
- return (rc);
- }
-
- return (0);
-}
-
-
-/*
- * _ii_ab_clr_copy_bits
- * Records that a chunk has been cleared on the shadow device, this
- * function assumes that the bits to clear are all in the same fba,
- * as is the case when they were generated by _ii_ab_next_copy_bit().
- *
- * Returns non-zero if an error is encountered
- * Returns 0 if no error
- */
-
-static int
-_ii_ab_clr_copy_bits(_ii_info_t *ip, chunkid_t chunk, int nchunks)
-{
- int rc;
- nsc_off_t fba;
- nsc_buf_t *tmp = NULL;
-
- if (ip->bi_flags & DSW_BMPOFFLINE)
- return (EIO);
-
- fba = ip->bi_copyfba + chunk / (FBA_SIZE(1) * DSW_BITS);
- chunk %= FBA_SIZE(1) * DSW_BITS;
- II_READ_START(ip, bitmap);
- rc = nsc_alloc_buf(ip->bi_bmpfd, fba, 1, NSC_RDBUF|NSC_WRBUF, &tmp);
- II_READ_END(ip, bitmap, rc, 1);
- if (!II_SUCCESS(rc)) {
- if (tmp)
- (void) nsc_free_buf(tmp);
- _ii_error(ip, DSW_BMPOFFLINE);
- return (rc);
- }
- for (; nchunks-- > 0; chunk++) {
- DSW_BIT_CLR(tmp->sb_vec->sv_addr[chunk/DSW_BITS],
- chunk%DSW_BITS);
- if (ip->bi_copybits > 0)
- ip->bi_copybits--;
- }
-
- II_NSC_WRITE(ip, bitmap, rc, tmp, fba, 1, 0);
- (void) nsc_free_buf(tmp);
- if (!II_SUCCESS(rc)) {
- _ii_error(ip, DSW_BMPOFFLINE);
- return (rc);
- }
-
- return (0);
-}
-
-/*
- * _ii_ab_fill_copy_bmp
- * Fills the copy bitmap with 1's.
- *
- * Returns non-zero if an error is encountered
- * Returns 0 if no error
- */
-
-static int
-_ii_ab_fill_copy_bmp(_ii_info_t *ip)
-{
- int rc;
- nsc_off_t fba;
- nsc_buf_t *tmp;
- unsigned char *p;
- int i, j;
-
- if (ip->bi_flags & DSW_BMPOFFLINE)
- return (EIO);
-
- fba = ip->bi_copyfba;
- for (i = DSW_BM_FBA_LEN(ip->bi_size); i-- > 0; fba++) {
- tmp = NULL;
- rc = nsc_alloc_buf(ip->bi_bmpfd, fba, 1, NSC_WRBUF, &tmp);
- if (!II_SUCCESS(rc)) {
- if (tmp)
- (void) nsc_free_buf(tmp);
- _ii_error(ip, DSW_BMPOFFLINE);
- return (rc);
- }
- p = (unsigned char *)tmp->sb_vec->sv_addr;
- for (j = FBA_SIZE(1); j-- > 0; p++)
- *p = (unsigned char)0xff;
- II_NSC_WRITE(ip, bitmap, rc, tmp, fba, 1, 0);
- if (!II_SUCCESS(rc)) {
- _ii_error(ip, DSW_BMPOFFLINE);
- (void) nsc_free_buf(tmp);
- return (rc);
- }
- (void) nsc_free_buf(tmp);
- }
-
- ip->bi_state |= (DSW_CNTSHDBITS|DSW_CNTCPYBITS);
-
- return (0);
-}
-
-/*
- * _ii_ab_load_bmp
- * Load bitmap from persistent storage.
- */
-
-static int
-_ii_ab_load_bmp(_ii_info_t *ip, int flag)
-/* ARGSUSED */
-{
- if (ip->bi_flags & DSW_BMPOFFLINE)
- return (EIO);
-
- ip->bi_state |= (DSW_CNTSHDBITS|DSW_CNTCPYBITS);
-
- return (0);
-}
-
-/*
- * _ii_ab_next_copy_bit
- * Find next set copy bit.
- *
- * Returns the next bits set in the copy bitmap, with the corresponding chunks
- * locked. Used to avoid having to reread the same bit map block as each bit
- * is tested.
- */
-
-static chunkid_t
-_ii_ab_next_copy_bit(_ii_info_t *ip, chunkid_t startchunk, chunkid_t maxchunk,
- int wanted, int *got)
-{
- chunkid_t rc;
- nsc_off_t fba;
- chunkid_t chunk;
- int bits_per_fba = FBA_SIZE(1) * DSW_BITS;
- int high;
- chunkid_t nextchunk;
- nsc_buf_t *tmp = NULL;
-
- *got = 0;
-again:
- if (ip->bi_flags & DSW_BMPOFFLINE)
- return (maxchunk + 1);
-
- while (startchunk < maxchunk) {
- tmp = NULL;
- fba = ip->bi_copyfba + startchunk / bits_per_fba;
- chunk = startchunk % bits_per_fba;
- II_READ_START(ip, bitmap);
- rc = nsc_alloc_buf(ip->bi_bmpfd, fba, 1, NSC_RDBUF, &tmp);
- II_READ_END(ip, bitmap, rc, 1);
- if (!II_SUCCESS(rc)) {
- if (tmp)
- (void) nsc_free_buf(tmp);
- _ii_error(ip, DSW_BMPOFFLINE);
- return (maxchunk + 1);
- }
- high = startchunk + bits_per_fba - startchunk%bits_per_fba;
- if (high > maxchunk)
- high = maxchunk;
- for (; startchunk < high; chunk++, startchunk++) {
- if (DSW_BIT_ISSET(tmp->sb_vec->sv_addr[chunk/DSW_BITS],
- chunk%DSW_BITS)) {
- /*
- * trylock won't sleep so can use while
- * holding the buf.
- */
- if (!_ii_trylock_chunk(ip, startchunk)) {
- (void) nsc_free_buf(tmp);
- _ii_lock_chunk(ip, startchunk);
- if (_ii_ab_tst_copy_bit(ip, startchunk)
- != 1) {
- /*
- * another process copied this
- * chunk while we were acquiring
- * the chunk lock.
- */
- _ii_unlock_chunk(ip,
- startchunk);
- DTRACE_PROBE(
- _ii_ab_next_copy_bit_again);
- goto again;
- }
- *got = 1;
- DTRACE_PROBE(_ii_ab_next_copy_bit_end);
- return (startchunk);
- }
- *got = 1;
- nextchunk = startchunk + 1;
- chunk++;
- for (; --wanted > 0 && nextchunk < high;
- nextchunk++, chunk++) {
- if (!DSW_BIT_ISSET(tmp->sb_vec->sv_addr
- [chunk/DSW_BITS], chunk%DSW_BITS)) {
- break; /* end of bit run */
- }
- if (_ii_trylock_chunk(ip, nextchunk))
- (*got)++;
- else
- break;
- }
- (void) nsc_free_buf(tmp);
- DTRACE_PROBE(_ii_ab_next_copy_bit);
- return (startchunk);
- }
- }
- (void) nsc_free_buf(tmp);
- }
-
- return (maxchunk + 1);
-}
-
-/*
- * _ii_ab_save_bmp
- * Save bitmap to persistent storage.
- */
-
-static int
-_ii_ab_save_bmp(_ii_info_t *ip, int flag)
-/* ARGSUSED */
-{
- if (ip->bi_flags & DSW_BMPOFFLINE)
- return (EIO);
-
- return (0);
-}
-
-/*
- * _ii_ab_change_bmp
- * copy change bitmap to memory
- */
-
-static int
-_ii_ab_change_bmp(_ii_info_t *ip, unsigned char *ptr)
-/* ARGSUSED */
-{
- int bm_size;
- int i, j, fba;
- int rc;
- unsigned char *p;
- nsc_buf_t *tmp = NULL;
-
- if (ip->bi_flags & DSW_BMPOFFLINE)
- return (EIO);
- bm_size = FBA_SIZE(DSW_BM_FBA_LEN(ip->bi_size));
-
- rc = _ii_nsc_io(ip, KS_BMP, ip->bi_bmpfd, NSC_RDBUF, ip->bi_shdfba,
- ptr, bm_size);
- if (!II_SUCCESS(rc)) {
- _ii_error(ip, DSW_BMPOFFLINE);
- return (rc);
- }
-
- fba = ip->bi_copyfba;
- for (i = DSW_BM_FBA_LEN(ip->bi_size); i-- > 0; fba++) {
- tmp = NULL;
- II_READ_START(ip, bitmap);
- rc = nsc_alloc_buf(ip->bi_bmpfd, fba, 1, NSC_RDBUF, &tmp);
- II_READ_END(ip, bitmap, rc, 1);
- if (!II_SUCCESS(rc)) {
- if (tmp)
- (void) nsc_free_buf(tmp);
- _ii_error(ip, DSW_BMPOFFLINE);
- return (rc);
- }
- p = (unsigned char *)tmp->sb_vec->sv_addr;
- for (j = FBA_SIZE(1); j-- > 0; p++)
- *ptr |= *p;
- (void) nsc_free_buf(tmp);
- }
-
- return (0);
-}
-
-/*
- * Count bits set in the bit map.
- */
-static int
-_ii_ab_cnt_bits(_ii_info_t *ip, nsc_off_t bm_offset, nsc_size_t *counter,
-int bm_size)
-{
- nsc_size_t last_fba;
- nsc_buf_t *tmp;
- nsc_vec_t *sd_vecp;
- nsc_off_t fba_pos;
- int buf_fba_len;
- int buf_byte_len;
- int co_len;
- int i;
- unsigned int j, k;
- unsigned char *cp;
- int rc;
-
- *counter = 0;
- if (ip->bi_flags & DSW_BMPOFFLINE)
- return (EIO);
-
- last_fba = bm_offset + DSW_BM_FBA_LEN(ip->bi_size);
-
- for (fba_pos = bm_offset; fba_pos < last_fba && bm_size > 0;
- fba_pos += DSW_CBLK_FBA) {
- tmp = NULL;
- buf_fba_len = fba_pos + DSW_CBLK_FBA < last_fba ?
- DSW_CBLK_FBA : last_fba - fba_pos;
- II_READ_START(ip, bitmap);
- rc = nsc_alloc_buf(ip->bi_bmpfd, fba_pos, buf_fba_len,
- NSC_RDBUF, &tmp);
- II_READ_END(ip, bitmap, rc, 1);
- if (!II_SUCCESS(rc)) {
- if (tmp)
- (void) nsc_free_buf(tmp);
-
- _ii_error(ip, DSW_BMPOFFLINE);
- return (EIO);
- }
-
- /* count each sd_vec's worth of data */
- buf_byte_len = FBA_SIZE(buf_fba_len);
- for (sd_vecp = tmp->sb_vec;
- buf_byte_len > 0 && bm_size > 0;
- sd_vecp++) {
- co_len = (bm_size > sd_vecp->sv_len) ?
- sd_vecp->sv_len : bm_size;
- cp = sd_vecp->sv_addr;
- for (i = k = 0; i < co_len; i++)
- for (j = (unsigned)*cp++; j; j &= j - 1)
- k++;
- *counter += k;
- bm_size -= co_len;
- buf_byte_len -= co_len;
- }
-
-
- (void) nsc_free_buf(tmp);
- }
-
- return (0);
-}
-
-/*
- * OR the bitmaps as part of a join operation
- */
-static int
-_ii_ab_join_bmp(_ii_info_t *dest_ip, _ii_info_t *src_ip)
-{
- int rc;
- nsc_size_t len;
- nsc_size_t size;
- nsc_buf_t *dest_tmp, *src_tmp;
- nsc_off_t src_fba_pos;
-
- if ((src_ip->bi_flags & DSW_BMPOFFLINE) ||
- (dest_ip->bi_flags & DSW_BMPOFFLINE))
- return (EIO);
-
- size = DSW_BM_FBA_LEN(src_ip->bi_size) + src_ip->bi_shdfba;
- for (src_fba_pos = src_ip->bi_shdfba; src_fba_pos < size;
- src_fba_pos += DSW_CBLK_FBA) {
- src_tmp = NULL;
- len = src_fba_pos + DSW_CBLK_FBA < size ?
- DSW_CBLK_FBA : size - src_fba_pos;
- II_READ_START(src_ip, bitmap);
- rc = nsc_alloc_buf(src_ip->bi_bmpfd, src_fba_pos, len,
- NSC_RDWRBUF, &src_tmp);
- II_READ_END(src_ip, bitmap, rc, len);
- if (!II_SUCCESS(rc)) {
- if (src_tmp)
- (void) nsc_free_buf(src_tmp);
-
- _ii_error(src_ip, DSW_BMPOFFLINE);
- return (rc);
- }
-
- dest_tmp = NULL;
- II_READ_START(dest_ip, bitmap);
- rc = nsc_alloc_buf(dest_ip->bi_bmpfd, src_fba_pos, len,
- NSC_RDWRBUF, &dest_tmp);
- II_READ_END(dest_ip, bitmap, rc, len);
- if (!II_SUCCESS(rc)) {
- (void) nsc_free_buf(src_tmp);
- if (dest_tmp)
- (void) nsc_free_buf(dest_tmp);
-
- _ii_error(dest_ip, DSW_BMPOFFLINE);
- return (rc);
- }
- rc = _ii_nsc_or(src_tmp, dest_tmp, src_fba_pos, src_fba_pos,
- len);
- if (II_SUCCESS(rc)) {
- II_NSC_WRITE(dest_ip, bitmap, rc, dest_tmp,
- src_fba_pos, len, 0);
- }
-
- (void) nsc_free_buf(src_tmp);
- (void) nsc_free_buf(dest_tmp);
- if (!II_SUCCESS(rc)) {
- _ii_error(dest_ip, DSW_BMPOFFLINE);
- return (rc);
- }
- }
-
- dest_ip->bi_state |= (DSW_CNTSHDBITS|DSW_CNTCPYBITS);
-
- return (0);
-
-}
-
-static _ii_bmp_ops_t alloc_buf_bmp = {
- _ii_ab_co_bmp,
- _ii_ab_ci_bmp,
- _ii_ab_zerobm,
- _ii_ab_copybm,
- _ii_ab_orbm,
- _ii_ab_tst_shd_bit,
- _ii_ab_set_shd_bit,
- _ii_ab_tst_copy_bit,
- _ii_ab_set_copy_bit,
- _ii_ab_clr_copy_bits,
- _ii_ab_next_copy_bit,
- _ii_ab_fill_copy_bmp,
- _ii_ab_load_bmp,
- _ii_ab_save_bmp,
- _ii_ab_change_bmp,
- _ii_ab_cnt_bits,
- _ii_ab_join_bmp
-};
-
-
-/*
- * Copyout the bit map.
- */
-static int
-_ii_km_co_bmp(_ii_info_t *ip, nsc_off_t bm_offset, unsigned char *user_bm,
- int user_bm_size)
-{
- int start_offset;
- int bm_size;
- size_t co_len;
- nsc_off_t last_fba;
-
- /* First calculate the size of the shadow and copy bitmaps */
- co_len = DSW_BM_FBA_LEN(ip->bi_size);
- ASSERT((ip->bi_copyfba - ip->bi_shdfba) == co_len);
-
- /* Are we in the ranges of the various bitmaps/indexes? */
- if (bm_offset < ip->bi_shdfba)
- return (EIO);
- else if (bm_offset < (last_fba = ip->bi_shdfba + co_len))
- /*EMPTY*/;
- else if (bm_offset < (last_fba = ip->bi_copyfba + co_len))
- /*EMPTY*/;
- else if ((ip->bi_flags & DSW_TREEMAP) &&
- (bm_offset < (last_fba = last_fba + (co_len * 32))))
- /*EMPTY*/;
- else return (EIO);
-
- if (FBA_LEN(user_bm_size) > last_fba - bm_offset)
- return (EIO);
-
- start_offset = FBA_SIZE(bm_offset);
- bm_size = FBA_SIZE(last_fba);
-
- co_len = (user_bm_size > bm_size) ? bm_size : user_bm_size;
- if (copyout(ip->bi_bitmap + start_offset, user_bm, co_len))
- return (EFAULT);
-
- return (0);
-}
-
-/*
- * Copyin a bit map and or with differences bitmap.
- */
-static int
-_ii_km_ci_bmp(_ii_info_t *ip, nsc_off_t bm_offset, unsigned char *user_bm,
- int user_bm_size)
-{
- unsigned char *tmp_buf;
- unsigned char *dest;
- unsigned char *p;
- size_t tmp_size;
- int n;
- int start_offset;
- int bm_size;
- size_t ci_len;
- int rc = 0;
-
- start_offset = FBA_SIZE(bm_offset);
- bm_size = FBA_SIZE(DSW_BM_FBA_LEN(ip->bi_size));
-
- tmp_buf = NULL;
- tmp_size = FBA_SIZE(1);
-
- tmp_buf = kmem_alloc(tmp_size, KM_SLEEP);
- start_offset = FBA_SIZE(bm_offset);
- dest = ip->bi_bitmap + start_offset;
- bm_size = FBA_SIZE(DSW_BM_FBA_LEN(ip->bi_size));
-
- ci_len = (user_bm_size > bm_size) ? bm_size : user_bm_size;
- while (ci_len > 0) {
- n = (tmp_size > ci_len) ? ci_len : tmp_size;
- if (copyin(user_bm, tmp_buf, n)) {
- rc = EFAULT;
- break;
- }
- user_bm += n;
- for (p = tmp_buf; n--> 0; ci_len--)
- *dest++ |= *p++;
- }
- if (tmp_buf)
- kmem_free(tmp_buf, tmp_size);
-
- ip->bi_state |= (DSW_CNTSHDBITS|DSW_CNTCPYBITS);
-
- return (rc);
-}
-
-/*
- * Completely zero the bit map.
- */
-static int
-_ii_km_zerobm(_ii_info_t *ip)
-{
- int start_offset = FBA_SIZE(ip->bi_shdfba);
- int len;
-
- len = FBA_SIZE(ip->bi_copyfba - ip->bi_shdfba);
- mutex_enter(&ip->bi_bmpmutex);
- bzero(ip->bi_bitmap+start_offset, len);
- mutex_exit(&ip->bi_bmpmutex);
-
- ip->bi_state |= (DSW_CNTSHDBITS|DSW_CNTCPYBITS);
-
- return (0);
-}
-
-
-/*
- * Copy shadow bitmap to copy bitmap
- */
-static int
-_ii_km_copybm(_ii_info_t *ip)
-{
- int copy_offset, shd_offset;
- int len;
-
- len = FBA_SIZE(ip->bi_copyfba - ip->bi_shdfba);
- shd_offset = FBA_SIZE(ip->bi_shdfba);
- copy_offset = FBA_SIZE(ip->bi_copyfba);
- mutex_enter(&ip->bi_bmpmutex);
- bcopy(ip->bi_bitmap+shd_offset, ip->bi_bitmap+copy_offset, len);
- mutex_exit(&ip->bi_bmpmutex);
-
- ip->bi_state |= (DSW_CNTSHDBITS|DSW_CNTCPYBITS);
-
- return (0);
-}
-
-
-/*
- * Or the shadow bitmap in to the copy bitmap, clear the
- * shadow bitmap.
- */
-static int
-_ii_km_orbm(_ii_info_t *ip)
-{
- unsigned char *copy, *shd;
- int copy_offset, shd_offset;
- int len;
-
- len = FBA_SIZE(ip->bi_copyfba - ip->bi_shdfba);
- shd_offset = FBA_SIZE(ip->bi_shdfba);
- copy_offset = FBA_SIZE(ip->bi_copyfba);
- shd = ip->bi_bitmap + shd_offset;
- copy = ip->bi_bitmap + copy_offset;
-
- mutex_enter(&ip->bi_bmpmutex);
- while (len-- > 0)
- *copy++ |= *shd++;
- mutex_exit(&ip->bi_bmpmutex);
-
- ip->bi_state |= (DSW_CNTSHDBITS|DSW_CNTCPYBITS);
-
- return (0);
-}
-
-/*
- * _ii_km_tst_shd_bit
- * Determine if a chunk has been copied to the shadow device
- *
- * Calling/Exit State:
- * Returns 1 if the modified bit has been set for the shadow device,
- * otherwise returns 0.
- */
-
-static int
-_ii_km_tst_shd_bit(_ii_info_t *ip, chunkid_t chunk)
-{
- unsigned char *bmp;
- int bmp_offset;
- int rc;
-
- bmp_offset = FBA_SIZE(ip->bi_shdfba);
- bmp = ip->bi_bitmap + bmp_offset;
-
- mutex_enter(&ip->bi_bmpmutex);
- rc = DSW_BIT_ISSET(bmp[chunk/DSW_BITS], chunk%DSW_BITS);
- mutex_exit(&ip->bi_bmpmutex);
-
- return (rc);
-}
-
-
-/*
- * _ii_km_set_shd_bit
- * Records that a chunk has been copied to the shadow device
- */
-
-static int
-_ii_km_set_shd_bit(_ii_info_t *ip, chunkid_t chunk)
-{
- unsigned char *bmp;
- int bmp_offset;
-
- bmp_offset = FBA_SIZE(ip->bi_shdfba);
- bmp = ip->bi_bitmap + bmp_offset;
-
- mutex_enter(&ip->bi_bmpmutex);
- if (DSW_BIT_ISSET(bmp[chunk/DSW_BITS], chunk%DSW_BITS) == 0) {
- DSW_BIT_SET(bmp[chunk/DSW_BITS], chunk%DSW_BITS);
- if ((ip->bi_state & DSW_CNTSHDBITS) == 0)
- ip->bi_shdbits++;
- }
- mutex_exit(&ip->bi_bmpmutex);
-
- return (0);
-}
-
-/*
- * _ii_km_tst_copy_bit
- * Determine if a chunk needs to be copied during updates.
- *
- * Calling/Exit State:
- * Returns 1 if the copy bit for the chunk is set,
- * otherwise returns 0
- */
-
-static int
-_ii_km_tst_copy_bit(_ii_info_t *ip, chunkid_t chunk)
-{
- unsigned char *bmp;
- int bmp_offset;
- int rc;
-
- bmp_offset = FBA_SIZE(ip->bi_copyfba);
- bmp = ip->bi_bitmap + bmp_offset;
-
- mutex_enter(&ip->bi_bmpmutex);
- rc = DSW_BIT_ISSET(bmp[chunk/DSW_BITS], chunk%DSW_BITS);
- mutex_exit(&ip->bi_bmpmutex);
-
- return (rc);
-}
-
-
-/*
- * _ii_km_set_copy_bit
- * Records that a chunk has been copied to the shadow device
- */
-
-static int
-_ii_km_set_copy_bit(_ii_info_t *ip, chunkid_t chunk)
-{
- unsigned char *bmp;
- int bmp_offset;
-
- bmp_offset = FBA_SIZE(ip->bi_copyfba);
- bmp = ip->bi_bitmap + bmp_offset;
-
- mutex_enter(&ip->bi_bmpmutex);
- if (DSW_BIT_ISSET(bmp[chunk/DSW_BITS], chunk%DSW_BITS) == 0) {
- DSW_BIT_SET(bmp[chunk/DSW_BITS], chunk%DSW_BITS);
- if ((ip->bi_state & DSW_CNTCPYBITS) == 0)
- ip->bi_copybits++;
- }
- mutex_exit(&ip->bi_bmpmutex);
-
- return (0);
-}
-
-
-/*
- * _ii_km_clr_copy_bits
- * Records that a chunk has been cleared on the shadow device
- */
-
-static int
-_ii_km_clr_copy_bits(_ii_info_t *ip, chunkid_t chunk, int nchunks)
-{
- unsigned char *bmp;
- int bmp_offset;
-
- bmp_offset = FBA_SIZE(ip->bi_copyfba);
- bmp = ip->bi_bitmap + bmp_offset;
-
- mutex_enter(&ip->bi_bmpmutex);
- for (; nchunks-- > 0; chunk++) {
- DSW_BIT_CLR(bmp[chunk/DSW_BITS], chunk%DSW_BITS);
- if (ip->bi_copybits > 0)
- ip->bi_copybits--;
- }
- mutex_exit(&ip->bi_bmpmutex);
-
- return (0);
-}
-
-/*
- * _ii_km_fill_copy_bmp
- * Fills the copy bitmap with 1's.
- */
-
-static int
-_ii_km_fill_copy_bmp(_ii_info_t *ip)
-{
- int len;
- unsigned char *bmp;
- int bmp_offset;
-
- bmp_offset = FBA_SIZE(ip->bi_copyfba);
- bmp = ip->bi_bitmap + bmp_offset;
-
- len = FBA_SIZE(ip->bi_copyfba - ip->bi_shdfba);
-
- mutex_enter(&ip->bi_bmpmutex);
- while (len-- > 0)
- *bmp++ = (unsigned char)0xff;
- mutex_exit(&ip->bi_bmpmutex);
-
- ip->bi_state |= (DSW_CNTSHDBITS|DSW_CNTCPYBITS);
-
- return (0);
-}
-
-/*
- * _ii_km_load_bmp
- * Load bitmap from persistent storage.
- */
-
-static int
-_ii_km_load_bmp(_ii_info_t *ip, int flag)
-{
- nsc_off_t bmp_offset;
- nsc_size_t bitmap_size;
- int rc;
-
- if (ip->bi_flags & DSW_BMPOFFLINE)
- return (EIO);
-
- if (ip->bi_bitmap == NULL) {
- bitmap_size = FBA_SIZE(2 * (ip->bi_copyfba - ip->bi_shdfba) +
- ip->bi_shdfba);
- ip->bi_bitmap = nsc_kmem_zalloc(bitmap_size, KM_SLEEP,
- _ii_local_mem);
- }
- if (flag)
- return (0); /* just create an empty bitmap */
- bmp_offset = FBA_SIZE(ip->bi_shdfba);
- rc = _ii_nsc_io(ip, KS_BMP, ip->bi_bmpfd, NSC_RDBUF, ip->bi_shdfba,
- ip->bi_bitmap + bmp_offset,
- 2 * FBA_SIZE(ip->bi_copyfba - ip->bi_shdfba));
- if (!II_SUCCESS(rc))
- _ii_error(ip, DSW_BMPOFFLINE);
-
- ip->bi_state |= (DSW_CNTSHDBITS|DSW_CNTCPYBITS);
-
- return (rc);
-}
-
-/*
- * _ii_km_save_bmp
- * Save bitmap to persistent storage.
- */
-
-static int
-_ii_km_save_bmp(_ii_info_t *ip, int flag)
-{
- int bmp_offset;
- int bitmap_size;
- int rc;
-
- bmp_offset = FBA_SIZE(ip->bi_shdfba);
- if (ip->bi_flags & DSW_BMPOFFLINE)
- rc = EIO;
- else {
- rc = _ii_nsc_io(ip, KS_BMP, ip->bi_bmpfd, NSC_WRBUF,
- ip->bi_shdfba, ip->bi_bitmap + bmp_offset,
- 2 * FBA_SIZE(ip->bi_copyfba - ip->bi_shdfba));
- if (!II_SUCCESS(rc))
- _ii_error(ip, DSW_BMPOFFLINE);
- }
-
- if (flag && ip->bi_bitmap) { /* dispose of bitmap memory */
- bitmap_size = FBA_SIZE(2 * (ip->bi_copyfba - ip->bi_shdfba) +
- ip->bi_shdfba);
- nsc_kmem_free(ip->bi_bitmap, bitmap_size);
- ip->bi_bitmap = NULL;
- }
-
- return (rc);
-}
-
-/*
- * _ii_km_next_copy_bit
- * Find next set copy bit.
- *
- * Returns the next bits set in the copy bitmap, with the corresponding chunks
- * locked. Used to cut down on the number of times the bmpmutex is acquired.
- */
-
-static chunkid_t
-_ii_km_next_copy_bit(_ii_info_t *ip, chunkid_t chunk, chunkid_t maxchunk,
- int want, int *got)
-{
- unsigned char *bmp;
- int bmp_offset;
- int nextchunk;
-
- *got = 0;
- bmp_offset = FBA_SIZE(ip->bi_copyfba);
- bmp = ip->bi_bitmap + bmp_offset;
-
- mutex_enter(&ip->bi_bmpmutex);
- for (; chunk < maxchunk; chunk++) {
- if (DSW_BIT_ISSET(bmp[chunk/DSW_BITS], chunk%DSW_BITS)) {
- /*
- * trylock won't sleep so can use while
- * holding bi_bmpmutex.
- */
- if (!_ii_trylock_chunk(ip, chunk)) {
- mutex_exit(&ip->bi_bmpmutex);
- _ii_lock_chunk(ip, chunk);
- *got = 1;
-
- DTRACE_PROBE(_ii_km_next_copy_bit);
-
- return (chunk);
- }
- *got = 1;
- for (nextchunk = chunk + 1;
- *got < want && nextchunk < maxchunk; nextchunk++) {
- if (!DSW_BIT_ISSET(bmp[nextchunk/DSW_BITS],
- nextchunk%DSW_BITS))
- break;
- if (_ii_trylock_chunk(ip, nextchunk))
- (*got)++;
- else
- break;
- }
- mutex_exit(&ip->bi_bmpmutex);
-
- DTRACE_PROBE(_ii_km_next_copy_bit);
- return (chunk);
- }
- }
- mutex_exit(&ip->bi_bmpmutex);
-
- return (maxchunk + 1);
-}
-
-/*
- * _ii_km_change_bmp
- * copy change bitmap to memory
- */
-
-static int
-_ii_km_change_bmp(_ii_info_t *ip, unsigned char *ptr)
-/* ARGSUSED */
-{
- int start_offset;
- int bm_size;
- unsigned char *q;
-
- bm_size = FBA_SIZE(DSW_BM_FBA_LEN(ip->bi_size));
-
- start_offset = FBA_SIZE(ip->bi_shdfba);
- bcopy(ip->bi_bitmap + start_offset, ptr, bm_size);
-
- start_offset = FBA_SIZE(ip->bi_copyfba);
- q = ip->bi_bitmap + start_offset;
- while (bm_size-- > 0)
- *ptr |= *q;
-
- return (0);
-}
-
-/*
- * Count bits set in the bit map.
- */
-static int
-_ii_km_cnt_bits(_ii_info_t *ip, nsc_off_t bm_offset, nsc_size_t *counter,
- int bm_size)
-{
- int start_offset;
- int i;
- nsc_size_t j, k;
- unsigned char *cp;
-
- start_offset = FBA_SIZE(bm_offset);
-
- cp = ip->bi_bitmap + start_offset;
- for (i = k = 0; i < bm_size; i++)
- for (j = (unsigned)*cp++; j; j &= j - 1)
- k++;
- *counter = k;
-
- return (0);
-}
-
-/*
- * Or the shadow bitmap in to the copy bitmap, clear the
- * shadow bitmap.
- */
-static int
-_ii_km_join_bmp(_ii_info_t *dest_ip, _ii_info_t *src_ip)
-{
- uchar_t *dest, *src;
- nsc_size_t bm_size;
-
- dest = dest_ip->bi_bitmap + FBA_SIZE(dest_ip->bi_shdfba);
- src = src_ip->bi_bitmap + FBA_SIZE(src_ip->bi_shdfba);
- bm_size = FBA_SIZE(DSW_BM_FBA_LEN(dest_ip->bi_size));
-
- while (bm_size-- > 0)
- *dest++ |= *src++;
-
- dest_ip->bi_state |= (DSW_CNTSHDBITS|DSW_CNTCPYBITS);
-
- return (0);
-}
-
-static _ii_bmp_ops_t kmem_buf_bmp = {
- _ii_km_co_bmp,
- _ii_km_ci_bmp,
- _ii_km_zerobm,
- _ii_km_copybm,
- _ii_km_orbm,
- _ii_km_tst_shd_bit,
- _ii_km_set_shd_bit,
- _ii_km_tst_copy_bit,
- _ii_km_set_copy_bit,
- _ii_km_clr_copy_bits,
- _ii_km_next_copy_bit,
- _ii_km_fill_copy_bmp,
- _ii_km_load_bmp,
- _ii_km_save_bmp,
- _ii_km_change_bmp,
- _ii_km_cnt_bits,
- _ii_km_join_bmp
-};
-
-
-static int
-ii_read_volume(_ii_info_t *ip, int mst_src, nsc_buf_t *srcbuf,
- nsc_buf_t *dstbuf, chunkid_t chunk_num, nsc_off_t fba, nsc_size_t len)
-{
- int rc;
- nsc_buf_t *tmp;
- nsc_off_t mapped_fba;
- chunkid_t mapped_chunk;
- int overflow;
-
- if (mst_src || (ip->bi_flags&DSW_TREEMAP) == 0) {
- /* simple read with optional copy */
- if (mst_src) {
- II_NSC_READ(ip, master, rc, srcbuf, fba, len, 0);
- } else {
- II_NSC_READ(ip, shadow, rc, srcbuf, fba, len, 0);
- }
- if (dstbuf && II_SUCCESS(rc)) {
- rc = nsc_copy(srcbuf, dstbuf, fba, fba, len);
- }
-
- return (rc);
- }
- /* read from mapped shadow into final buffer */
- mapped_chunk = ii_tsearch(ip, chunk_num);
- if (mapped_chunk == II_NULLNODE)
- return (EIO);
- overflow = II_ISOVERFLOW(mapped_chunk);
- if (overflow)
- mapped_chunk = II_2OVERFLOW(mapped_chunk);
- /* convert chunk number from tsearch into final fba */
- mapped_fba = DSW_CHK2FBA(mapped_chunk) + (fba % DSW_SIZE);
- tmp = NULL;
- if (overflow) {
- (void) nsc_reserve(OVRFD(ip), NSC_MULTI);
- II_READ_START(ip, overflow);
- rc = nsc_alloc_buf(OVRFD(ip), mapped_fba, len, NSC_RDBUF, &tmp);
- II_READ_END(ip, overflow, rc, len);
- } else {
- II_READ_START(ip, shadow);
- rc = nsc_alloc_buf(SHDFD(ip), mapped_fba, len, NSC_RDBUF, &tmp);
- II_READ_END(ip, shadow, rc, len);
- }
- if (II_SUCCESS(rc)) {
- if (dstbuf == NULL)
- dstbuf = srcbuf;
- rc = nsc_copy(tmp, dstbuf, mapped_fba, fba, len);
- (void) nsc_free_buf(tmp);
- }
- if (overflow)
- nsc_release(OVRFD(ip));
-
- return (rc);
-}
-
-/*
- * _ii_fill_buf
- * Read data from the required device
- *
- * Calling/Exit State:
- * Returns 0 if the data was read successfully, otherwise
- * error code.
- *
- * Description:
- * Reads the data from fba_pos for length fba_len from the
- * required device. This data may be a mix of data from the master
- * device and the shadow device, depending on the state of the
- * bitmaps.
- */
-
-static int
-_ii_fill_buf(ii_fd_t *bfd, nsc_off_t fba_pos, nsc_size_t fba_len, int flag,
- nsc_buf_t **handle, nsc_buf_t **handle2)
-{
- _ii_info_t *ip = bfd->ii_info;
- _ii_info_t *xip;
- int second_shd = 0;
- nsc_off_t temp_fba;
- nsc_size_t temp_len;
- nsc_size_t bmp_len;
- chunkid_t chunk_num;
- int rc;
- int fill_from_pair;
- int rtype = SHDR|BMP;
- nsc_buf_t *second_buf = NULL;
-
- if (flag&NSC_RDAHEAD)
- return (NSC_DONE);
-
- chunk_num = fba_pos / DSW_SIZE;
- temp_fba = fba_pos;
- temp_len = fba_len;
-
- /*
- * If the master is being updated from a shadow we need to fill from
- * the correct shadow volume.
- */
- if (NSHADOWS(ip) && bfd->ii_shd == 0) {
- for (xip = ip->bi_head; xip; xip = xip->bi_sibling) {
- if (xip == ip)
- continue;
- if (xip->bi_flags &DSW_COPYINGS) {
- second_shd = 1;
- ip = xip;
- if ((rc = _ii_rsrv_devs(ip, rtype,
- II_INTERNAL)) != 0)
- return (EIO);
- rc = nsc_alloc_buf(SHDFD(ip), fba_pos, fba_len,
- (flag&NSC_RDAHEAD)|NSC_MIXED, &second_buf);
- if (!II_SUCCESS(rc)) {
- rc = EIO;
- goto out;
- }
- handle2 = &second_buf;
- break;
- }
- }
- }
-
- while (temp_len > 0) {
- if ((temp_fba + temp_len) > DSW_CHK2FBA(chunk_num + 1)) {
- bmp_len = DSW_CHK2FBA(chunk_num + 1) - temp_fba;
- temp_len -= bmp_len;
- } else {
- bmp_len = temp_len;
- temp_len = 0;
- }
-
- fill_from_pair = 0;
-
- if ((ip->bi_flags & DSW_COPYINGM) == DSW_COPYINGM) {
- rc = II_TST_COPY_BIT(ip, chunk_num);
- /* Treat a failed bitmap volume as a clear bit */
- if (rc > 0) {
- /* Copy bit set */
- if (bfd->ii_shd) {
- if (*handle2)
- fill_from_pair = 1;
- else {
- rc = EIO;
- goto out;
- }
- }
- }
- }
- if ((ip->bi_flags & DSW_COPYINGS) == DSW_COPYINGS) {
- rc = II_TST_COPY_BIT(ip, chunk_num);
- /* Treat a failed bitmap volume as a clear bit */
- if (rc > 0) {
- /* Copy bit set */
- if (bfd->ii_shd == 0) {
- if (*handle2 ||
- (ip->bi_flags&DSW_TREEMAP))
- fill_from_pair = 1;
- else {
- rc = EIO;
- goto out;
- }
- }
- }
- }
- if (((ip->bi_flags & DSW_GOLDEN) == 0) && bfd->ii_shd) {
- /* Dependent shadow read */
-
- rc = II_TST_SHD_BIT(ip, chunk_num);
- if (rc < 0) {
- rc = EIO;
- goto out;
- }
- if (rc == 0) {
- /* Shadow bit clear */
- if (*handle2)
- fill_from_pair = 1;
- else {
- rc = EIO;
- goto out;
- }
- }
- }
-
- if (fill_from_pair) {
- /* it matters now */
- if (ip->bi_flags & (DSW_MSTOFFLINE | DSW_SHDOFFLINE)) {
- rc = EIO;
- goto out;
- }
- if (*handle2 == NULL &&
- (ip->bi_flags&DSW_TREEMAP) == 0) {
- rc = EIO;
- goto out;
- }
- rc = ii_read_volume(ip, bfd->ii_shd,
- *handle2, *handle, chunk_num, temp_fba, bmp_len);
- if (!II_SUCCESS(rc)) {
- _ii_error(ip, DSW_MSTOFFLINE);
- _ii_error(ip, DSW_SHDOFFLINE);
- goto out;
- }
- } else {
- if (bfd->ii_shd && (ip->bi_flags & DSW_SHDOFFLINE)) {
- rc = EIO;
- goto out;
- }
- if ((bfd->ii_shd == 0) &&
- (ip->bi_flags & DSW_MSTOFFLINE)) {
- rc = EIO;
- goto out;
- }
- rc = ii_read_volume(ip, !(bfd->ii_shd), *handle, NULL,
- chunk_num, temp_fba, bmp_len);
- if (!II_SUCCESS(rc)) {
- if (bfd->ii_shd)
- _ii_error(ip, DSW_SHDOFFLINE);
- else
- _ii_error(ip, DSW_MSTOFFLINE);
- goto out;
- }
- }
-
- temp_fba += bmp_len;
- chunk_num++;
- }
-
- rc = 0;
-out:
- if (second_buf)
- (void) nsc_free_buf(second_buf);
- if (second_shd)
- _ii_rlse_devs(ip, rtype);
-
- return (rc);
-}
-
-
-/*
- * _ii_shadow_write
- * Perform any copy on write required by a write buffer request
- *
- * Calling/Exit State:
- * Returns 0 on success, otherwise error code.
- *
- */
-
-static int
-_ii_shadow_write(ii_fd_t *bfd, nsc_off_t pos, nsc_size_t len)
-{
- _ii_info_t *ip = bfd->ii_info;
- chunkid_t chunk_num;
- int rc;
- int flag;
- int hanging;
-
- DTRACE_PROBE2(_ii_shadow_write_start, nsc_off_t, pos, nsc_size_t, len);
-
- /* fail immediately if config DB is unavailable */
- if ((ip->bi_flags & DSW_CFGOFFLINE) == DSW_CFGOFFLINE) {
- return (EIO);
- }
-
- chunk_num = pos / DSW_SIZE;
-
- if (bfd->ii_shd)
- flag = 0; /* To shadow */
- else
- flag = CV_SHD2MST; /* To master */
-
- mutex_enter(&ip->bi_mutex);
- ip->bi_shdref++;
- mutex_exit(&ip->bi_mutex);
- hanging = (ip->bi_flags&DSW_HANGING) != 0;
-
- for (; (chunk_num >= 0) &&
- DSW_CHK2FBA(chunk_num) < (pos + len); chunk_num++) {
-
- if (!hanging)
- _ii_lock_chunk(ip, chunk_num);
- rc = _ii_copy_on_write(ip, flag, chunk_num, 1);
-
- /*
- * Set the shadow bit when a small shadow has overflowed so
- * that ii_read_volume can return an error if an attempt is
- * made to read that chunk.
- */
- if (!hanging) {
- if (rc == 0 ||
- (rc == EIO && (ip->bi_flags&DSW_OVERFLOW) != 0))
- (void) II_SET_SHD_BIT(ip, chunk_num);
- _ii_unlock_chunk(ip, chunk_num);
- }
- }
-
- mutex_enter(&ip->bi_mutex);
- ip->bi_shdref--;
- if (ip->bi_state & DSW_CLOSING) {
- if (total_ref(ip) == 0) {
- cv_signal(&ip->bi_closingcv);
- }
- }
- mutex_exit(&ip->bi_mutex);
-
- /* did the bitmap fail during this process? */
- return (ip->bi_flags & DSW_CFGOFFLINE? EIO : 0);
-}
-
-/*
- * _ii_alloc_buf
- * Allocate a buffer of data
- *
- * Calling/Exit State:
- * Returns 0 for success, < 0 for async I/O, > 0 is an error code.
- *
- * Description:
- * For a write buffer, calls dsw_shadow_write to perform any necessary
- * copy on write operations, then allocates the real buffers from the
- * underlying devices.
- * For a read buffer, allocates the real buffers from the underlying
- * devices, then calls _ii_fill_buf to fill the required buffer.
- * For a buffer that is neither read nor write, just allocate the
- * buffers so that a _ii_fill_buf can be done later by _ii_read.
- */
-
-static int
-_ii_alloc_buf(ii_fd_t *bfd, nsc_off_t pos, nsc_size_t len, int flag,
- ii_buf_t **ptr)
-{
- _ii_info_t *ip = bfd->ii_info;
- ii_buf_t *h;
- int raw = II_RAW(bfd);
- int rc = 0;
- int ioflag;
- int fbuf = 0, fbuf2 = 0, abuf = 0;
- int rw_ent = 0;
-
- if (bfd->ii_bmp) {
- DTRACE_PROBE(_ii_alloc_buf_end);
- /* any I/O to the bitmap device is barred */
- return (EIO);
- }
-
- if (len == 0) {
- DTRACE_PROBE(_ii_alloc_buf_end);
- return (EINVAL);
- }
-
- /* Bounds checking */
- if (pos + len > ip->bi_size) {
- if (ii_debug > 1)
- cmn_err(CE_NOTE,
- "!ii: Attempt to access beyond end of ii volume");
- DTRACE_PROBE(_ii_alloc_buf_end);
- return (EIO);
- }
-
- h = *ptr;
- if (h == NULL) {
- h = (ii_buf_t *)_ii_alloc_handle(NULL, NULL, NULL, bfd);
- if (h == NULL) {
- DTRACE_PROBE(_ii_alloc_buf_end);
- return (ENOMEM);
- }
- }
-
- /*
- * Temporary nsc_reserve of bitmap and other device.
- * This device has already been reserved by the preceding _ii_attach.
- * Corresponding nsc_release is in _ii_free_buf.
- */
-
- h->ii_rsrv = BMP | (raw ? (bfd->ii_shd ? MSTR : SHDR)
- : (bfd->ii_shd ? MST : SHD));
-
- if (!bfd->ii_shd)
- ip = ip->bi_master;
-
- rw_enter(&ip->bi_linkrw, RW_READER);
- rw_ent = 1;
- if (ip->bi_shdfd == NULL || (ip->bi_flags & DSW_SHDEXPORT) ==
- DSW_SHDEXPORT)
- h->ii_rsrv &= ~(SHD|SHDR);
- if ((rc = _ii_rsrv_devs(ip, h->ii_rsrv, II_EXTERNAL)) != 0) {
- rw_exit(&ip->bi_linkrw);
- rw_ent = 0;
- h->ii_rsrv = NULL;
- goto error;
- }
-
- if (flag & NSC_WRBUF) {
- rc = _ii_shadow_write(bfd, pos, len);
- if (!II_SUCCESS(rc))
- goto error;
- }
-
- if (!(flag & NSC_RDAHEAD))
- ioflag = flag & ~(NSC_RDBUF);
- else
- ioflag = flag;
-
- if (bfd->ii_shd) {
- /*
- * SHADOW
- */
-
- if (ip->bi_flags & DSW_SHDEXPORT) {
- rc = EIO;
- goto error;
- }
- /*
- * The master device buffer has to be allocated first
- * so that deadlocks are avoided.
- */
- DTRACE_PROBE(AllocBufFor_SHADOW);
-
- if ((ip->bi_flags & (DSW_MSTOFFLINE|DSW_SHDIMPORT)) == 0) {
- rc = nsc_alloc_buf(MSTFD(ip), pos, len,
- (flag&NSC_RDAHEAD)|NSC_MIXED, &h->ii_bufp2);
- if (!II_SUCCESS(rc)) {
- if (ii_debug > 2)
- cmn_err(CE_WARN, "!ii: "
- "Join/write-S race detected\n");
- if (h->ii_bufp2)
- (void) nsc_free_buf(h->ii_bufp2);
- h->ii_bufp2 = NULL;
- /*
- * Carry on as this will not matter if
- * _ii_fill_buf is not called, or if
- * it is called but doesn't need to read this
- * volume.
- */
- rc = 0;
- }
- fbuf2 = 1;
- }
-
- if (ip->bi_flags & DSW_SHDOFFLINE) {
- rc = EIO;
- goto error;
- }
- if ((ip->bi_flags)&DSW_TREEMAP) {
- rc = nsc_alloc_abuf(pos, len, 0, &h->ii_abufp);
- if (!II_SUCCESS(rc)) {
- _ii_error(ip, DSW_SHDOFFLINE);
- goto error;
- }
- abuf = 1;
- } else {
- II_ALLOC_BUF(ip, shadow, rc, SHDFD(ip), pos, len,
- ioflag, &h->ii_bufp); /* do not read yet */
- if (!II_SUCCESS(rc)) {
- _ii_error(ip, DSW_SHDOFFLINE);
- goto error;
- }
- fbuf = 1;
- }
- } else {
- /*
- * MASTER
- */
-
- /*
- * The master device buffer has to be allocated first
- * so that deadlocks are avoided.
- */
-
- if (ip->bi_flags & (DSW_MSTOFFLINE|DSW_SHDIMPORT)) {
- rc = EIO;
- goto error;
- }
-
- DTRACE_PROBE(AllocBufFor_MASTER);
-
- II_ALLOC_BUF(ip, master, rc, MSTFD(ip), pos, len, ioflag,
- &h->ii_bufp); /* do not read yet */
- if (!II_SUCCESS(rc)) {
- _ii_error(ip, DSW_MSTOFFLINE);
- goto error;
- }
- fbuf = 1;
-
- /*
- * If shadow FD and (dependent set OR copying) and
- * not (compact dependent && shadow offline && shadow exported)
- */
- if ((ip->bi_shdfd) &&
- ((ip->bi_flags & DSW_COPYINGP) ||
- (!(ip->bi_flags & DSW_GOLDEN))) &&
- (!(ip->bi_flags &
- (DSW_TREEMAP|DSW_SHDOFFLINE|DSW_SHDEXPORT)))) {
- rc = nsc_alloc_buf(SHDFD(ip), pos, len,
- (flag&NSC_RDAHEAD)|NSC_MIXED, &h->ii_bufp2);
- if (!II_SUCCESS(rc)) {
- if (ii_debug > 2)
- cmn_err(CE_WARN, "!ii: "
- "Join/write-M race detected\n");
- if (h->ii_bufp2)
- (void) nsc_free_buf(h->ii_bufp2);
- h->ii_bufp2 = NULL;
- /*
- * Carry on as this will not matter if
- * _ii_fill_buf is not called, or if
- * it is called but doesn't need to read this
- * volume.
- */
- rc = 0;
- }
- fbuf2 = 1;
- }
- }
-
- if (flag & NSC_RDBUF)
- rc = _ii_fill_buf(bfd, pos, len, flag,
- h->ii_abufp ? &h->ii_abufp : &h->ii_bufp, &h->ii_bufp2);
-
-error:
- if (II_SUCCESS(rc)) {
- h->ii_bufh.sb_vec = h->ii_abufp ? h->ii_abufp->sb_vec :
- h->ii_bufp->sb_vec;
- h->ii_bufh.sb_error = 0;
- h->ii_bufh.sb_flag |= flag;
- h->ii_bufh.sb_pos = pos;
- h->ii_bufh.sb_len = len;
- } else {
- h->ii_bufh.sb_error = rc;
- if (h->ii_bufp2 && fbuf2) {
- (void) nsc_free_buf(h->ii_bufp2);
- h->ii_bufp2 = NULL;
- }
- if (h->ii_bufp && fbuf) {
- (void) nsc_free_buf(h->ii_bufp);
- h->ii_bufp = NULL;
- }
- if (h->ii_abufp && abuf) {
- (void) nsc_free_buf(h->ii_abufp);
- h->ii_abufp = NULL;
- }
-
- if (h->ii_rsrv) {
- /*
- * Release temporary reserve - reserved above.
- */
- _ii_rlse_devs(ip, h->ii_rsrv);
- h->ii_rsrv = NULL;
- }
- if (rw_ent)
- rw_exit(&ip->bi_linkrw);
- }
-
- return (rc);
-}
-
-
-/*
- * _ii_free_buf
- */
-
-static int
-_ii_free_buf(ii_buf_t *h)
-{
- ii_fd_t *bfd;
- int rsrv;
- int rc;
-
- if (h->ii_abufp == NULL) {
- rc = nsc_free_buf(h->ii_bufp);
- } else {
- rc = nsc_free_buf(h->ii_abufp);
- h->ii_abufp = NULL;
- }
- if (!II_SUCCESS(rc))
- return (rc);
- if (h->ii_bufp2) {
- rc = nsc_free_buf(h->ii_bufp2);
- h->ii_bufp2 = NULL;
- if (!II_SUCCESS(rc))
- return (rc);
- }
-
- bfd = h->ii_fd;
- rsrv = h->ii_rsrv;
-
- if ((h->ii_bufh.sb_flag & NSC_HALLOCATED) == 0) {
- rc = _ii_free_handle(h, h->ii_fd);
- if (!II_SUCCESS(rc))
- return (rc);
- } else {
- h->ii_bufh.sb_flag = NSC_HALLOCATED;
- h->ii_bufh.sb_vec = NULL;
- h->ii_bufh.sb_error = 0;
- h->ii_bufh.sb_pos = 0;
- h->ii_bufh.sb_len = 0;
- h->ii_rsrv = NULL;
- }
-
- /*
- * Release temporary reserve - reserved in _ii_alloc_buf.
- */
-
- if (rsrv)
- _ii_rlse_devs(bfd->ii_info, rsrv);
- rw_exit(&bfd->ii_info->bi_linkrw);
-
- return (0);
-}
-
-
-/*
- * _ii_open
- * Open a device
- *
- * Calling/Exit State:
- * Returns a token to identify the shadow device.
- *
- * Description:
- * Performs the housekeeping operations associated with an upper layer
- * of the nsc stack opening a shadowed device.
- */
-
-/* ARGSUSED */
-
-static int
-_ii_open(char *path, int flag, blind_t *cdp, nsc_iodev_t *iodev)
-{
- _ii_info_t *ip;
- _ii_overflow_t *op;
- ii_fd_t *bfd;
- int is_mst = 0;
- int is_shd = 0;
- int raw = (flag & NSC_CACHE) == 0;
-
- bfd = nsc_kmem_zalloc(sizeof (*bfd), KM_SLEEP, _ii_local_mem);
- if (!bfd)
- return (ENOMEM);
-
- DTRACE_PROBE1(_ii_open_mutex,
- ii_fd_t *, bfd);
-
- mutex_enter(&_ii_info_mutex);
-
- for (ip = _ii_info_top; ip; ip = ip->bi_next) {
- if (strcmp(path, ii_pathname(ip->bi_mstfd)) == 0) {
- is_mst = 1;
- break;
- } else if (strcmp(path, ip->bi_keyname) == 0) {
- is_shd = 1;
- break;
- } else if (strcmp(path, ii_pathname(ip->bi_bmpfd)) == 0)
- break;
- }
-
- if (is_mst)
- ip = ip->bi_master;
-
- if (ip && ip->bi_disabled && !(ip->bi_state & DSW_MULTIMST)) {
- DTRACE_PROBE(_ii_open_Disabled);
- mutex_exit(&_ii_info_mutex);
- return (EINTR);
- }
-
- if (!ip) {
- /* maybe it's an overflow */
- mutex_exit(&_ii_info_mutex);
- mutex_enter(&_ii_overflow_mutex);
- for (op = _ii_overflow_top; op; op = op->ii_next) {
- if (strcmp(path, op->ii_volname) == 0)
- break;
- }
- mutex_exit(&_ii_overflow_mutex);
-
- if (!op) {
- nsc_kmem_free(bfd, sizeof (*bfd));
- DTRACE_PROBE(_ii_open_end_EINVAL);
- return (EINVAL);
- }
- bfd->ii_ovr = 1;
- bfd->ii_oflags = flag;
- bfd->ii_optr = op;
- *cdp = (blind_t)bfd;
-
- DTRACE_PROBE(_ii_open_end_overflow);
- return (0);
- }
- mutex_enter(&ip->bi_mutex);
- ip->bi_ioctl++;
- mutex_exit(&_ii_info_mutex);
-
- if (is_mst) {
- if (raw) {
- ip->bi_mstr_iodev = NULL; /* set in attach */
- ip->bi_mstrref++;
- } else {
- ip->bi_mst_iodev = NULL; /* set in attach */
- ip->bi_mstref++;
- }
- ip->bi_master->bi_iifd = bfd;
- } else if (is_shd) {
- if (raw) {
- ip->bi_shdr_iodev = NULL; /* set in attach */
- ip->bi_shdrref++;
- } else {
- ip->bi_shd_iodev = NULL; /* set in attach */
- ip->bi_shdref++;
- }
- bfd->ii_shd = 1;
- } else {
- ip->bi_bmpref++;
- ip->bi_bmp_iodev = NULL; /* set in attach */
- bfd->ii_bmp = 1;
- }
-
- _ii_ioctl_done(ip);
- mutex_exit(&ip->bi_mutex);
-
- bfd->ii_info = ip;
- bfd->ii_oflags = flag;
-
- *cdp = (blind_t)bfd;
-
- return (0);
-}
-
-static int
-_ii_openc(char *path, int flag, blind_t *cdp, nsc_iodev_t *iodev)
-{
- return (_ii_open(path, NSC_CACHE|flag, cdp, iodev));
-}
-
-static int
-_ii_openr(char *path, int flag, blind_t *cdp, nsc_iodev_t *iodev)
-{
- return (_ii_open(path, NSC_DEVICE|flag, cdp, iodev));
-}
-
-
-/*
- * _ii_close
- * Close a device
- *
- * Calling/Exit State:
- * Always succeeds - returns 0
- *
- * Description:
- * Performs the housekeeping operations associated with an upper layer
- * of the nsc stack closing a shadowed device.
- */
-
-static int
-_ii_close(bfd)
-ii_fd_t *bfd;
-{
- _ii_info_t *ip = bfd->ii_info;
- _ii_info_dev_t *dip;
- int raw;
-
- if (!ip) {
- ASSERT(bfd->ii_ovr);
- return (0);
- }
-
- raw = II_RAW(bfd);
-
- mutex_enter(&ip->bi_mutex);
-
- if (bfd->ii_shd && raw) {
- dip = &ip->bi_shdrdev;
- } else if (bfd->ii_shd) {
- dip = &ip->bi_shddev;
- } else if (bfd->ii_bmp) {
- dip = &ip->bi_bmpdev;
- } else if (raw) {
- dip = ip->bi_mstrdev;
- } else {
- dip = ip->bi_mstdev;
- }
-
- if (dip) {
- dip->bi_ref--;
- if (dip->bi_ref == 0)
- dip->bi_iodev = NULL;
- }
-
- if (ip->bi_state & DSW_CLOSING) {
- if (total_ref(ip) == 0) {
- cv_signal(&ip->bi_closingcv);
- }
- } else if ((ip->bi_flags & DSW_HANGING) &&
- (ip->bi_head->bi_state & DSW_CLOSING))
- cv_signal(&ip->bi_head->bi_closingcv);
-
- if (!(bfd->ii_shd || bfd->ii_bmp)) /* is master device */
- ip->bi_master->bi_iifd = NULL;
- mutex_exit(&ip->bi_mutex);
-
- nsc_kmem_free(bfd, sizeof (*bfd));
-
- return (0);
-}
-
-/*
- * _ii_alloc_handle
- * Allocate a handle
- *
- */
-
-static nsc_buf_t *
-_ii_alloc_handle(void (*d_cb)(), void (*r_cb)(), void (*w_cb)(), ii_fd_t *bfd)
-{
- ii_buf_t *h;
-
- if (REMOTE_VOL(bfd->ii_shd, bfd->ii_info))
- return (NULL);
-
- h = kmem_alloc(sizeof (*h), KM_SLEEP);
- if (!h)
- return (NULL);
-
- h->ii_abufp = NULL;
- h->ii_bufp = nsc_alloc_handle(II_FD(bfd), d_cb, r_cb, w_cb);
- if (!h->ii_bufp) {
- kmem_free(h, sizeof (*h));
- return (NULL);
- }
- h->ii_bufp2 = NULL;
- h->ii_bufh.sb_flag = NSC_HALLOCATED;
- h->ii_fd = bfd;
- h->ii_rsrv = NULL;
-
- return ((nsc_buf_t *)h);
-}
-
-
-/*
- * _ii_free_handle
- * Free a handle
- *
- */
-
-static int /*ARGSUSED*/
-_ii_free_handle(ii_buf_t *h, ii_fd_t *bfd)
-{
- int rc;
-
- if (h->ii_abufp)
- (void) nsc_free_buf(h->ii_abufp);
- rc = nsc_free_handle(h->ii_bufp);
- if (!II_SUCCESS(rc)) {
- return (rc);
- }
-
- kmem_free(h, sizeof (ii_buf_t));
-
- return (0);
-}
-
-
-/*
- * _ii_attach
- * Attach
- *
- * Calling/Exit State:
- * Returns 0 for success, errno on failure.
- *
- * Description:
- */
-
-static int
-_ii_attach(ii_fd_t *bfd, nsc_iodev_t *iodev)
-{
- _ii_info_t *ip;
- int dev;
- int raw;
- int rc;
- _ii_info_dev_t *infop;
-
- raw = II_RAW(bfd);
-
- DTRACE_PROBE2(_ii_attach_info,
- char *, bfd->ii_shd? "shadow" : "master",
- int, raw);
-
- if (bfd->ii_ovr)
- return (EINVAL);
-
- ip = bfd->ii_info;
- if (ip == NULL)
- return (EINVAL);
-
- mutex_enter(&ip->bi_mutex);
- if (bfd->ii_bmp) {
- infop = &ip->bi_bmpdev;
- } else if (bfd->ii_shd) {
- if (raw) {
- infop = &ip->bi_shdrdev;
- } else {
- infop = &ip->bi_shddev;
- }
- } else if (!bfd->ii_ovr) {
- if (raw) {
- infop = ip->bi_mstrdev;
- } else {
- infop = ip->bi_mstdev;
- }
- }
-
- if (iodev) {
- infop->bi_iodev = iodev;
- nsc_set_owner(infop->bi_fd, infop->bi_iodev);
- }
- mutex_exit(&ip->bi_mutex);
-
- if (bfd->ii_bmp)
- return (EINVAL);
-
- if (raw)
- dev = bfd->ii_shd ? SHDR : MSTR;
- else
- dev = bfd->ii_shd ? SHD : MST;
-
- rc = _ii_rsrv_devs(ip, dev, II_EXTERNAL);
-
- return (rc);
-}
-
-
-/*
- * _ii_detach
- * Detach
- *
- * Calling/Exit State:
- * Returns 0 for success, always succeeds
- *
- * Description:
- */
-
-static int
-_ii_detach(bfd)
-ii_fd_t *bfd;
-{
- int dev;
- int raw;
-
- raw = II_RAW(bfd);
-
- DTRACE_PROBE2(_ii_detach_info,
- char *, bfd->ii_shd? "shadow" : "master",
- int, raw);
-
- if (bfd->ii_bmp)
- return (0);
-
- ASSERT(bfd->ii_info);
- dev = bfd->ii_shd ? (raw ? SHDR : SHD) : (raw ? MSTR : MST);
- _ii_rlse_devs(bfd->ii_info, dev);
-
- return (0);
-}
-
-/*
- * _ii_get_pinned
- *
- */
-
-static int
-_ii_get_pinned(ii_fd_t *bfd)
-{
- int rc;
-
- if (REMOTE_VOL(bfd->ii_shd, bfd->ii_info))
- return (EIO);
-
- rc = nsc_get_pinned(II_FD(bfd));
-
- return (rc);
-}
-
-/*
- * _ii_discard_pinned
- *
- */
-
-static int
-_ii_discard_pinned(ii_fd_t *bfd, nsc_off_t pos, nsc_size_t len)
-{
- int rc;
-
- if (REMOTE_VOL(bfd->ii_shd, bfd->ii_info))
- return (EIO);
- rc = nsc_discard_pinned(II_FD(bfd), pos, len);
-
- return (rc);
-}
-
-/*
- * _ii_partsize
- *
- */
-
-static int
-_ii_partsize(ii_fd_t *bfd, nsc_size_t *ptr)
-{
- /* Always return saved size */
- *ptr = bfd->ii_info->bi_size;
- return (0);
-}
-
-/*
- * _ii_maxfbas
- *
- */
-
-static int
-_ii_maxfbas(ii_fd_t *bfd, int flag, nsc_size_t *ptr)
-{
- int rc;
- int rs;
- int dev;
- _ii_info_t *ip;
-
- ip = bfd->ii_info;
- if (REMOTE_VOL(bfd->ii_shd, ip))
- return (EIO);
-
- dev = ((ip->bi_flags)&DSW_SHDIMPORT) ? SHDR : MSTR;
-
- DTRACE_PROBE1(_ii_maxfbas_info,
- char *, dev == SHDR? "shadow" : "master");
-
- rs = _ii_rsrv_devs(ip, dev, II_INTERNAL);
- rc = nsc_maxfbas((dev == MSTR) ? MSTFD(ip) : SHDFD(ip), flag, ptr);
-
- if (rs == 0)
- _ii_rlse_devs(ip, dev);
-
- return (rc);
-}
-
-/*
- * ii_get_group_list
- */
-_ii_info_t **
-ii_get_group_list(char *group, int *count)
-{
- int i;
- int nip;
- uint64_t hash;
- _ii_info_t **ipa;
- _ii_lsthead_t *head;
- _ii_lstinfo_t *np;
-
- hash = nsc_strhash(group);
-
- for (head = _ii_group_top; head; head = head->lst_next) {
- if (hash == head->lst_hash && strncmp(head->lst_name,
- group, DSW_NAMELEN) == 0)
- break;
- }
-
- if (!head) {
- return (NULL);
- }
-
- /* Count entries */
- for (nip = 0, np = head->lst_start; np; np = np->lst_next)
- ++nip;
-
- ASSERT(nip > 0);
-
- ipa = kmem_zalloc(sizeof (_ii_info_t *) * nip, KM_SLEEP);
-
- np = head->lst_start;
-
- for (i = 0; i < nip; i++) {
- ASSERT(np != 0);
-
- ipa[i] = np->lst_ip;
- np = np->lst_next;
- }
-
- *count = nip;
- return (ipa);
-}
-
-/*
- * _ii_pinned
- *
- */
-
-static void
-_ii_pinned(_ii_info_dev_t *dip, nsc_off_t pos, nsc_size_t len)
-{
- DTRACE_PROBE3(_ii_pinned_start, nsc_iodev_t, dip->bi_iodev,
- nsc_off_t, pos, nsc_size_t, len);
-
- nsc_pinned_data(dip->bi_iodev, pos, len);
-
-}
-
-/*
- * _ii_unpinned
- *
- */
-
-static void
-_ii_unpinned(_ii_info_dev_t *dip, nsc_off_t pos, nsc_size_t len)
-{
- nsc_unpinned_data(dip->bi_iodev, pos, len);
-
-}
-
-
-/*
- * _ii_read
- */
-
-static int
-_ii_read(ii_buf_t *h, nsc_off_t pos, nsc_size_t len, int flag)
-{
- int rc;
- void *sb_vec;
- nsc_vec_t **src;
-
- if (REMOTE_VOL(h->ii_fd->ii_shd, h->ii_fd->ii_info))
- rc = EIO;
- else {
- src = h->ii_abufp? &h->ii_abufp->sb_vec : &h->ii_bufp->sb_vec;
- sb_vec = *src;
- *src = h->ii_bufh.sb_vec;
- rc = _ii_fill_buf(h->ii_fd, pos, len, flag,
- h->ii_abufp ? &h->ii_abufp : &h->ii_bufp, &h->ii_bufp2);
- *src = sb_vec;
- }
- if (!II_SUCCESS(rc))
- h->ii_bufh.sb_error = rc;
-
- return (rc);
-}
-
-
-/*
- * _ii_write
- */
-
-static int
-_ii_write(ii_buf_t *h, nsc_off_t pos, nsc_size_t len, int flag)
-{
- int rc;
- ii_fd_t *bfd = h->ii_fd;
- _ii_info_t *ip = bfd->ii_info;
- chunkid_t chunk_num;
- nsc_size_t copy_len;
- nsc_off_t mapped_fba;
- chunkid_t mapped_chunk;
- int overflow;
- nsc_buf_t *tmp;
- void *sb_vec;
-
- if (REMOTE_VOL(h->ii_fd->ii_shd, h->ii_fd->ii_info))
- rc = EIO;
- else if ((ip->bi_flags&DSW_TREEMAP) == 0 || !bfd->ii_shd) {
- sb_vec = h->ii_bufp->sb_vec;
- h->ii_bufp->sb_vec = h->ii_bufh.sb_vec;
- if (bfd->ii_shd) {
- II_NSC_WRITE(ip, shadow, rc, h->ii_bufp, pos, len,
- flag);
- } else {
- II_NSC_WRITE(ip, master, rc, h->ii_bufp, pos, len,
- flag);
- }
- h->ii_bufp->sb_vec = sb_vec;
- } else {
- /* write of mapped shadow buffer */
- rc = 0;
- chunk_num = pos / DSW_SIZE;
- while (len > 0 && II_SUCCESS(rc)) {
- /*
- * don't need to test bitmaps as allocating the
- * write buffer will c-o-write the chunk.
- */
- mapped_chunk = ii_tsearch(ip, chunk_num);
- if (mapped_chunk == II_NULLNODE) {
- rc = EIO;
- break;
- }
- overflow = II_ISOVERFLOW(mapped_chunk);
- if (overflow)
- mapped_chunk = II_2OVERFLOW(mapped_chunk);
- mapped_fba = DSW_CHK2FBA(mapped_chunk) +
- (pos % DSW_SIZE);
- copy_len = DSW_SIZE - (pos % DSW_SIZE);
- if (copy_len > len)
- copy_len = len;
- tmp = NULL;
- if (overflow) {
- (void) nsc_reserve(OVRFD(ip), NSC_MULTI);
- rc = nsc_alloc_buf(OVRFD(ip), mapped_fba,
- copy_len, NSC_WRBUF, &tmp);
- } else
- rc = nsc_alloc_buf(SHDFD(ip), mapped_fba,
- copy_len, NSC_WRBUF, &tmp);
- sb_vec = h->ii_abufp->sb_vec;
- h->ii_abufp->sb_vec = h->ii_bufh.sb_vec;
- if (II_SUCCESS(rc)) {
- rc = nsc_copy(h->ii_abufp, tmp, pos,
- mapped_fba, copy_len);
- }
- if (overflow) {
- II_NSC_WRITE(ip, overflow, rc, tmp, mapped_fba,
- copy_len, flag);
- } else {
- II_NSC_WRITE(ip, shadow, rc, tmp, mapped_fba,
- copy_len, flag);
- }
- h->ii_abufp->sb_vec = sb_vec;
- (void) nsc_free_buf(tmp);
- if (overflow)
- nsc_release(OVRFD(ip));
- /* move on to next chunk */
- pos += copy_len;
- len -= copy_len;
- chunk_num++;
- }
- }
- if (!II_SUCCESS(rc))
- h->ii_bufh.sb_error = rc;
-
- return (rc);
-}
-
-
-/*
- * _ii_zero
- */
-
-static int
-_ii_zero(ii_buf_t *h, nsc_off_t pos, nsc_size_t len, int flag)
-{
- int rc;
- void *sb_vec;
-
- sb_vec = h->ii_bufp->sb_vec;
- h->ii_bufp->sb_vec = h->ii_bufh.sb_vec;
- rc = nsc_zero(h->ii_bufp, pos, len, flag);
- h->ii_bufp->sb_vec = sb_vec;
- if (!II_SUCCESS(rc))
- h->ii_bufh.sb_error = rc;
-
- return (rc);
-}
-
-
-/*
- * _ii_uncommit
- */
-
-static int
-_ii_uncommit(ii_buf_t *h, nsc_off_t pos, nsc_size_t len, int flag)
-{
- int rc;
- void *sb_vec;
-
- sb_vec = h->ii_bufp->sb_vec;
- h->ii_bufp->sb_vec = h->ii_bufh.sb_vec;
- rc = nsc_uncommit(h->ii_bufp, pos, len, flag);
- h->ii_bufp->sb_vec = sb_vec;
- if (!II_SUCCESS(rc))
- h->ii_bufh.sb_error = rc;
-
- return (rc);
-}
-
-
-/*
- * _ii_trksize
- */
-
-static int
-_ii_trksize(ii_fd_t *bfd, int trksize)
-{
- int rc;
-
- rc = nsc_set_trksize(II_FD(bfd), trksize);
-
- return (rc);
-}
-
-/*
- * _ii_register_path
- */
-
-static nsc_path_t *
-_ii_register_path(char *path, int type, nsc_io_t *io)
-{
- nsc_path_t *tok;
-
- tok = nsc_register_path(path, type, io);
-
- return (tok);
-}
-
-/*
- * _ii_unregister_path
- */
-/*ARGSUSED*/
-static int
-_ii_unregister_path(nsc_path_t *sp, int flag, char *type)
-{
- int rc;
-
- rc = nsc_unregister_path(sp, flag);
-
- return (rc);
-}
-
-int
-_ii_ll_add(_ii_info_t *ip, kmutex_t *mutex, _ii_lsthead_t **lst, char *name,
- char **key)
-{
- _ii_lsthead_t **head;
- _ii_lstinfo_t *node;
- uint64_t hash;
-
- ASSERT(key && !*key);
- ASSERT(ip && mutex && lst && name);
-
- node = kmem_zalloc(sizeof (_ii_lstinfo_t), KM_SLEEP);
- if (!node) {
- cmn_err(CE_WARN, "!ii: _ii_ll_add: ENOMEM");
- DTRACE_PROBE(_ii_ll_add_end_ENOMEM);
- return (ENOMEM);
- }
- node->lst_ip = ip;
-
- /* find out where we should insert it */
- hash = nsc_strhash(name);
-
- mutex_enter(mutex);
- for (head = lst; *head; head = &((*head)->lst_next)) {
- if (((*head)->lst_hash == hash) &&
- strncmp(name, (*head)->lst_name, DSW_NAMELEN) == 0) {
- node->lst_next = (*head)->lst_start;
- (*head)->lst_start = node;
- break;
- }
- }
-
- if (!*head) {
- /* create a new entry */
- *head = kmem_zalloc(sizeof (_ii_lsthead_t), KM_SLEEP);
- if (!*head) {
- /* bother */
- cmn_err(CE_WARN, "!ii: _ii_ll_add: ENOMEM");
- kmem_free(node, sizeof (_ii_lstinfo_t));
- DTRACE_PROBE(_ii_ll_add_end_2);
- return (ENOMEM);
- }
- (*head)->lst_hash = hash;
- (void) strncpy((*head)->lst_name, name, DSW_NAMELEN);
- (*head)->lst_start = node;
- }
- mutex_exit(mutex);
-
- *key = (*head)->lst_name;
-
- return (0);
-}
-
-int
-_ii_ll_remove(_ii_info_t *ip, kmutex_t *mutex, _ii_lsthead_t **lst, char **key)
-{
- _ii_lsthead_t **head, *oldhead = 0;
- _ii_lstinfo_t **node, *oldnode = 0;
- uint64_t hash;
- int found;
-
- ASSERT(key && *key);
- ASSERT(ip && lst);
-
- hash = nsc_strhash(*key);
-
- mutex_enter(mutex);
- for (head = lst; *head; head = &((*head)->lst_next)) {
- if (((*head)->lst_hash == hash) &&
- strncmp(*key, (*head)->lst_name, DSW_NAMELEN) == 0)
- break;
- }
- if (!*head) {
- /* no such link (!) */
- mutex_exit(mutex);
- return (0);
- }
-
- found = 0;
- for (node = &(*head)->lst_start; *node; node = &((*node)->lst_next)) {
- if (ip == (*node)->lst_ip) {
- oldnode = *node;
- *node = (*node)->lst_next;
- kmem_free(oldnode, sizeof (_ii_lstinfo_t));
- found = 1;
- break;
- }
- }
-
- ASSERT(found);
-
- if (!found) {
- mutex_exit(mutex);
- return (0);
- }
-
- /* did we just delete the last set in this resource group? */
- if (!(*head)->lst_start) {
- oldhead = *head;
- *head = (*head)->lst_next;
- kmem_free(oldhead, sizeof (_ii_lsthead_t));
- }
- mutex_exit(mutex);
-
- *key = NULL;
-
- return (0);
-}
-
-static nsc_def_t _ii_fd_def[] = {
- "Pinned", (uintptr_t)_ii_pinned, 0,
- "Unpinned", (uintptr_t)_ii_unpinned, 0,
- 0, 0, 0
-};
-
-
-static nsc_def_t _ii_io_def[] = {
- "Open", (uintptr_t)_ii_openc, 0,
- "Close", (uintptr_t)_ii_close, 0,
- "Attach", (uintptr_t)_ii_attach, 0,
- "Detach", (uintptr_t)_ii_detach, 0,
- "AllocHandle", (uintptr_t)_ii_alloc_handle, 0,
- "FreeHandle", (uintptr_t)_ii_free_handle, 0,
- "AllocBuf", (uintptr_t)_ii_alloc_buf, 0,
- "FreeBuf", (uintptr_t)_ii_free_buf, 0,
- "GetPinned", (uintptr_t)_ii_get_pinned, 0,
- "Discard", (uintptr_t)_ii_discard_pinned, 0,
- "PartSize", (uintptr_t)_ii_partsize, 0,
- "MaxFbas", (uintptr_t)_ii_maxfbas, 0,
- "Read", (uintptr_t)_ii_read, 0,
- "Write", (uintptr_t)_ii_write, 0,
- "Zero", (uintptr_t)_ii_zero, 0,
- "Uncommit", (uintptr_t)_ii_uncommit, 0,
- "TrackSize", (uintptr_t)_ii_trksize, 0,
- "Provide", 0, 0,
- 0, 0, 0
-};
-
-static nsc_def_t _ii_ior_def[] = {
- "Open", (uintptr_t)_ii_openr, 0,
- "Close", (uintptr_t)_ii_close, 0,
- "Attach", (uintptr_t)_ii_attach, 0,
- "Detach", (uintptr_t)_ii_detach, 0,
- "AllocHandle", (uintptr_t)_ii_alloc_handle, 0,
- "FreeHandle", (uintptr_t)_ii_free_handle, 0,
- "AllocBuf", (uintptr_t)_ii_alloc_buf, 0,
- "FreeBuf", (uintptr_t)_ii_free_buf, 0,
- "GetPinned", (uintptr_t)_ii_get_pinned, 0,
- "Discard", (uintptr_t)_ii_discard_pinned, 0,
- "PartSize", (uintptr_t)_ii_partsize, 0,
- "MaxFbas", (uintptr_t)_ii_maxfbas, 0,
- "Read", (uintptr_t)_ii_read, 0,
- "Write", (uintptr_t)_ii_write, 0,
- "Zero", (uintptr_t)_ii_zero, 0,
- "Uncommit", (uintptr_t)_ii_uncommit, 0,
- "TrackSize", (uintptr_t)_ii_trksize, 0,
- "Provide", 0, 0,
- 0, 0, 0
-};
diff --git a/usr/src/uts/common/avs/ns/dsw/dsw_dev.h b/usr/src/uts/common/avs/ns/dsw/dsw_dev.h
deleted file mode 100644
index f5cb574d8b..0000000000
--- a/usr/src/uts/common/avs/ns/dsw/dsw_dev.h
+++ /dev/null
@@ -1,633 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _DSW_DEV_H
-#define _DSW_DEV_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Definitions for kstats
- */
-#define DSW_SKSTAT_SIZE "size"
-#define DSW_SKSTAT_MTIME "latest modified time"
-#define DSW_SKSTAT_FLAGS "flags"
-#define DSW_SKSTAT_THROTTLE_UNIT "ii_throttle_unit"
-#define DSW_SKSTAT_THROTTLE_DELAY "ii_throttle_delay"
-#define DSW_SKSTAT_SHDCHKS "shdchks"
-#define DSW_SKSTAT_SHDCHKUSED "shdchkused"
-#define DSW_SKSTAT_SHDBITS "shdbits"
-#define DSW_SKSTAT_COPYBITS "copybits"
-#define DSW_SKSTAT_MSTA "mst-a"
-#define DSW_SKSTAT_MSTB "mst-b"
-#define DSW_SKSTAT_MSTC "mst-c"
-#define DSW_SKSTAT_MSTD "mst-d"
-#define DSW_SKSTAT_SETA "set-a"
-#define DSW_SKSTAT_SETB "set-b"
-#define DSW_SKSTAT_SETC "set-c"
-#define DSW_SKSTAT_SETD "set-d"
-#define DSW_SKSTAT_BMPA "bmp-a"
-#define DSW_SKSTAT_BMPB "bmp-b"
-#define DSW_SKSTAT_BMPC "bmp-c"
-#define DSW_SKSTAT_BMPD "bmp-d"
-#define DSW_SKSTAT_OVRA "ovr-a"
-#define DSW_SKSTAT_OVRB "ovr-b"
-#define DSW_SKSTAT_OVRC "ovr-c"
-#define DSW_SKSTAT_OVRD "ovr-d"
-#define DSW_SKSTAT_MSTIO "mst-io"
-#define DSW_SKSTAT_SHDIO "shd-io"
-#define DSW_SKSTAT_BMPIO "bmp-io"
-#define DSW_SKSTAT_OVRIO "ovr-io"
-
-/*
- * Bitmap macros
- */
-
-#define DSW_BIT_CLR(bmap, bit) (bmap &= (char)~(1 << bit))
-#define DSW_BIT_SET(bmap, bit) (bmap |= (char)(1 << bit))
-#define DSW_BIT_ISSET(bmap, bit) ((bmap & (1 << bit)) != 0)
-
-#define DSW_CBLK_FBA 16 /* cache blocks in fba's */
-#define DSW_SHD_BM_OFFSET DSW_CBLK_FBA /* offset to allow for header */
-#define DSW_COPY_BM_OFFSET (DSW_SHD_BM_OFFSET + \
- DSW_BM_FBA_LEN(ip->bi_size))
-#define DSW_BM_FBA_LEN(mst_size) ((mst_size) / FBA_SIZE(DSW_SIZE*DSW_BITS) + \
- DSW_CBLK_FBA)
-
-#define DSW_BM_SIZE_CHUNKS(ip) ((ip->bi_size + DSW_SIZE - 1) / DSW_SIZE)
-#define DSW_BM_SIZE_BYTES(ip) ((DSW_BM_SIZE_CHUNKS(ip) + DSW_BITS - 1) / \
- DSW_BITS)
-
-#define DSW_CHK2FBA(chunk) (((nsc_off_t)(chunk)) * DSW_SIZE)
-
-#if defined(_KERNEL) || defined(_KMEMUSER)
-
-/*
- * Shadow types.
- */
-
-#define DSW_GOLDEN_TYPE 0x1000
-#define DSW_QUICK_TYPE 0x2000
-
-/*
- * Miscellaneous defines
- */
-
-#define II_INTERNAL 0x1
-#define II_EXTERNAL 0x2
-
-#define II_EXISTING 0x01 /* Internal dsw_ioctl()/dsw_config() flags */
-#define II_IMPORT 0x02
-
-/*
- * defines for _ii_nsc_io and _ii_write, used by kstats
- */
-
-#define KS_NA 0
-#define KS_MST 1
-#define KS_SHD 2
-#define KS_BMP 3
-#define KS_OVR 4
-
-/*
- * global kstats
- */
-
-typedef struct _iigkstat_s {
- /* static */
- kstat_named_t ii_debug;
- kstat_named_t ii_bitmap;
- kstat_named_t ii_throttle_unit;
- kstat_named_t ii_throttle_delay;
- kstat_named_t ii_copy_direct;
-
- /* dynamic */
- kstat_named_t num_sets;
- kstat_named_t assoc_over;
- kstat_named_t spilled_over;
-} iigkstat_t;
-
-extern iigkstat_t iigkstat;
-
-/*
- * set-specific kstats
- */
-typedef struct _ii_kstat_set_s {
- kstat_named_t size; /* from _ii_stat() */
- kstat_named_t mtime; /* from _ii_stat() */
- kstat_named_t flags; /* from _ii_stat() */
- kstat_named_t unit; /* ii_throttle_unit */
- kstat_named_t delay; /* ii_throttle_delay */
- kstat_named_t shdchks; /* from _ii_stat() */
- kstat_named_t shdchkused; /* from _ii_stat() */
- kstat_named_t shdbits; /* # bits set shadow bitmap */
- kstat_named_t copybits; /* # bits set copy bitmap */
- kstat_named_t mst_a; /* name */
- kstat_named_t mst_b; /* .. of */
- kstat_named_t mst_c; /* .. master */
- kstat_named_t mst_d; /* .. volume */
- kstat_named_t set_a; /* name */
- kstat_named_t set_b; /* .. of */
- kstat_named_t set_c; /* .. the */
- kstat_named_t set_d; /* .. set */
- kstat_named_t bmp_a; /* name */
- kstat_named_t bmp_b; /* .. of */
- kstat_named_t bmp_c; /* .. bitmap */
- kstat_named_t bmp_d; /* .. volume */
- kstat_named_t ovr_a; /* name */
- kstat_named_t ovr_b; /* .. of */
- kstat_named_t ovr_c; /* .. overflow */
- kstat_named_t ovr_d; /* .. volume */
- kstat_named_t mst_io; /* kstat_io of master */
- kstat_named_t shd_io; /* kstat_io of shadow */
- kstat_named_t bmp_io; /* kstat_io of bitmap */
- kstat_named_t ovr_io; /* kstat_io of overflow */
-} ii_kstat_set_t;
-
-extern ii_kstat_set_t ii_kstat_set;
-#define IOSTAT_NAME_LEN 10
-
-/* Basic types */
-#ifdef II_MULTIMULTI_TERABYTE
-typedef int64_t chunkid_t;
-typedef int32_t chunkid32_t;
-#else
-typedef int32_t chunkid_t;
-#endif
-
-/*
- * OV_HEADER_VERSION
- * 0 = original OV header version
- * 1 = flags support
- */
-#define OV_HEADER_VERSION 1
-
-/* Overflow disk volume header */
-typedef struct _ii_doverflow_s {
- char ii_dvolname[DSW_NAMELEN]; /* this volumes name */
- uint32_t ii_dhmagic; /* sanity check */
- uint32_t ii_dhversion; /* volume format */
- int32_t ii_ddrefcnt; /* total number of users */
- int32_t ii_dflags; /* status flags */
- int64_t ii_dfreehead; /* chain of freed chunks */
- int64_t ii_dnchunks; /* total number of chunks */
- int64_t ii_dunused; /* number of chunks available */
- int64_t ii_dused; /* number of chunks allocated */
- int32_t ii_urefcnt; /* # shadows needing update */
- int32_t ii_dcrefcnt; /* current number of users */
-} _ii_doverflow_t;
-
-/* Overflow volume in core structure */
-typedef struct _ii_overflow_s {
- _ii_doverflow_t ii_do;
- kmutex_t ii_mutex; /* Mutex */
- kmutex_t ii_kstat_mutex; /* Mutex for overflow kstat */
- int ii_detachcnt; /* users detaching on disable */
- struct _ii_overflow_s *ii_next; /* chain of incore structs */
- struct _ii_info_dev_s *ii_dev; /* pointer to device details */
- kstat_t *ii_overflow; /* kstats data for this vol */
- char ii_ioname[KSTAT_DATA_CHAR_LEN]; /* name for iostat -x */
-} _ii_overflow_t;
-
-#define ii_volname ii_do.ii_dvolname
-#define ii_hmagic ii_do.ii_dhmagic
-#define ii_drefcnt ii_do.ii_ddrefcnt
-#define ii_freehead ii_do.ii_dfreehead
-#define ii_nchunks ii_do.ii_dnchunks
-#define ii_unused ii_do.ii_dunused
-#define ii_used ii_do.ii_dused
-#define ii_hversion ii_do.ii_dhversion
-#define ii_flags ii_do.ii_dflags
-#define ii_urefcnt ii_do.ii_urefcnt
-#define ii_crefcnt ii_do.ii_dcrefcnt
-
-#define II_OHEADER_FBA 0 /* overflow header location */
-/*
- * logging of kstat_io
- */
-#ifdef DISABLE_KSTATS
-#define II_READ_START(ip, type)
-#define II_READ_END(ip, type, rc, blocks)
-#define II_WRITE_START(ip, type)
-#define II_WRITE_END(ip, type, rc, blocks)
-#else
-
-#define II_KS(ip, x) KSTAT_IO_PTR(ip->bi_kstat_io.x)
-#define II_MUTEX(ip, x) ip->bi_kstat_io.x->ks_lock
-#define II_BLKSIZE 512
-
-#define II_READ_START(ip, type) \
- if (ip->bi_kstat_io.type) { \
- mutex_enter(II_MUTEX(ip, type)); \
- kstat_runq_enter(II_KS(ip, type)); \
- mutex_exit(II_MUTEX(ip, type)); \
- }
-#define II_READ_END(ip, type, rc, blocks) \
- if (ip->bi_kstat_io.type) { \
- mutex_enter(II_MUTEX(ip, type)); \
- if (II_SUCCESS(rc)) { \
- II_KS(ip, type)->reads++; \
- II_KS(ip, type)->nread += II_BLKSIZE * (blocks);\
- } \
- kstat_runq_exit(II_KS(ip, type)); \
- mutex_exit(II_MUTEX(ip, type)); \
- }
-
-#define II_WRITE_START(ip, type) \
- if (ip->bi_kstat_io.type) { \
- mutex_enter(II_MUTEX(ip, type)); \
- kstat_runq_enter(II_KS(ip, type)); \
- mutex_exit(II_MUTEX(ip, type)); \
- }
-#define II_WRITE_END(ip, type, rc, blocks) \
- if (ip->bi_kstat_io.type) { \
- mutex_enter(II_MUTEX(ip, type)); \
- if (II_SUCCESS(rc)) { \
- II_KS(ip, type)->writes++; \
- II_KS(ip, type)->nwritten += II_BLKSIZE * (blocks);\
- } \
- kstat_runq_exit(II_KS(ip, type)); \
- mutex_exit(II_MUTEX(ip, type)); \
- }
-#endif
-
-#define II_NSC_READ(ip, type, rc, buf, pos, len, flag) \
- II_READ_START(ip, type); \
- rc = nsc_read(buf, pos, len, flag); \
- II_READ_END(ip, type, rc, len);
-
-#define II_NSC_WRITE(ip, type, rc, buf, pos, len, flag) \
- II_WRITE_START(ip, type); \
- rc = nsc_write(buf, pos, len, flag); \
- II_WRITE_END(ip, type, rc, len);
-
-#define II_NSC_COPY_DIRECT(ip, t1, t2, rc, buf1, buf2, pos1, pos2, len) \
- II_WRITE_START(ip, t2); \
- rc = nsc_copy_direct(buf1, buf2, pos1, pos2, len); \
- II_WRITE_END(ip, t2, rc, len);
-
-#define II_ALLOC_BUF(ip, type, rc, fd, pos, len, flag, tmp) \
- if (flag & NSC_READ) { \
- II_READ_START(ip, type); \
- } \
- rc = nsc_alloc_buf(fd, pos, len, flag, tmp); \
- if (flag & NSC_READ) { \
- II_READ_END(ip, type, rc, len); \
- }
-
-/*
- * All kstat_io associated with a set. NOTE: only one mutex for all
- * of the kstats for a given set; all master/shadow/bmp/overflow mutexes
- * point back to the statmutex
- */
-
-typedef struct _ii_kstat_info_s {
- kstat_t *master;
- kstat_t *shadow;
- kstat_t *bitmap;
- kstat_t *overflow;
- kmutex_t statmutex;
- char mstio[KSTAT_DATA_CHAR_LEN]; /* name of mst in iostat -x */
- char shdio[KSTAT_DATA_CHAR_LEN]; /* name of shd in iostat -x */
- char bmpio[KSTAT_DATA_CHAR_LEN]; /* name of bmp in iostat -x */
- char ovrio[KSTAT_DATA_CHAR_LEN]; /* name of ovr in iostat -x */
-} ii_kstat_info_t;
-
-/*
- * II device info structure
- */
-
-typedef struct _ii_info_dev_s {
- nsc_fd_t *bi_fd; /* Bitmap file descriptor */
- nsc_iodev_t *bi_iodev; /* I/O device structure */
- nsc_path_t *bi_tok; /* Register path token */
- int bi_ref; /* Count of fd's referencing */
- int bi_rsrv; /* Count of reserves held */
- int bi_orsrv; /* Reserves for other io prov */
- int bi_flag; /* Internal/External reserve */
-} _ii_info_dev_t;
-
-typedef struct _ii_info_s {
- struct _ii_info_s *bi_next; /* Chain of all groups */
- struct _ii_info_s *bi_head; /* head of sibling chain */
- struct _ii_info_s *bi_sibling; /* Chain of groups with same */
- /* master */
- struct _ii_info_s *bi_master; /* location of master */
- struct _ii_info_s *bi_nextmst; /* next multimaster */
- kmutex_t bi_mutex; /* Mutex */
- _ii_info_dev_t *bi_mstdev;
- _ii_info_dev_t *bi_mstrdev;
- _ii_info_dev_t bi_shddev;
- _ii_info_dev_t bi_shdrdev;
- _ii_info_dev_t bi_bmpdev;
- char bi_keyname[DSW_NAMELEN];
- unsigned char *bi_bitmap; /* Master device bitmap */
- char *bi_cluster; /* cluster name */
- char *bi_group; /* group name */
- char *bi_busy; /* Busy bitmap */
- nsc_off_t bi_shdfba; /* location of shadow bitmap */
- nsc_size_t bi_shdbits; /* shadow bitmap counter */
- nsc_off_t bi_copyfba; /* location of copy bitmap */
- nsc_size_t bi_copybits; /* copy bitmap counter */
- nsc_size_t bi_size; /* Size of mst device */
- uint_t bi_flags; /* Flags */
- uint_t bi_state; /* State flags */
- int bi_disabled; /* Disable has started */
- int bi_ioctl; /* Number of active ioctls */
- int bi_release; /* Do a release in copyvol */
- int bi_rsrvcnt; /* reserve count */
- kcondvar_t bi_copydonecv; /* Copy operation condvar */
- kcondvar_t bi_reservecv; /* Reserve condvar */
- kcondvar_t bi_releasecv; /* Release condvar */
- kcondvar_t bi_closingcv; /* Shadow closing condvar */
- kcondvar_t bi_ioctlcv; /* Ioctls complete condvar */
- kcondvar_t bi_busycv; /* Busy bitmap condvar */
- krwlock_t bi_busyrw; /* Busy bitmap rwlock */
- struct _ii_bmp_ops_s *bi_bitmap_ops; /* Functions for bitmap ops */
- kmutex_t bi_rsrvmutex; /* Reserve operation mutex */
- kmutex_t bi_rlsemutex; /* Release operation mutex */
- kmutex_t bi_bmpmutex; /* mutex for bi_bitmap_ops */
- chunkid_t bi_mstchks;
- chunkid_t bi_shdchks; /* # of chunks on shadow vol */
- chunkid_t bi_shdchkused; /* # of allocated */
- chunkid_t bi_shdfchk; /* start of shd chunk flst */
- _ii_overflow_t *bi_overflow;
- struct ii_fd_s *bi_iifd; /* fd holding master's ip */
- int32_t bi_throttle_unit;
- int32_t bi_throttle_delay;
- krwlock_t bi_linkrw; /* altering linkage rwlock */
- kmutex_t bi_chksmutex; /* Mutex for bi_???chks */
- pid_t bi_locked_pid; /* lock pid for update/copy */
- kstat_t *bi_kstat; /* kstat data for set */
- ii_kstat_info_t bi_kstat_io; /* kstat I/O data for set */
- time_t bi_mtime;
-} _ii_info_t;
-
-#define bi_bmpfd bi_bmpdev.bi_fd
-#define bi_mstfd bi_mstdev->bi_fd
-#define bi_mstrfd bi_mstrdev->bi_fd
-#define bi_shdfd bi_shddev.bi_fd
-#define bi_shdrfd bi_shdrdev.bi_fd
-#define bi_mst_iodev bi_mstdev->bi_iodev
-#define bi_mstr_iodev bi_mstrdev->bi_iodev
-#define bi_shd_iodev bi_shddev.bi_iodev
-#define bi_shdr_iodev bi_shdrdev.bi_iodev
-#define bi_bmp_iodev bi_bmpdev.bi_iodev
-#define bi_mst_tok bi_mstdev->bi_tok
-#define bi_mstr_tok bi_mstrdev->bi_tok
-#define bi_shd_tok bi_shddev.bi_tok
-#define bi_shdr_tok bi_shdrdev.bi_tok
-#define bi_bmp_tok bi_bmpdev.bi_tok
-#define bi_mstref bi_mstdev->bi_ref
-#define bi_mstrref bi_mstrdev->bi_ref
-#define bi_shdref bi_shddev.bi_ref
-#define bi_shdrref bi_shdrdev.bi_ref
-#define bi_bmpref bi_bmpdev.bi_ref
-#define bi_mstrsrv bi_mstdev->bi_rsrv
-#define bi_mstrrsrv bi_mstrdev->bi_rsrv
-#define bi_shdrsrv bi_shddev.bi_rsrv
-#define bi_shdrrsrv bi_shdrdev.bi_rsrv
-#define bi_bmprsrv bi_bmpdev.bi_rsrv
-#define bi_mstrflag bi_mstrdev->bi_flag
-#define bi_shdrflag bi_shdrdev.bi_flag
-/*
- * Cluster and group linked lists
- */
-typedef struct _ii_lstinfo_s {
- _ii_info_t *lst_ip; /* ptr to info_t */
- struct _ii_lstinfo_s *lst_next; /* ptr to next in chain */
-} _ii_lstinfo_t;
-
-typedef struct _ii_lsthead_s {
- uint64_t lst_hash; /* from nsc_strhash */
- char lst_name[DSW_NAMELEN]; /* resource group */
- _ii_lstinfo_t *lst_start; /* start of set list */
- struct _ii_lsthead_s *lst_next; /* next list head */
-} _ii_lsthead_t;
-
-/*
- * Flag set and clear macros and function.
- */
-
-void _ii_flag_op(int and, int or, _ii_info_t *ip, int update);
-
-#define II_FLAG_SET(f, ip) _ii_flag_op(~0, (f), ip, TRUE)
-#define II_FLAG_CLR(f, ip) _ii_flag_op(~(f), 0, ip, TRUE)
-
-#define II_FLAG_SETX(f, ip) _ii_flag_op(~0, (f), ip, FALSE)
-#define II_FLAG_CLRX(f, ip) _ii_flag_op(~(f), 0, ip, FALSE)
-#define II_FLAG_ASSIGN(f, ip) _ii_flag_op(0, (f), ip, FALSE);
-#define LOG_EVENT(msg, level) \
- nsc_do_sysevent("ii", msg, level, level, component, ii_dip);
-
-/* Reserve and release macros */
-
- /* also used by ii_volume() volume identification, hence NONE & OVR */
-#define NONE 0x0000 /* no volume type */
-#define MST 0x0001 /* master reserve/release flag */
-#define MSTR 0x0010 /* raw master reserve/release flag */
-#define SHD 0x0002 /* shadow reserve/release flag */
-#define SHDR 0x0020 /* raw shadow reserve/release flag */
-#define BMP 0x0100 /* bitmap reserve/release flag */
-#define OVR 0x0400 /* overflow volume */
-
-#define RSRV(ip) ((ip)->bi_rsrv > 0 || (ip)->bi_orsrv > 0)
-
-#define MSTRSRV(ip) (RSRV(((ip)->bi_mstdev)))
-#define SHDRSRV(ip) (RSRV(&((ip)->bi_shddev)))
-
-#define MSTFD(ip) (MSTRSRV(ip) ? (ip)->bi_mstfd : (ip)->bi_mstrfd)
-#define SHDFD(ip) (SHDRSRV(ip) ? (ip)->bi_shdfd : (ip)->bi_shdrfd)
-#define OVRFD(ip) (ip->bi_overflow->ii_dev->bi_fd)
-
-#define II_RAW(ii) (((ii)->ii_oflags&NSC_DEVICE) != 0)
-#define II_FD(ii) ((ii)->ii_shd ? SHDFD((ii)->ii_info) : \
- MSTFD((ii)->ii_info))
-
- /* are there multiple shadows of ip's master volume? */
-#define NSHADOWS(ip) ((ip)->bi_head != (ip) || (ip)->bi_sibling)
-
-typedef struct _ii_bmp_ops_s {
- int (*co_bmp)(_ii_info_t *, nsc_off_t, unsigned char *, int);
- int (*ci_bmp)(_ii_info_t *, nsc_off_t, unsigned char *, int);
- int (*zerobm)(_ii_info_t *);
- int (*copybm)(_ii_info_t *);
- int (*orbm)(_ii_info_t *);
- int (*tst_shd_bit)(_ii_info_t *, chunkid_t);
- int (*set_shd_bit)(_ii_info_t *, chunkid_t);
- int (*tst_copy_bit)(_ii_info_t *, chunkid_t);
- int (*set_copy_bit)(_ii_info_t *, chunkid_t);
- int (*clr_copy_bits)(_ii_info_t *, chunkid_t, int);
- chunkid_t (*next_copy_bit)(_ii_info_t *, chunkid_t, chunkid_t,
- int, int *);
- int (*fill_copy_bmp)(_ii_info_t *);
- int (*load_bmp)(_ii_info_t *, int);
- int (*save_bmp)(_ii_info_t *, int);
- int (*change_bmp)(_ii_info_t *, unsigned char *);
- int (*cnt_bits)(_ii_info_t *, nsc_off_t, nsc_size_t *, int);
- int (*join_bmp)(_ii_info_t *, _ii_info_t *);
-} _ii_bmp_ops_t;
-
-#define II_CO_BMP(ip, a, b, c) (*(ip)->bi_bitmap_ops->co_bmp)(ip, a, b, c)
-#define II_CI_BMP(ip, a, b, c) (*(ip)->bi_bitmap_ops->ci_bmp)(ip, a, b, c)
-#define II_ZEROBM(ip) (*(ip)->bi_bitmap_ops->zerobm)(ip)
-#define II_COPYBM(ip) (*(ip)->bi_bitmap_ops->copybm)(ip)
-#define II_ORBM(ip) (*(ip)->bi_bitmap_ops->orbm)(ip)
-#define II_TST_SHD_BIT(ip, c) (*(ip)->bi_bitmap_ops->tst_shd_bit)(ip, c)
-#define II_SET_SHD_BIT(ip, c) (*(ip)->bi_bitmap_ops->set_shd_bit)(ip, c)
-#define II_TST_COPY_BIT(ip, c) (*(ip)->bi_bitmap_ops->tst_copy_bit)(ip, c)
-#define II_SET_COPY_BIT(ip, c) (*(ip)->bi_bitmap_ops->set_copy_bit)(ip, c)
-#define II_CLR_COPY_BITS(ip, c, n) (*(ip)->bi_bitmap_ops->clr_copy_bits) \
- (ip, c, n)
-#define II_CLR_COPY_BIT(ip, c) (*(ip)->bi_bitmap_ops->clr_copy_bits)(ip, c, 1)
-#define II_NEXT_COPY_BIT(ip, c, m, w, g) \
- (*(ip)->bi_bitmap_ops->next_copy_bit)(ip, c, m, w, g)
-#define II_FILL_COPY_BMP(ip) (*(ip)->bi_bitmap_ops->fill_copy_bmp)(ip)
-#define II_LOAD_BMP(ip, f) (*(ip)->bi_bitmap_ops->load_bmp)(ip, f)
-#define II_SAVE_BMP(ip, f) (*(ip)->bi_bitmap_ops->save_bmp)(ip, f)
-#define II_CHANGE_BMP(ip, p) (*(ip)->bi_bitmap_ops->change_bmp)(ip, p)
-#define II_CNT_BITS(ip, a, b, c) (*(ip)->bi_bitmap_ops->cnt_bits)(ip, a, b, c)
-#define II_JOIN_BMP(dip, sip) (*(ip)->bi_bitmap_ops->join_bmp)(dip, sip)
-
-/*
- * State flags
- */
-#define DSW_IOCTL 0x0001 /* Waiting for ioctl to complete */
-#define DSW_CLOSING 0x0002 /* Waiting for shadow to close */
-#define DSW_MSTTARGET 0x0004 /* Master is target of update */
-#define DSW_MULTIMST 0x0008 /* disabled set is multi master */
-#define DSW_CNTSHDBITS 0x0010 /* need to count # of shd bits set */
-#define DSW_CNTCPYBITS 0x0020 /* need to count # of copy bits set */
-
-/*
- * DSW file descriptor structure
- */
-
-typedef struct ii_fd_s {
- _ii_info_t *ii_info; /* Info structure */
- int ii_bmp; /* This fd is for the bmp device */
- int ii_shd; /* This fd is for the shadow device */
- int ii_ovr; /* This fd is for the overflow device */
- _ii_overflow_t *ii_optr; /* pointer to overflow structure */
- int ii_oflags; /* raw or cached open type */
-} ii_fd_t;
-
-
-/*
- * II buffer header
- */
-
-typedef struct ii_buf_s {
- nsc_buf_t ii_bufh; /* exported buffer header */
- nsc_buf_t *ii_bufp; /* main underlying buffer */
- nsc_buf_t *ii_bufp2; /* second underlying buffer */
- nsc_buf_t *ii_abufp; /* anonymous underlying buffer */
- ii_fd_t *ii_fd; /* back link */
- int ii_rsrv; /* fd to release in free_buf */
-} ii_buf_t;
-#endif /* _KERNEL || _KMEMUSER */
-
-
-/*
- * Valid magic numbers in the bitmap volume header
- */
-
-#define DSW_DIRTY 0x44495254
-#define DSW_CLEAN 0x434C4541
-#define DSW_INVALID 0x00000000
-
-/*
- * II_HEADER_VERSION
- * 1 = original II header version
- * 2 = Compact Dependent Shadows (DSW_TREEMAP)
- * 3 = Persistance of throttle parameters
- * 4 = add cluster & group information
- * 5 = add time string to hold last modify time
- */
-#define II_HEADER_VERSION 5
-
-/*
- * DSW bitmap volume header structure
- */
-
-typedef struct ii_header_s {
- int32_t ii_magic; /* magic number */
- int32_t ii_type; /* bitmap or independent copy */
- int32_t ii_state; /* State of the master/shadow/bitmap tuple */
- int32_t ii_version; /* version or format of bitmap volume */
- int32_t ii_shdfba; /* location of shadow bitmap */
- int32_t ii_copyfba; /* location of copy bitmap */
- char master_vol[DSW_NAMELEN];
- char shadow_vol[DSW_NAMELEN];
- char bitmap_vol[DSW_NAMELEN];
- /* II_HEADER_VERSION 2 */
- char overflow_vol[DSW_NAMELEN];
- int64_t ii_mstchks; /* # of chunks in master volume */
- int64_t ii_shdchks; /* # of chunks in shadow volume */
- int64_t ii_shdchkused; /* # of shd chunks allocated or on free list */
- int64_t ii_shdfchk; /* list of free shadow chunks */
- /* II_HEADER_VERSION 3 */
- int32_t ii_throttle_unit; /* Last setting of throttle unit */
- int32_t ii_throttle_delay; /* Last setting of throttle delay */
- /* II_HEADER_VERSION 4 */
- char clstr_name[DSW_NAMELEN];
- char group_name[DSW_NAMELEN];
- /* II_HEADER_VERSION 5 */
- time_t ii_mtime;
-} ii_header_t;
-
-#define II_SUCCESS(rc) (((rc) == NSC_DONE) || ((rc) == NSC_HIT))
-
-/*
- * Overflow volume defines.
- */
-
-#define II_OMAGIC 0x476F6C64 /* "Gold" */
-#define II_ISOVERFLOW(n) ((n) < 0 && (n) != II_NULLCHUNK)
-#define II_2OVERFLOW(n) (-(n))
- /* -tive node id's are in overflow volume */
-
-#ifdef _SunOS_5_6
-#define II_NULLNODE (INT_MIN)
-#define II_NULLCHUNK (INT_MIN)
-#else
-#ifdef II_MULTIMULTI_TERABYTE
-#define II_NULLNODE (INT64_MIN)
-#define II_NULLCHUNK (INT64_MIN)
-#define II_NULL32NODE (INT32_MIN)
-#define II_NULL32CHUNK (INT32_MIN)
-#else
-#define II_NULLNODE (INT32_MIN)
-#define II_NULLCHUNK (INT32_MIN)
-#endif /* II_MULTIMULTI_TERABYTE */
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _DSW_DEV_H */
diff --git a/usr/src/uts/common/avs/ns/dsw/ii.conf b/usr/src/uts/common/avs/ns/dsw/ii.conf
deleted file mode 100644
index f964881494..0000000000
--- a/usr/src/uts/common/avs/ns/dsw/ii.conf
+++ /dev/null
@@ -1,38 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# InstantImage Solaris configuration properties
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#
-name="ii" parent="pseudo" ;
-#
-# level of detail in console debugging messages - 0 means no messages.
-#
-ii_debug=0;
-#
-# bitmap volume storage strategy:
-# 0 indicates kernel memory loaded from bitmap volume when shadow is resumed
-# and saved to bitmap volume when shadow is suspended.
-# 1 indicates permanent SDBC storage, bitmap volume is updated directly as
-# bits are changed.
-# 2 indicates that if FWC is present strategy 1 is used, otherwise strategy 0.
-ii_bitmap=1;
diff --git a/usr/src/uts/common/avs/ns/dsw/ii_tree.c b/usr/src/uts/common/avs/ns/dsw/ii_tree.c
deleted file mode 100644
index 202cb2b8f4..0000000000
--- a/usr/src/uts/common/avs/ns/dsw/ii_tree.c
+++ /dev/null
@@ -1,599 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/ksynch.h>
-#include <sys/kmem.h>
-#include <sys/errno.h>
-#include <sys/cmn_err.h>
-#include <sys/debug.h>
-#include <sys/cred.h>
-#include <sys/file.h>
-#include <sys/ddi.h>
-#include <sys/nsctl/nsctl.h>
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_errors.h>
-
-#include <sys/unistat/spcs_s_k.h>
-#include "dsw.h"
-#include "dsw_dev.h"
-
-#ifdef DS_DDICT
-#include "../contract.h"
-#endif
-
-#include <sys/sdt.h> /* dtrace is S10 or later */
-
-/*
- * Instant Image.
- *
- * This file contains the chunk map lookup functions of II.
- *
- */
-#define CHUNK_FBA(chunk) DSW_CHK2FBA(chunk)
-
-extern int ii_debug; /* debug level switch */
-int ii_map_debug = 0;
-
-#ifdef II_MULTIMULTI_TERABYTE
-typedef int64_t nodeid_t;
-typedef int32_t nodeid32_t;
-#else
-typedef int32_t nodeid_t;
-#endif
-
-typedef struct ii_node {
- chunkid_t vchunk_id; /* virtual chunk id */
-} NODE;
-
-typedef struct ii_nodelink_s {
- chunkid_t next_chunk;
-} ii_nodelink_t;
-
-static int nodes_per_fba = FBA_SIZE(1) / sizeof (NODE);
-
-ii_header_t *_ii_bm_header_get(_ii_info_t *ip, nsc_buf_t **tmp);
-int _ii_bm_header_put(ii_header_t *hdr, _ii_info_t *ip,
- nsc_buf_t *tmp);
-void _ii_rlse_devs(_ii_info_t *, int);
-int _ii_rsrv_devs(_ii_info_t *, int, int);
-void _ii_error(_ii_info_t *, int);
-/*
- * Private functions for use in this file.
- */
-static void free_node(_ii_info_t *ip, NODE *np, nodeid_t ni);
-static chunkid_t ii_alloc_overflow(_ii_info_t *ip);
-void ii_free_overflow(_ii_info_t *, chunkid_t);
-extern int _ii_nsc_io(_ii_info_t *, int, nsc_fd_t *, int, nsc_off_t,
- unsigned char *, nsc_size_t);
-
-static int
-update_tree_header(_ii_info_t *ip)
-{
- ii_header_t *header;
- nsc_buf_t *tmp = NULL;
-
- mutex_enter(&ip->bi_mutex);
- header = _ii_bm_header_get(ip, &tmp);
- if (header == NULL) {
- /* bitmap is probably offline */
- mutex_exit(&ip->bi_mutex);
- DTRACE_PROBE(_iit_update_tree_header_end);
- return (1);
- }
- header->ii_mstchks = ip->bi_mstchks;
- header->ii_shdchks = ip->bi_shdchks;
- header->ii_shdchkused = ip->bi_shdchkused;
- header->ii_shdfchk = ip->bi_shdfchk;
- (void) _ii_bm_header_put(header, ip, tmp);
- mutex_exit(&ip->bi_mutex);
-
- return (0);
-}
-
-static int
-update_overflow_header(_ii_info_t *ip, _ii_overflow_t *op)
-{
- (void) _ii_nsc_io(ip, KS_OVR, op->ii_dev->bi_fd, NSC_WRBUF,
- II_OHEADER_FBA, (unsigned char *)&(op->ii_do),
- sizeof (_ii_doverflow_t));
-
- return (0);
-}
-
-static int
-node_io(_ii_info_t *ip, NODE *np, nodeid_t node, int flag)
-{
- int rc;
- int node_fba;
- int tree_fba = ip->bi_copyfba + (ip->bi_copyfba-ip->bi_shdfba);
- int offset;
- nsc_buf_t *tmp = NULL;
-
- /*
- * Don't use _ii_nsc_io() as _ii_nsc_io() requires io to start at
- * an fba boundary.
- */
-
- /* calculate location of node on bitmap file */
- offset = (node % nodes_per_fba) * sizeof (NODE);
- node_fba = tree_fba + node / nodes_per_fba;
-
- /* read disk block containing node */
- rc = nsc_alloc_buf(ip->bi_bmpfd, node_fba, 1, NSC_RDBUF|flag, &tmp);
- if (!II_SUCCESS(rc)) {
- _ii_error(ip, DSW_BMPOFFLINE);
- if (tmp)
- (void) nsc_free_buf(tmp);
-
- DTRACE_PROBE(_iit_node_io_end);
- return (1);
- }
-
- /* copy node and update bitmap file if needed */
- rc = 0;
- if (flag == NSC_RDBUF)
- bcopy(tmp->sb_vec->sv_addr+offset, np, sizeof (NODE));
- else {
- bcopy(np, tmp->sb_vec->sv_addr+offset, sizeof (NODE));
- II_NSC_WRITE(ip, bitmap, rc, tmp, node_fba, 1, 0);
- if (!II_SUCCESS(rc)) {
- _ii_error(ip, DSW_BMPOFFLINE);
- rc = EIO;
- }
- }
- if (tmp)
- (void) nsc_free_buf(tmp);
-
- return (0);
-}
-
-static int
-node_fba_fill(_ii_info_t *ip, nsc_size_t nchunks, chunkid_t vchunk_id)
-{
- int rc;
- nsc_off_t fba;
- nsc_size_t fbas;
- nsc_size_t maxfbas;
- nsc_buf_t *bp;
- nsc_vec_t *vp;
-
- /* Determine maximum number of FBAs to allocate */
- rc = nsc_maxfbas(ip->bi_bmpfd, 0, &maxfbas);
- if (!II_SUCCESS(rc))
- maxfbas = DSW_CBLK_FBA;
-
- /* Write out blocks of initialied NODEs */
- fba = ip->bi_copyfba + (ip->bi_copyfba-ip->bi_shdfba);
- fbas = FBA_LEN(nchunks * sizeof (NODE));
- while (fbas > 0) {
-
- /* Determine number of FBA to allocate this time */
- if (fbas < maxfbas) maxfbas = fbas;
-
- /* Allocate buffer which map to FBAs containing NODEs */
- bp = NULL;
- rc = nsc_alloc_buf(ip->bi_bmpfd, fba, maxfbas, NSC_WRBUF, &bp);
- if (!II_SUCCESS(rc)) {
- _ii_error(ip, DSW_BMPOFFLINE);
- DTRACE_PROBE(alloc_buf_failed);
- return (EIO);
- }
-
- /* traverse vector list, filling wth initialized NODEs */
- for (vp = bp->sb_vec; vp->sv_addr && vp->sv_len; vp++) {
- NODE *pnode = (NODE *)vp->sv_addr;
- NODE *enode = (NODE *)(vp->sv_addr + vp->sv_len);
- while (pnode < enode) {
- pnode->vchunk_id = vchunk_id;
- pnode++;
- }
- }
-
- /* write FBAs containing initialized NODEs */
- II_NSC_WRITE(ip, bitmap, rc, bp, fba, maxfbas, 0);
- if (!II_SUCCESS(rc)) {
- _ii_error(ip, DSW_BMPOFFLINE);
- (void) nsc_free_buf(bp);
- DTRACE_PROBE(write_failed);
- return (EIO);
- }
-
- /* free the buffer */
- (void) nsc_free_buf(bp);
-
- /* Adjust nsc buffer values */
- fba += maxfbas;
- fbas -= maxfbas;
- }
-
- return (0);
-}
-
-/*
- * Reads the node into core and returns a pointer to it.
- */
-
-static NODE *
-read_node(_ii_info_t *ip, nodeid_t node)
-{
- NODE *new;
-
- new = (NODE *)kmem_alloc(sizeof (NODE), KM_SLEEP);
-
- if (node_io(ip, new, node, NSC_RDBUF)) {
- kmem_free(new, sizeof (NODE));
- new = NULL;
- }
-
- return (new);
-}
-
-
-static chunkid_t
-alloc_chunk(_ii_info_t *ip)
-{
- ii_nodelink_t nl;
- int fba;
- chunkid_t rc = II_NULLCHUNK;
-
- mutex_enter(&ip->bi_chksmutex);
- if (ip->bi_shdchkused < ip->bi_shdchks) {
- rc = ip->bi_shdchkused++;
- } else if (ip->bi_shdfchk != II_NULLCHUNK) {
- ASSERT(ip->bi_shdfchk >= 0 && ip->bi_shdfchk < ip->bi_shdchks);
- rc = ip->bi_shdfchk;
- fba = CHUNK_FBA(rc);
- (void) _ii_rsrv_devs(ip, SHDR, II_INTERNAL);
- (void) _ii_nsc_io(ip, KS_SHD, SHDFD(ip), NSC_RDBUF, fba,
- (unsigned char *)&nl, sizeof (nl));
- _ii_rlse_devs(ip, SHDR);
- ip->bi_shdfchk = nl.next_chunk;
- ASSERT(ip->bi_shdfchk == II_NULLCHUNK ||
- (ip->bi_shdfchk >= 0 && ip->bi_shdfchk < ip->bi_shdchks));
- } else {
-
- /* into overflow */
- rc = ii_alloc_overflow(ip);
- }
- mutex_exit(&ip->bi_chksmutex);
- (void) update_tree_header(ip);
-
- return (rc);
-}
-
-/*
- * releases memory for node
- */
-static void /*ARGSUSED*/
-release_node(_ii_info_t *ip, NODE *np, nodeid_t ni)
-{
- kmem_free(np, sizeof (NODE));
-
-}
-
-static void
-write_node(_ii_info_t *ip, NODE *np, nodeid_t ni)
-{
- (void) node_io(ip, np, ni, NSC_WRBUF);
- release_node(ip, np, ni);
-
-}
-
-static void
-free_node(_ii_info_t *ip, NODE *np, nodeid_t ni)
-{
- ii_nodelink_t nl;
- int fba;
-
- if (np == NULL) {
- DTRACE_PROBE(_iit_free_node_end);
- return;
- }
-
- mutex_enter(&ip->bi_chksmutex);
- if (II_ISOVERFLOW(np->vchunk_id)) {
- /* link chunk onto overflow free list */
- ii_free_overflow(ip, np->vchunk_id);
- } else {
- /* write old free list head into chunk */
- nl.next_chunk = ip->bi_shdfchk;
- ip->bi_shdfchk = np->vchunk_id;
- ASSERT(ip->bi_shdfchk == II_NULLCHUNK ||
- (ip->bi_shdfchk >= 0 && ip->bi_shdfchk < ip->bi_shdchks));
- fba = CHUNK_FBA(np->vchunk_id);
- (void) _ii_rsrv_devs(ip, SHDR, II_INTERNAL);
- (void) _ii_nsc_io(ip, KS_SHD, SHDFD(ip), NSC_WRBUF, fba,
- (unsigned char *)&nl, sizeof (nl));
- _ii_rlse_devs(ip, SHDR);
- /* update free counts */
- /* ip->bi_unused++; */
- }
- np->vchunk_id = II_NULLCHUNK;
- (void) node_io(ip, np, ni, NSC_WRBUF);
- (void) update_tree_header(ip);
- mutex_exit(&ip->bi_chksmutex);
-
-}
-
-/*
- * Public functions for dsw_dev to use.
- */
-
-/*
- * Overflow volume functions.
- */
-
-/* put overflow chunk on the overflow volume free list */
-void
-ii_free_overflow(_ii_info_t *ip, chunkid_t chunk)
-{
- ii_nodelink_t nl;
- _ii_overflow_t *op;
- int fba;
-
- if (!II_ISOVERFLOW(chunk)) {
- DTRACE_PROBE(_iit_free_overflow_end_1);
- return;
- }
- chunk = II_2OVERFLOW(chunk);
-
- op = ip->bi_overflow;
- if (op == NULL) {
-#ifdef DEBUG
- cmn_err(CE_PANIC, "overflow used, but not attached ip %p",
- (void *) ip);
-#endif
- DTRACE_PROBE(_iit_free_overflow_end_2);
- return;
- }
- mutex_enter(&(op->ii_mutex));
-
- DTRACE_PROBE(_iit_free_overflow);
-
- /* write old free list head into chunk */
- nl.next_chunk = op->ii_freehead;
- fba = CHUNK_FBA(chunk);
- (void) nsc_reserve(op->ii_dev->bi_fd, NSC_MULTI);
- (void) _ii_nsc_io(ip, KS_OVR, op->ii_dev->bi_fd, NSC_WRBUF, fba,
- (unsigned char *)&nl, sizeof (nl));
- /* update free counts */
- op->ii_unused++;
- ASSERT(op->ii_used > 0); /* always use 1 for header */
-
- /* write chunk id into header freelist start */
- op->ii_freehead = chunk;
-
- (void) update_overflow_header(ip, op);
- nsc_release(op->ii_dev->bi_fd);
- mutex_exit(&(op->ii_mutex));
-
-}
-
-/* reclaim any overflow storage used by the volume */
-void
-ii_reclaim_overflow(_ii_info_t *ip)
-{
- NODE *node;
- nodeid_t node_id;
- _ii_overflow_t *op;
-
- if ((ip->bi_flags & (DSW_VOVERFLOW | DSW_FRECLAIM)) == 0) {
- DTRACE_PROBE(_iit_reclaim_overflow_end);
- return;
- }
-
- /*
- * Determine whether overflow should be reclaimed:
- * 1/ If we're not doing a group volume update
- * OR
- * 2/ If the number of detaches != number of attached vols
- */
- op = ip->bi_overflow;
- if (op && (((op->ii_flags & IIO_VOL_UPDATE) == 0) ||
- (op->ii_detachcnt != op->ii_drefcnt))) {
-#ifndef II_MULTIMULTI_TERABYTE
- /* assert volume size fits into node_id */
- ASSERT(ip->bi_mstchks <= INT32_MAX);
-#endif
- for (node_id = 0; node_id < ip->bi_mstchks; node_id++) {
- if ((node = read_node(ip, node_id)) == NULL) {
- DTRACE_PROBE(_iit_reclaim_overflow_end);
- return;
- }
- ii_free_overflow(ip, node->vchunk_id);
- release_node(ip, node, node_id);
- }
- } else {
- /* need to reset the overflow volume header */
- op->ii_freehead = II_NULLNODE;
- op->ii_used = 1; /* we have used the header */
- op->ii_unused = op->ii_nchunks - op->ii_used;
- (void) update_overflow_header(ip, op);
- }
-
- DTRACE_PROBE(_iit_reclaim_overflow);
-
- if ((ip->bi_flags & DSW_VOVERFLOW) == DSW_VOVERFLOW) {
- mutex_enter(&ip->bi_mutex);
- II_FLAG_CLR(DSW_VOVERFLOW, ip);
- mutex_exit(&ip->bi_mutex);
- }
- --iigkstat.spilled_over.value.ul;
-
-}
-
-static chunkid_t
-ii_alloc_overflow(_ii_info_t *ip)
-{
- chunkid_t chunk;
- ii_nodelink_t nl;
- _ii_overflow_t *op;
- int fba;
-
- if ((op = ip->bi_overflow) == NULL) {
- DTRACE_PROBE(_iit_alloc_overflow_end);
- return (II_NULLCHUNK); /* no overflow volume attached */
- }
-
- mutex_enter(&(op->ii_mutex));
-
- DTRACE_PROBE(_iit_alloc_overflow);
-
- if (op->ii_unused < 1) {
- mutex_exit(&(op->ii_mutex));
- DTRACE_PROBE(_iit_alloc_overflow_end);
- return (II_NULLCHUNK);
- }
- (void) nsc_reserve(op->ii_dev->bi_fd, NSC_MULTI);
- if (op->ii_freehead != II_NULLCHUNK) {
- /* pick first from free list */
- chunk = op->ii_freehead;
- fba = CHUNK_FBA(chunk);
- (void) _ii_nsc_io(ip, KS_OVR, op->ii_dev->bi_fd, NSC_RDBUF, fba,
- (unsigned char *)&nl, sizeof (nl));
- op->ii_freehead = nl.next_chunk;
- /* decrease unused count, fix bug 4419956 */
- op->ii_unused--;
- } else {
- /* otherwise pick first unused */
- if (op->ii_used > op->ii_nchunks)
- chunk = II_NULLCHUNK;
- else {
- chunk = op->ii_used++;
- op->ii_unused--;
- }
- }
- if (chunk != II_NULLCHUNK) {
- chunk = II_2OVERFLOW(chunk);
- if ((ip->bi_flags&DSW_VOVERFLOW) == 0) {
- mutex_enter(&ip->bi_mutex);
- II_FLAG_SET(DSW_VOVERFLOW, ip);
- mutex_exit(&ip->bi_mutex);
- ++iigkstat.spilled_over.value.ul;
- }
- }
- (void) update_overflow_header(ip, op);
- nsc_release(op->ii_dev->bi_fd);
- mutex_exit(&(op->ii_mutex));
-
- return (chunk);
-}
-/*
- * Find or insert key into search tree.
- */
-
-chunkid_t
-ii_tsearch(_ii_info_t *ip, chunkid_t chunk_id)
- /* Address of the root of the tree */
-{
- NODE *rootp = NULL;
- chunkid_t n; /* New node id if key not found */
-
- if ((rootp = read_node(ip, chunk_id)) == NULL) {
- DTRACE_PROBE(_iit_tsearch_end);
- return (II_NULLNODE);
- }
- n = rootp->vchunk_id;
- if (n != II_NULLCHUNK) { /* chunk allocated, return location */
- release_node(ip, rootp, 0);
- DTRACE_PROBE(_iit_tsearch_end);
- return (n);
- }
- n = alloc_chunk(ip);
- if (n != II_NULLCHUNK) {
- rootp->vchunk_id = n;
- write_node(ip, rootp, chunk_id);
- } else
- release_node(ip, rootp, 0);
-
- return (n);
-}
-
-/* Delete node with key chunkid */
-void
-ii_tdelete(_ii_info_t *ip,
- chunkid_t chunkid) /* Key to be deleted */
-{
- NODE *np = NULL;
-
- if ((np = read_node(ip, chunkid)) == NULL) {
- DTRACE_PROBE(_iit_tdelete_end);
- return;
- }
-
- ASSERT(np->vchunk_id != II_NULLCHUNK);
- free_node(ip, np, chunkid);
- np->vchunk_id = II_NULLCHUNK;
- write_node(ip, np, chunkid);
-
-}
-
-/*
- * initialise an empty map for ip
- */
-
-int
-ii_tinit(_ii_info_t *ip)
-{
- int rc = 0;
-
- /* overflow can't be attached before first call to this function */
- if (ip->bi_overflow)
- ii_reclaim_overflow(ip);
-
- mutex_enter(&ip->bi_chksmutex);
- ip->bi_shdfchk = II_NULLCHUNK; /* set freelist to empty chain */
- ip->bi_shdchkused = 0;
-
- /* fill index (bi_mstchks size) with II_NULLCHUNK */
- rc = node_fba_fill(ip, ip->bi_mstchks, II_NULLCHUNK);
- if (rc == 0)
- rc = update_tree_header(ip);
- mutex_exit(&ip->bi_chksmutex);
-
- return (rc);
-}
-
-/*
- * Calculate the size of map space provided by a bitmap volume with
- * tree_len fba's spare for the tree.
- */
-
-nsc_size_t
-ii_btsize(nsc_size_t tree_len)
-{
- nsc_size_t nchunks;
-
- nchunks = tree_len * nodes_per_fba;
-
- if (ii_debug > 1)
- cmn_err(CE_NOTE,
- "!ii_btsize: bitmap with %" NSC_SZFMT
- " spare fba's will map %" NSC_SZFMT " chunks",
- tree_len, nchunks);
-
- return (nchunks);
-}
diff --git a/usr/src/uts/common/avs/ns/model.h b/usr/src/uts/common/avs/ns/model.h
deleted file mode 100644
index 9c6c1a14af..0000000000
--- a/usr/src/uts/common/avs/ns/model.h
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SYS_NSCTL_MODEL_H
-#define _SYS_NSCTL_MODEL_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Stolen from Solaris 8
- * Only used for Solaris 2.6
- */
-#define _ILP32
-#undef _ASM
-
-
-#ifdef _KERNEL
-#include <sys/debug.h>
-#endif
-
-#ifndef DS_DDICT
-#include <sys/isa_defs.h>
-#endif
-
-typedef uint32_t caddr32_t;
-
-#if defined(_KERNEL) || defined(_KMEMUSER)
-
-/*
- * These bits are used in various places to specify the data model
- * of the originator (and/or consumer) of data items. See <sys/conf.h>
- * <sys/file.h>, <sys/stream.h> and <sys/sunddi.h>.
- *
- * This state should only be known to the kernel implementation.
- */
-#define DATAMODEL_MASK 0x0FF00000
-
-#define DATAMODEL_ILP32 0x00100000
-#define DATAMODEL_LP64 0x00200000
-
-#define DATAMODEL_NONE 0
-
-#if defined(_LP64)
-#define DATAMODEL_NATIVE DATAMODEL_LP64
-#elif defined(_ILP32)
-#define DATAMODEL_NATIVE DATAMODEL_ILP32
-#else
-#error "No DATAMODEL_NATIVE specified"
-#endif /* _LP64 || _ILP32 */
-
-#endif /* _KERNEL || _KMEMUSER */
-
-#ifndef _ASM
-/*
- * XXX Ick. This type needs to be visible outside the above guard because
- * the proc structure is visible outside the _KERNEL | _KMEMUSER guard.
- * If we can make proc internals less visible, (which we obviously should)
- * then this can be invisible too.
- */
-typedef unsigned int model_t;
-
-#endif /* _ASM */
-
-#if defined(_KERNEL) && !defined(_ASM)
-/*
- * These macros allow two views of the same piece of memory depending
- * on the originating user-mode program's data model. See the manual
- * pages (or uts/README.XX64).
- */
-#if defined(_LP64)
-
-#define STRUCT_HANDLE(struct_type, handle) \
- struct __##handle##_type { \
- union { \
- struct struct_type##32 *m32; \
- struct struct_type *m64; \
- } ptr; \
- model_t model; \
- } handle = { NULL, DATAMODEL_ILP32 }
-
-#define STRUCT_DECL(struct_type, handle) \
- struct struct_type __##handle##_buf; \
- STRUCT_HANDLE(struct_type, handle)
-
-#define STRUCT_SET_HANDLE(handle, umodel, addr) \
- (handle).model = (model_t)(umodel) & DATAMODEL_MASK; \
- ASSERT(((umodel) & DATAMODEL_MASK) != DATAMODEL_NONE); \
- ((handle).ptr.m64) = (addr)
-
-#define STRUCT_INIT(handle, umodel) \
- STRUCT_SET_HANDLE(handle, umodel, &__##handle##_buf)
-
-#define STRUCT_SIZE(handle) \
- ((handle).model == DATAMODEL_ILP32 ? \
- sizeof (*(handle).ptr.m32) : \
- sizeof (*(handle).ptr.m64))
-
-/*
- * In STRUCT_FADDR and STRUCT_FGETP a sleight of hand is employed to make
- * the compiler cope with having two different pointer types within ?:.
- * The (void *) case on the ILP32 case makes it a pointer which can be
- * converted to the pointer on the LP64 case, thus quieting the compiler.
- */
-#define STRUCT_FADDR(handle, field) \
- ((handle).model == DATAMODEL_ILP32 ? \
- (void *)&(handle).ptr.m32->field : \
- &(handle).ptr.m64->field)
-
-#define STRUCT_FGET(handle, field) \
- (((handle).model == DATAMODEL_ILP32) ? \
- (handle).ptr.m32->field : \
- (handle).ptr.m64->field)
-
-#define STRUCT_FGETP(handle, field) \
- ((handle).model == DATAMODEL_ILP32 ? \
- (void *)(handle).ptr.m32->field : \
- (handle).ptr.m64->field)
-
-#define STRUCT_FSET(handle, field, val) \
- ((handle).model == DATAMODEL_ILP32 ? \
- ((handle).ptr.m32->field = (val)) : \
- ((handle).ptr.m64->field = (val)))
-
-#define STRUCT_FSETP(handle, field, val) \
- ((handle).model == DATAMODEL_ILP32 ? \
- (void) ((handle).ptr.m32->field = (caddr32_t)(val)) : \
- (void) ((handle).ptr.m64->field = (val)))
-
-#define STRUCT_BUF(handle) ((handle).ptr.m64)
-
-#define SIZEOF_PTR(umodel) \
- (((umodel) & DATAMODEL_MASK) == DATAMODEL_ILP32 ? \
- sizeof (caddr32_t) : \
- sizeof (caddr_t))
-
-#define SIZEOF_STRUCT(struct_type, umodel) \
- (((umodel) & DATAMODEL_MASK) == DATAMODEL_ILP32 ? \
- sizeof (struct struct_type##32) : \
- sizeof (struct struct_type))
-
-#else /* _LP64 */
-
-#define STRUCT_HANDLE(struct_type, handle) \
- struct __##handle##_32 { \
- struct struct_type *ptr; \
- }; \
- struct __##handle##_32 handle = { NULL }
-
-#define STRUCT_DECL(struct_type, handle) \
- struct struct_type __##handle##_buf; \
- STRUCT_HANDLE(struct_type, handle)
-
-#ifdef lint
-#define STRUCT_SET_HANDLE(handle, umodel, addr) \
- (void) (umodel); \
- (handle).ptr = (addr)
-#else
-#define STRUCT_SET_HANDLE(handle, umodel, addr) \
- (handle).ptr = (addr)
-#endif /* lint */
-
-#define STRUCT_INIT(handle, umodel) \
- STRUCT_SET_HANDLE(handle, umodel, &__##handle##_buf)
-
-#define STRUCT_SIZE(handle) (sizeof (*(handle).ptr))
-
-#define STRUCT_FADDR(handle, field) (&(handle).ptr->field)
-
-#define STRUCT_FGET(handle, field) ((handle).ptr->field)
-
-#define STRUCT_FGETP STRUCT_FGET
-
-#define STRUCT_FSET(handle, field, val) ((handle).ptr->field = (val))
-
-#define STRUCT_FSETP STRUCT_FSET
-
-#define STRUCT_BUF(handle) ((handle).ptr)
-
-#define SIZEOF_PTR(umodel) sizeof (caddr_t)
-
-#define SIZEOF_STRUCT(struct_type, umodel) sizeof (struct struct_type)
-
-#endif /* _LP64 */
-
-#if defined(_LP64) || defined(lint) || defined(__lint)
-
-struct _klwp;
-
-extern model_t lwp_getdatamodel(struct _klwp *);
-extern model_t get_udatamodel(void);
-
-#else
-
-/*
- * If we're the 32-bit kernel, the result of these function
- * calls is completely predictable, so let's just cheat. A
- * good compiler should be able to elide all the unreachable code
- * that results. Optimism about optimization reigns supreme ;-)
- */
-#define lwp_getdatamodel(t) DATAMODEL_ILP32
-#define get_udatamodel() DATAMODEL_ILP32
-
-#endif /* _LP64 || lint || __lint */
-
-#endif /* _KERNEL && !_ASM */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SYS_NSCTL_MODEL_H */
diff --git a/usr/src/uts/common/avs/ns/ncall_inter.h b/usr/src/uts/common/avs/ns/ncall_inter.h
deleted file mode 100644
index 5f4c0689e3..0000000000
--- a/usr/src/uts/common/avs/ns/ncall_inter.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SYS_NCALL_INTER_H
-#define _SYS_NCALL_INTER_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef _KERNEL
-
-void ncall_register_svc(int, void (*)(void *, int *)) { }
-void ncall_unregister_svc(int) { }
-int ncall_register_module(void *, void *);
-int ncall_unregister_module(void *);
-
-int ncall_nodeid(char *) { }
-char *ncall_nodename(int) { }
-int ncall_mirror(int) { }
-int ncall_self(void) { }
-
-int ncall_alloc(int, int, int, void **) { }
-int ncall_timedsend(void *, int, int, struct timeval *, ...) { }
-int ncall_timedsendnotify(void *, int, int, struct timeval *,
- void (*)(void *, void *), void *, ...) { }
-int ncall_send(void *, int, int, ...) { }
-int ncall_read_reply(void *, int, ...) { }
-void ncall_reset(void *) { }
-void ncall_free(void *) { }
-
-int ncall_put_data(void *, void *, int) { }
-int ncall_get_data(void *, void *, int) { }
-
-int ncall_sender(void *) { }
-void ncall_reply(void *, ...) { }
-void ncall_pend(void *) { }
-void ncall_done(void *) { }
-
-int ncall_maxnodes(void) { }
-int ncall_nextnode(void **) { }
-int ncall_errcode(void *, int *) { }
-
-
-/* Health monitor typedefs, variables and functions */
-typedef void hmio_name_t;
-typedef void hm_sarea_t;
-typedef void hm_statev_t;
-#ifndef _HM_TOK_T
-#define _HM_TOK_T
-typedef void *hm_tok_t;
-#endif
-
-int bchm_load(void) { }
-int bchm_unload(void) { }
-int bchm_getnetname(hmio_name_t *) { }
-int bchm_getstatename(hmio_name_t *) { }
-int bchm_startnet(hmio_name_t *, int) { }
-int bchm_initted;
-hm_sarea_t *bchm_start_addr[1];
-hm_sarea_t hm_latest_state;
-
-#endif /* _KERNEL */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SYS_NCALL_INTER_H */
diff --git a/usr/src/uts/common/avs/ns/nsctl.h b/usr/src/uts/common/avs/ns/nsctl.h
deleted file mode 100644
index c91d691684..0000000000
--- a/usr/src/uts/common/avs/ns/nsctl.h
+++ /dev/null
@@ -1,526 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SYS_NSCTL_H
-#define _SYS_NSCTL_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if (defined(lint) || defined(OSDEBUG)) && defined(_KERNEL)
-#define __NSC_GEN__
-#include <sys/ksynch.h>
-#include <sys/nsctl/nsc_dev.h>
-#include <sys/nsctl/nsc_gen.h>
-#include <sys/nsctl/nsc_mem.h>
-#include <sys/nsctl/nsc_rmspin.h>
-#endif
-
-
-/*
- * nsctl multi-terabyte volume support
- *
- * To build a multi-terabyte stack, '#define NSC_MULTI_TERABYTE'.
- */
-
-#ifdef NSC_MULTI_TERABYTE
-typedef uint64_t nsc_off_t; /* positions, offsets */
-typedef uint64_t nsc_size_t; /* lengths, sizes */
-#ifdef _LP64
-#define NSC_SZFMT "lu"
-#define NSC_XSZFMT "lx"
-#else
-#define NSC_SZFMT "llu"
-#define NSC_XSZFMT "llx"
-#endif
-
-#else /* max 1TB volume size */
-typedef int nsc_off_t;
-typedef int nsc_size_t;
-#define NSC_SZFMT "u"
-#define NSC_XSZFMT "x"
-#endif
-
-
-#ifdef _KERNEL
-
-#ifdef sun
-#include <sys/nsc_ddi.h>
-#endif
-
-/*
- * Generic parameter definition.
- */
-
-typedef struct nsc_def_s {
- char *name; /* Parameter name */
- uintptr_t value; /* Parameter value */
- int offset; /* Structure offset */
-} nsc_def_t;
-
-extern int nsc_inval(), nsc_ioerr();
-extern int nsc_fatal(), nsc_null(), nsc_true();
-extern void nsc_decode_param(nsc_def_t *, nsc_def_t *, long *);
-#endif /* _KERNEL */
-
-
-/* ID and Type flags */
-
-#define NSC_ID 0x40000000 /* Module ID */
-#define NSC_NULL 0x00000100 /* No I/O possible */
-#define NSC_DEVICE 0x00000200 /* Device interface */
-#define NSC_FILE 0x00000400 /* File vnode interface */
-#define NSC_CACHE 0x00000800 /* Cache interface */
-#define NSC_ANON 0x00001000 /* Supports anonymous buffers */
-#define NSC_VCHR 0x00002000 /* VCHR vnode device */
-#define NSC_NCALL 0x00004000 /* ncall-io interface */
-
-#define NSC_IDS 0x7ff00000 /* ID mask */
-#define NSC_TYPES 0x7fffff00 /* Type mask */
-
-#define NSC_MKID(x) (NSC_ID | ((x) << 20))
-
-#define NSC_RAW_ID NSC_MKID(39) /* Raw device */
-#define NSC_FILE_ID NSC_MKID(40) /* File vnode device */
-#define NSC_FREEZE_ID NSC_MKID(41) /* Frozen raw device */
-#define NSC_VCHR_ID NSC_MKID(42) /* VCHR vnode device */
-#define NSC_NCALL_ID NSC_MKID(43) /* ncall-io */
-#define NSC_SDBC_ID NSC_MKID(80) /* Block based cache */
-#define NSC_RDCLR_ID NSC_MKID(94) /* RDC (low, raw) */
-#define NSC_RDCL_ID NSC_MKID(95) /* RDC (low, cache) */
-#define NSC_IIR_ID NSC_MKID(96) /* Instant Image (raw) */
-#define NSC_II_ID NSC_MKID(98) /* Instant Image */
-#define NSC_RDCHR_ID NSC_MKID(99) /* RDC (high, raw) */
-#define NSC_RDCH_ID NSC_MKID(100) /* RDC (high, cache) */
-
-typedef enum nsc_power_ops_e {
- Power_Lost, /* Power Failing initial warning */
- /* with timeleft (rideout) minutes */
-
- Power_OK, /* Power OK or restored before death */
-
- Power_Down /* that's all folks machine will */
- /* be shutdown, save any state */
-} nsc_power_ops_t;
-
-#ifdef _KERNEL
-
-/* Module Flags */
-
-#define NSC_REFCNT 0x00000001 /* Counts references */
-#define NSC_FILTER 0x00000002 /* Uses lower level driver */
-
-
-#ifndef _NSC_DEV_H
-typedef struct nsc_io_s { int x; } nsc_io_t;
-typedef struct nsc_path_s { int x; } nsc_path_t;
-#endif
-
-extern nsc_io_t *nsc_register_io(char *, int, nsc_def_t *);
-extern int nsc_unregister_io(nsc_io_t *, int);
-extern nsc_path_t *nsc_register_path(char *, int, nsc_io_t *);
-extern int nsc_unregister_path(nsc_path_t *, int);
-extern int nsc_cache_sizes(int *, int *);
-extern int nsc_node_hints(unsigned int *);
-extern int nsc_node_hints_set(unsigned int);
-extern blind_t nsc_register_power(char *, nsc_def_t *);
-extern int nsc_unregister_power(blind_t);
-
-/*
- * Strategy function interface
- */
-#ifndef DS_DDICT
-typedef int (*strategy_fn_t)(struct buf *);
-#endif
-extern strategy_fn_t nsc_get_strategy(major_t);
-
-extern void *nsc_get_devops(major_t);
-
-#endif /* _KERNEL */
-
-
-/* Block sizes */
-
-#define FBA_SHFT 9
-#define FBA_MASK 0x1ff
-#define FBA_SIZE(x) ((x) << FBA_SHFT) /* fba to bytes */
-#define FBA_OFF(x) ((x) & FBA_MASK) /* byte offset */
-#define FBA_LEN(x) FBA_NUM((x) + FBA_MASK) /* len to fba */
-#define FBA_NUM(x) ((nsc_size_t)((uint64_t)(x) >> FBA_SHFT))
- /* bytes to fba */
-
-
-/* Return values */
-
-#define NSC_DONE (0)
-#define NSC_PENDING (-1)
-#define NSC_HIT (-2)
-
-
-#if defined(_KERNEL) || defined(_KMEMUSER)
-
-/*
- * External file descriptor.
- */
-
-#ifndef _NSC_DEV_H
-typedef struct nsc_fd_s { int x; } nsc_fd_t;
-#endif
-
-#endif /* _KERNEL || _KMEMUSER */
-
-
-#ifdef _KERNEL
-
-#define NSC_TRY (1<<24) /* Conditional operation */
-#define NSC_PCATCH (1<<25) /* Catch signals */
-#define NSC_DEFER (1<<26) /* Defer if busy */
-#define NSC_MULTI (1<<27) /* Multiple reserves */
-#define NSC_NOWAIT (1<<28) /* Don't wait if busy */
-
-extern nsc_fd_t *nsc_open(char *, int, nsc_def_t *, blind_t, int *);
-extern int nsc_close(nsc_fd_t *);
-extern char *nsc_pathname(nsc_fd_t *);
-extern int nsc_fdpathcmp(nsc_fd_t *, uint64_t, char *);
-extern int nsc_shared(nsc_fd_t *);
-extern int nsc_setval(nsc_fd_t *, char *, int);
-extern int nsc_getval(nsc_fd_t *, char *, int *);
-extern int nsc_set_trksize(nsc_fd_t *, nsc_size_t);
-extern int nsc_discard_pinned(nsc_fd_t *, nsc_off_t, nsc_size_t);
-extern kmutex_t *nsc_lock_addr(nsc_fd_t *);
-extern int nsc_attach(nsc_fd_t *, int);
-extern int nsc_reserve(nsc_fd_t *, int);
-extern void nsc_reserve_lk(nsc_fd_t *);
-extern void nsc_release(nsc_fd_t *);
-extern int nsc_release_lk(nsc_fd_t *);
-extern int nsc_detach(nsc_fd_t *, int);
-extern int nsc_avail(nsc_fd_t *);
-extern int nsc_held(nsc_fd_t *);
-extern int nsc_waiting(nsc_fd_t *);
-extern int nsc_partsize(nsc_fd_t *, nsc_size_t *);
-extern int nsc_maxfbas(nsc_fd_t *, int, nsc_size_t *);
-extern int nsc_get_pinned(nsc_fd_t *);
-extern int nsc_max_devices(void);
-extern int nsc_control(nsc_fd_t *, int, void *, int);
-
-#endif /* _KERNEL */
-
-
-#if defined(_KERNEL) || defined(_KMEMUSER)
-
-/*
- * I/O device structure.
- */
-
-#ifndef _NSC_DEV_H
-typedef struct nsc_iodev_s { int x; } nsc_iodev_t;
-#endif
-
-#ifdef _KERNEL
-extern void nsc_set_owner(nsc_fd_t *, nsc_iodev_t *);
-extern void nsc_pinned_data(nsc_iodev_t *, nsc_off_t, nsc_size_t);
-extern void nsc_unpinned_data(nsc_iodev_t *, nsc_off_t, nsc_size_t);
-#endif
-
-
-/*
- * Data structures used by I/O interface.
- */
-
-typedef struct nsc_vec_s { /* Scatter gather element */
- unsigned char *sv_addr; /* Virtual address of data */
- unsigned long sv_vme; /* VME address of data */
- int sv_len; /* Data length in bytes */
-} nsc_vec_t;
-
-
-typedef struct nsc_buf_s { /* Buffer structure */
- nsc_fd_t *sb_fd; /* File descriptor */
- nsc_off_t sb_pos; /* Block offset of data */
- nsc_size_t sb_len; /* Length of data in blocks */
- volatile int sb_flag; /* Buffer flags */
- int sb_error; /* Error code */
- uintptr_t sb_user; /* User definable */
- nsc_vec_t *sb_vec; /* Scatter gather list */
-} nsc_buf_t;
-
-#endif /* _KERNEL || _KMEMUSER */
-
-
-/* Allocate flags */
-
-#define NSC_RDBUF 0x0001
-#define NSC_WRBUF 0x0002
-#define NSC_PINNABLE 0x0004
-#define NSC_NOBLOCK 0x0008
-
-#define NSC_READ (NSC_RDBUF)
-#define NSC_WRITE (NSC_WRBUF)
-#define NSC_RDWR (NSC_RDBUF | NSC_WRBUF)
-#define NSC_RDWRBUF (NSC_RDBUF | NSC_WRBUF)
-
-
-/* Other flags */
-
-#define NSC_CACHEBLK 0x0008 /* nsc_maxfbas: size of cache block in fbas */
-#define NSC_HALLOCATED 0x0010 /* handle allocated (IO provider internals) */
-#define NSC_HACTIVE 0x0020 /* handle active (IO provider internals) */
-#define NSC_BCOPY 0x0040 /* bcopy, don't DMA when moving data */
-#define NSC_PAGEIO 0x0080 /* client will use handle for pageio */
-#define NSC_ABUF 0x0100 /* anonymous buffer handle */
-#define NSC_MIXED 0x0200 /* data from 2 devs is mixed in this buffer */
-#define NSC_NODATA 0x0400 /* allocate without data buffer (sb_vec) */
-
-
-#define NSC_FLAGS 0xffff
-
-#ifdef _KERNEL
-
-#define NSC_ANON_CD ((blind_t)(-1)) /* used for IO provider alloc buf */
-
-extern int nsc_alloc_buf(nsc_fd_t *, nsc_off_t, nsc_size_t, int, nsc_buf_t **);
-extern int nsc_alloc_abuf(nsc_off_t, nsc_size_t, int, nsc_buf_t **);
-extern int nsc_read(nsc_buf_t *, nsc_off_t, nsc_size_t, int);
-extern int nsc_write(nsc_buf_t *, nsc_off_t, nsc_size_t, int);
-extern int nsc_zero(nsc_buf_t *, nsc_off_t, nsc_size_t, int);
-extern int nsc_copy(nsc_buf_t *, nsc_buf_t *, nsc_off_t, nsc_off_t, nsc_size_t);
-extern int nsc_copy_direct(nsc_buf_t *, nsc_buf_t *, nsc_off_t,
- nsc_off_t, nsc_size_t);
-extern int nsc_uncommit(nsc_buf_t *, nsc_off_t, nsc_size_t, int);
-extern int nsc_free_buf(nsc_buf_t *);
-extern nsc_buf_t *nsc_alloc_handle(nsc_fd_t *,
- void (*)(), void (*)(), void (*)());
-extern int nsc_free_handle(nsc_buf_t *);
-extern int nsc_uread(nsc_fd_t *, void *, void *);
-extern int nsc_uwrite(nsc_fd_t *, void *, void *);
-
-#endif /* _KERNEL */
-
-
-/*
- * Performance hints.
- */
-
-#define NSC_WRTHRU 0x00010000
-#define NSC_FORCED_WRTHRU 0x00020000
-#define NSC_NOCACHE 0x00040000
-#define NSC_QUEUE 0x00080000
-#define NSC_RDAHEAD 0x00100000
-#define NSC_NO_FORCED_WRTHRU 0x00200000
-#define NSC_METADATA 0x00400000
-#define NSC_SEQ_IO 0x00800000
-
-#define NSC_HINTS 0x00ff0000
-
-
-#ifdef _KERNEL
-/*
- * node hint actions
- */
-
-#define NSC_GET_NODE_HINT 0
-#define NSC_SET_NODE_HINT 1
-#define NSC_CLEAR_NODE_HINT 2
-
-/*
- * Reflective memory spinlocks.
- */
-
-
-#ifndef _NSC_RMSPIN_H
-typedef struct nsc_rmlock_s { int x; } nsc_rmlock_t;
-#endif
-
-
-extern nsc_rmlock_t *nsc_rm_lock_alloc(char *, int, void *);
-extern void nsc_rm_lock_dealloc(nsc_rmlock_t *);
-extern int nsc_rm_lock(nsc_rmlock_t *);
-extern void nsc_rm_unlock(nsc_rmlock_t *);
-
-#endif /* _KERNEL */
-
-
-/*
- * Memory allocation routines.
- */
-
-#define NSC_MEM_LOCAL 0x1
-#define NSC_MEM_GLOBAL 0x4
-
-#define NSC_MEM_RESIZE 0x100
-#define NSC_MEM_NVDIRTY 0x400
-
-
-#ifdef _KERNEL
-
-#ifndef _NSC_MEM_H
-typedef struct nsc_mem_s { int x; } nsc_mem_t;
-#endif
-
-
-extern nsc_mem_t *nsc_register_mem(char *, int, int);
-extern void nsc_unregister_mem(nsc_mem_t *);
-extern void *nsc_kmem_alloc(size_t, int, nsc_mem_t *);
-extern void *nsc_kmem_zalloc(size_t, int, nsc_mem_t *);
-extern void nsc_kmem_free(void *, size_t);
-extern void nsc_mem_sizes(nsc_mem_t *, size_t *, size_t *, size_t *);
-extern size_t nsc_mem_avail(nsc_mem_t *);
-
-/* nvmem suppport */
-typedef void (*nsc_mem_err_cb) (void *, void *, size_t, int);
-extern int nsc_commit_mem(void *, void *, size_t, nsc_mem_err_cb);
-
-extern void nsc_cm_errhdlr(void *, void *, size_t, int);
-
-#endif /* _KERNEL */
-
-
-/*
- * Max pathname
- * Note: Currently defined both here and in nsc_dev.h
- */
-#if !defined(NSC_MAXPATH)
-#define NSC_MAXPATH 64
-#endif
-
-#ifdef _KERNEL
-
-/*
- * Inter-module function (callback) services
- */
-
-#ifndef _NSC_GEN_H
-typedef struct nsc_svc_s { int x; } nsc_svc_t;
-#endif
-
-extern nsc_svc_t *nsc_register_svc(char *, void (*)(intptr_t));
-extern int nsc_unregister_svc(nsc_svc_t *);
-extern int nsc_call_svc(nsc_svc_t *, intptr_t);
-
-
-/*
- * String manipulation functions.
- */
-
-#ifndef sun
-#define sprintf nsc_sprintf
-#endif /* sun */
-
-extern char *nsc_strdup(char *);
-extern void nsc_strfree(char *);
-extern int nsc_strmatch(char *, char *);
-extern void nsc_sprintf(char *, char *, ...);
-extern uint64_t nsc_strhash(char *);
-
-
-/*
- * Macro definitions.
- */
-
-#define NSC_HIER 1
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-
-/*
- * External definitions.
- */
-
-#undef HZ
-extern clock_t HZ;
-extern int nsc_max_nodeid, nsc_min_nodeid;
-
-extern int nsc_node_id(void);
-extern char *nsc_node_name(void);
-extern int nsc_node_up(int);
-extern time_t nsc_time(void);
-extern clock_t nsc_lbolt(void);
-extern int nsc_delay_sig(clock_t);
-extern clock_t nsc_usec(void);
-extern void nsc_yield(void);
-
-extern void nsc_membar_stld(void);
-extern uint8_t nsc_ldstub(uint8_t *);
-extern caddr_t nsc_caller(void);
-extern caddr_t nsc_callee(void);
-
-extern int nsc_create_process(void (*)(void *), void *, boolean_t);
-
-extern int nsc_power_init(void);
-extern void nsc_power_deinit(void);
-extern int nsc_nodeid_data(void);
-
-#define NSC_ALERT_INFO 0 /* Information alert */
-#define NSC_ALERT_WARNING 1 /* Warning alert */
-#define NSC_ALERT_ERROR 2 /* Error alert */
-#define NSC_ALERT_DOWN 3 /* System or Module down */
-
-extern void nsc_do_sysevent(char *, char *, int, int, char *, dev_info_t *);
-
-
-/*
- * Missing DDI/DKI definition.
- */
-
-#if defined(_SYS_CONF_H)
-#ifndef D_MP
-#define D_MP 0
-#endif
-#endif
-
-extern void *nsc_threadp(void);
-
-#endif /* _KERNEL */
-
-
-/*
- * Common defines
- */
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#ifndef NBBY
-#define NBBY 8 /* number of bits per byte */
-#endif
-
-/*
- * kstat definition
- */
-#define KSTAT_DATA_CHAR_LEN (sizeof (((kstat_named_t *)0)->value.c))
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SYS_NSCTL_H */
diff --git a/usr/src/uts/common/avs/ns/nsctl/Makefile b/usr/src/uts/common/avs/ns/nsctl/Makefile
deleted file mode 100644
index 2ea51f19da..0000000000
--- a/usr/src/uts/common/avs/ns/nsctl/Makefile
+++ /dev/null
@@ -1,55 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# include global definitions
-include ../../../../../Makefile.master
-
-HDRS= nsc_dev.h \
- nsc_gen.h \
- nsc_ioctl.h \
- nsc_mem.h \
- nsc_rmspin.h \
- nsc_disk.h \
- nsc_power.h \
- nsvers.h
-
-ROOTDIRS= $(ROOT)/usr/include/sys/nsctl
-
-ROOTHDRS= $(HDRS:%=$(ROOTDIRS)/%)
-
-CHECKHDRS= $(HDRS:%.h=%.check)
-
-# install rule
-$(ROOTDIRS)/%: %
- $(INS.file)
-
-.KEEP_STATE:
-
-.PARALLEL: $(CHECKHDRS)
-
-install_h: $(ROOTDIRS) $(ROOTHDRS)
-
-$(ROOTDIRS):
- $(INS.dir)
-
-check: $(CHECKHDRS)
diff --git a/usr/src/uts/common/avs/ns/nsctl/nsc_cache.c b/usr/src/uts/common/avs/ns/nsctl/nsc_cache.c
deleted file mode 100644
index bdb7009644..0000000000
--- a/usr/src/uts/common/avs/ns/nsctl/nsc_cache.c
+++ /dev/null
@@ -1,499 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/ksynch.h>
-#include <sys/errno.h>
-#include <sys/uio.h>
-#include <sys/ddi.h>
-
-#define __NSC_GEN__
-#include "nsc_dev.h"
-
-#ifdef DS_DDICT
-#include "../contract.h"
-#endif
-
-#include "../nsctl.h"
-
-
-#define _I(x) (((long)(&((nsc_io_t *)0)->x))/sizeof (long))
-
-
-nsc_def_t _nsc_cache_def[] = {
- "AllocBuf", (uintptr_t)nsc_ioerr, _I(alloc_buf),
- "FreeBuf", (uintptr_t)nsc_fatal, _I(free_buf),
- "Read", (uintptr_t)nsc_fatal, _I(read),
- "Write", (uintptr_t)nsc_fatal, _I(write),
- "Zero", (uintptr_t)nsc_fatal, _I(zero),
- "Copy", (uintptr_t)nsc_ioerr, _I(copy),
- "CopyDirect", (uintptr_t)nsc_ioerr, _I(copy_direct),
- "Uncommit", (uintptr_t)nsc_null, _I(uncommit),
- "AllocHandle", (uintptr_t)nsc_null, _I(alloc_h),
- "FreeHandle", (uintptr_t)nsc_fatal, _I(free_h),
- "TrackSize", (uintptr_t)nsc_null, _I(trksize),
- "Discard", (uintptr_t)nsc_null, _I(discard),
- "Sizes", (uintptr_t)nsc_null, _I(sizes),
- "GetPinned", (uintptr_t)nsc_null, _I(getpin),
- "NodeHints", (uintptr_t)nsc_inval, _I(nodehints),
- 0, 0, 0
-};
-
-
-static int _nsc_alloc_buf_h(blind_t, nsc_off_t, nsc_size_t, int,
- nsc_buf_t **, nsc_fd_t *);
-static int _nsc_copy_h(nsc_buf_t *, nsc_buf_t *, nsc_off_t,
- nsc_off_t, nsc_size_t);
-
-extern nsc_io_t *_nsc_reserve_io(char *, int);
-extern void _nsc_release_io(nsc_io_t *);
-
-extern kmutex_t _nsc_io_lock;
-
-
-
-
-/* ARGSUSED */
-
-void
-_nsc_add_cache(nsc_io_t *io)
-{
-}
-
-
-nsc_buf_t *
-nsc_alloc_handle(nsc_fd_t *fd, void (*d_cb)(), void (*r_cb)(), void (*w_cb)())
-{
- nsc_buf_t *h = (*fd->sf_aio->alloc_h)(d_cb, r_cb, w_cb, fd->sf_cd);
-
- if (h)
- h->sb_fd = fd;
-
- return (h);
-}
-
-
-int
-nsc_free_handle(nsc_buf_t *h)
-{
- if (h == NULL || (h->sb_flag & NSC_ABUF))
- return (EINVAL);
-
- return ((*h->sb_fd->sf_aio->free_h)(h, h->sb_fd->sf_cd));
-}
-
-
-int
-nsc_alloc_abuf(nsc_off_t pos, nsc_size_t len, int flag, nsc_buf_t **ptr)
-{
- nsc_buf_t *h;
- nsc_io_t *io;
- int rc;
-
- if (*ptr != NULL)
- return (EINVAL);
-
- if (flag & NSC_NODATA)
- return (EINVAL);
-
- io = _nsc_reserve_io(NULL, NSC_ANON);
- if (io == NULL)
- return (ENOBUFS);
-
- if ((h = (*io->alloc_h)(NULL, NULL, NULL, NSC_ANON_CD)) == NULL) {
- _nsc_release_io(io);
- return (ENOBUFS);
- }
-
- rc = (*io->alloc_buf)(NSC_ANON_CD, pos, len,
- NSC_NOCACHE|flag, &h, NULL);
- if (rc <= 0) {
- h->sb_flag &= ~NSC_HALLOCATED;
- h->sb_flag |= NSC_ABUF;
- h->sb_fd = (nsc_fd_t *)io; /* note overloaded field */
-
- *ptr = h;
-
- mutex_enter(&_nsc_io_lock);
- io->abufcnt++;
- mutex_exit(&_nsc_io_lock);
- }
-
- _nsc_release_io(io);
- return (rc);
-}
-
-
-int
-nsc_alloc_buf(nsc_fd_t *fd, nsc_off_t pos, nsc_size_t len,
- int flag, nsc_buf_t **ptr)
-{
- int (*fn)() = _nsc_alloc_buf_h;
-
- if ((fd->sf_avail & NSC_WRITE) == 0)
- if (flag & NSC_WRBUF)
- return (EACCES);
-
- if ((flag & (NSC_READ|NSC_WRITE|NSC_NODATA)) ==
- (NSC_READ|NSC_NODATA)) {
- /*
- * NSC_NODATA access checks.
- *
- * - NSC_READ|NSC_NODATA is illegal since there would
- * be no data buffer to immediately read the data into.
- * - NSC_WRITE|NSC_NODATA is valid since the client can
- * provide the buffer and then call nsc_write() as
- * necessary.
- * - NSC_NODATA is valid since the client can provide the
- * buffer and then call nsc_read() or nsc_write() as
- * necessary.
- */
- return (EACCES);
- }
-
- if (*ptr) {
- fn = fd->sf_aio->alloc_buf;
- (*ptr)->sb_fd = fd;
- }
-
- return (*fn)(fd->sf_cd, pos, len, flag, ptr, fd);
-}
-
-
-/* ARGSUSED */
-
-static int
-_nsc_alloc_buf_h(blind_t cd, nsc_off_t pos, nsc_size_t len,
- int flag, nsc_buf_t **ptr, nsc_fd_t *fd)
-{
- nsc_buf_t *h;
- int rc;
-
- if (!(h = nsc_alloc_handle(fd, NULL, NULL, NULL)))
- return (ENOBUFS);
-
- if ((rc = nsc_alloc_buf(fd, pos, len, flag, &h)) <= 0) {
- h->sb_flag &= ~NSC_HALLOCATED;
- *ptr = h;
- return (rc);
- }
-
- (void) nsc_free_handle(h);
- return (rc);
-}
-
-
-int
-nsc_read(nsc_buf_t *h, nsc_off_t pos, nsc_size_t len, int flag)
-{
- if ((h->sb_flag & NSC_ABUF) ||
- ((h->sb_flag & NSC_NODATA) && h->sb_vec == NULL))
- return (EIO);
-
- return ((*h->sb_fd->sf_aio->read)(h, pos, len, flag));
-}
-
-
-int
-nsc_write(nsc_buf_t *h, nsc_off_t pos, nsc_size_t len, int flag)
-{
- if ((h->sb_flag & NSC_ABUF) ||
- ((h->sb_flag & NSC_NODATA) && h->sb_vec == NULL))
- return (EIO);
-
- return ((*h->sb_fd->sf_aio->write)(h, pos, len, flag));
-}
-
-
-int
-nsc_zero(nsc_buf_t *h, nsc_off_t pos, nsc_size_t len, int flag)
-{
- if ((h->sb_flag & NSC_ABUF) ||
- ((h->sb_flag & NSC_NODATA) && h->sb_vec == NULL))
- return (EIO);
-
- return ((*h->sb_fd->sf_aio->zero)(h, pos, len, flag));
-}
-
-
-int
-nsc_copy(nsc_buf_t *h1, nsc_buf_t *h2, nsc_off_t pos1,
- nsc_off_t pos2, nsc_size_t len)
-{
- nsc_io_t *io1, *io2;
- int rc = EIO;
-
- if (((h1->sb_flag & NSC_NODATA) && h1->sb_vec == NULL) ||
- ((h2->sb_flag & NSC_NODATA) && h2->sb_vec == NULL))
- return (EIO);
-
- if (h1->sb_fd && h2->sb_fd) {
- io1 = (h1->sb_flag & NSC_ABUF) ?
- (nsc_io_t *)h1->sb_fd : h1->sb_fd->sf_aio;
-
- io2 = (h2->sb_flag & NSC_ABUF) ?
- (nsc_io_t *)h2->sb_fd : h2->sb_fd->sf_aio;
-
- if (io1 == io2)
- rc = (*io1->copy)(h1, h2, pos1, pos2, len);
- }
-
- if (rc != EIO)
- return (rc);
-
- return (_nsc_copy_h(h1, h2, pos1, pos2, len));
-}
-
-
-static int
-_nsc_copy_h(nsc_buf_t *h1, nsc_buf_t *h2, nsc_off_t pos1,
- nsc_off_t pos2, nsc_size_t len)
-{
- nsc_vec_t *v1, *v2;
- uchar_t *a1, *a2;
- int sz, l1, l2, lenbytes; /* byte sizes within an nsc_vec_t */
-
- if (pos1 < h1->sb_pos || pos1 + len > h1->sb_pos + h1->sb_len ||
- pos2 < h2->sb_pos || pos2 + len > h2->sb_pos + h2->sb_len)
- return (EINVAL);
-
- if (!len)
- return (0);
-
- /* find starting point in "from" vector */
-
- v1 = h1->sb_vec;
- pos1 -= h1->sb_pos;
-
- for (; pos1 >= FBA_NUM(v1->sv_len); v1++)
- pos1 -= FBA_NUM(v1->sv_len);
-
- a1 = v1->sv_addr + FBA_SIZE(pos1);
- l1 = v1->sv_len - FBA_SIZE(pos1);
-
- /* find starting point in "to" vector */
-
- v2 = h2->sb_vec;
- pos2 -= h2->sb_pos;
-
- for (; pos2 >= FBA_NUM(v2->sv_len); v2++)
- pos2 -= FBA_NUM(v2->sv_len);
-
- a2 = v2->sv_addr + FBA_SIZE(pos2);
- l2 = v2->sv_len - FBA_SIZE(pos2);
-
- /* copy required data */
-
- ASSERT(FBA_SIZE(len) < INT_MAX);
- lenbytes = (int)FBA_SIZE(len);
-
- while (lenbytes) {
- sz = min(l1, l2);
- sz = min(sz, lenbytes);
-
- bcopy(a1, a2, sz);
-
- l1 -= sz; l2 -= sz;
- a1 += sz; a2 += sz;
- lenbytes -= sz;
-
- if (!l1)
- a1 = (++v1)->sv_addr, l1 = v1->sv_len;
- if (!l2)
- a2 = (++v2)->sv_addr, l2 = v2->sv_len;
- }
-
- return (0);
-}
-
-
-int
-nsc_copy_direct(nsc_buf_t *h1, nsc_buf_t *h2, nsc_off_t pos1,
- nsc_off_t pos2, nsc_size_t len)
-{
- int rc = EIO;
-
- if (!h1 || !h2)
- return (EINVAL);
-
- if (((h1->sb_flag & NSC_NODATA) && h1->sb_vec == NULL) ||
- ((h2->sb_flag & NSC_NODATA) && h2->sb_vec == NULL))
- return (EIO);
-
- if ((h2->sb_flag & NSC_RDWR) != NSC_WRITE) {
- cmn_err(CE_WARN,
- "nsc_copy_direct: h2 (%p) flags (%x) include NSC_READ",
- (void *)h2, h2->sb_flag);
- }
-
- if ((h2->sb_flag & NSC_WRTHRU) == 0) {
- cmn_err(CE_WARN,
- "nsc_copy_direct: h2 (%p) flags (%x) do not "
- "include NSC_WRTHRU", (void *)h2, h2->sb_flag);
- h2->sb_flag |= NSC_WRTHRU;
- }
-
- if (h1->sb_fd && h2->sb_fd && h1->sb_fd->sf_aio == h2->sb_fd->sf_aio)
- rc = (*h1->sb_fd->sf_aio->copy_direct)(h1, h2, pos1, pos2, len);
-
- if (rc != EIO)
- return (rc);
-
- /*
- * The slow way ...
- */
-
- rc = nsc_copy(h1, h2, pos1, pos2, len);
- if (rc <= 0)
- rc = nsc_write(h2, pos2, len, NSC_WRTHRU);
-
- return (rc);
-}
-
-
-int
-nsc_uncommit(nsc_buf_t *h, nsc_off_t pos, nsc_size_t len, int flag)
-{
- if (h->sb_flag & NSC_ABUF)
- return (EIO);
-
- return ((*h->sb_fd->sf_aio->uncommit)(h, pos, len, flag));
-}
-
-
-int
-nsc_free_buf(nsc_buf_t *h)
-{
- nsc_io_t *io;
- int abuf;
- int rc;
-
- if (h == NULL)
- return (0);
-
- if ((h->sb_flag & NSC_NODATA) && (h->sb_vec != NULL)) {
- h->sb_vec = NULL;
- }
-
- abuf = (h->sb_flag & NSC_ABUF);
-
- if (abuf)
- io = (nsc_io_t *)h->sb_fd;
- else
- io = h->sb_fd->sf_aio;
-
- rc = (*io->free_buf)(h);
-
- if (abuf && rc <= 0) {
- mutex_enter(&_nsc_io_lock);
- io->abufcnt--;
- mutex_exit(&_nsc_io_lock);
- }
-
- return (rc);
-}
-
-
-int
-nsc_node_hints(uint_t *hints)
-{
- return (_nsc_call_io(_I(nodehints), (blind_t)hints,
- (blind_t)NSC_GET_NODE_HINT, 0));
-}
-
-int
-nsc_node_hints_set(uint_t hints)
-{
- return (_nsc_call_io(_I(nodehints), (blind_t)(unsigned long)hints,
- (blind_t)NSC_SET_NODE_HINT, 0));
-}
-
-
-int
-nsc_cache_sizes(int *asize, int *wsize)
-{
- return (_nsc_call_io(_I(sizes), (blind_t)asize, (blind_t)wsize, 0));
-}
-
-
-int
-nsc_set_trksize(nsc_fd_t *fd, nsc_size_t trsize)
-{
- return (*fd->sf_aio->trksize)(fd->sf_cd, trsize);
-}
-
-
-int
-nsc_get_pinned(nsc_fd_t *fd)
-{
- return (*fd->sf_aio->getpin)(fd->sf_cd);
-}
-
-
-int
-nsc_discard_pinned(nsc_fd_t *fd, nsc_off_t pos, nsc_size_t len)
-{
- return (*fd->sf_aio->discard)(fd->sf_cd, pos, len);
-}
-
-
-void
-nsc_pinned_data(nsc_iodev_t *iodev, nsc_off_t pos, nsc_size_t len)
-{
- nsc_fd_t *fd;
-
- if (!iodev)
- return;
-
- mutex_enter(&iodev->si_dev->nsc_lock);
- iodev->si_busy++;
- mutex_exit(&iodev->si_dev->nsc_lock);
-
- for (fd = iodev->si_open; fd; fd = fd->sf_next)
- if (fd->sf_avail & _NSC_ATTACH)
- (*fd->sf_pinned)(fd->sf_arg, pos, len);
-
- _nsc_wake_dev(iodev->si_dev, &iodev->si_busy);
-}
-
-
-void
-nsc_unpinned_data(nsc_iodev_t *iodev, nsc_off_t pos, nsc_size_t len)
-{
- nsc_fd_t *fd;
-
- if (!iodev)
- return;
-
- mutex_enter(&iodev->si_dev->nsc_lock);
- iodev->si_busy++;
- mutex_exit(&iodev->si_dev->nsc_lock);
-
- for (fd = iodev->si_open; fd; fd = fd->sf_next)
- if (fd->sf_avail & _NSC_ATTACH)
- (*fd->sf_unpinned)(fd->sf_arg, pos, len);
-
- _nsc_wake_dev(iodev->si_dev, &iodev->si_busy);
-}
diff --git a/usr/src/uts/common/avs/ns/nsctl/nsc_dev.c b/usr/src/uts/common/avs/ns/nsctl/nsc_dev.c
deleted file mode 100644
index ac618e0615..0000000000
--- a/usr/src/uts/common/avs/ns/nsctl/nsc_dev.c
+++ /dev/null
@@ -1,2215 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/debug.h>
-#include <sys/ksynch.h>
-#include <sys/kmem.h>
-#include <sys/cmn_err.h>
-#include <sys/errno.h>
-#include <sys/ddi.h>
-
-#include <sys/ncall/ncall.h>
-
-#define __NSC_GEN__
-#include "nsc_dev.h"
-
-#ifdef DS_DDICT
-#include "../contract.h"
-#endif
-
-#include "../nsctl.h"
-
-#define NSC_DEVMIN "DevMin"
-#define NSC_DEVMAJ "DevMaj"
-
-#define _I(x) (((long)(&((nsc_io_t *)0)->x))/sizeof (long))
-#define _F(x) (((long)(&((nsc_fd_t *)0)->x))/sizeof (long))
-
-
-nsc_def_t _nsc_io_def[] = {
- "Open", (uintptr_t)nsc_null, _I(open),
- "Close", (uintptr_t)nsc_null, _I(close),
- "Attach", (uintptr_t)nsc_null, _I(attach),
- "Detach", (uintptr_t)nsc_null, _I(detach),
- "Flush", (uintptr_t)nsc_null, _I(flush),
- "Provide", 0, _I(provide),
- 0, 0, 0
-};
-
-nsc_def_t _nsc_fd_def[] = {
- "Pinned", (uintptr_t)nsc_null, _F(sf_pinned),
- "Unpinned", (uintptr_t)nsc_null, _F(sf_unpinned),
- "Attach", (uintptr_t)nsc_null, _F(sf_attach),
- "Detach", (uintptr_t)nsc_null, _F(sf_detach),
- "Flush", (uintptr_t)nsc_null, _F(sf_flush),
- 0, 0, 0
-};
-
-kmutex_t _nsc_io_lock;
-kmutex_t _nsc_devval_lock;
-
-nsc_io_t *_nsc_io_top = NULL;
-nsc_io_t *_nsc_null_io = NULL;
-nsc_dev_t *_nsc_dev_top = NULL;
-nsc_dev_t *_nsc_dev_pend = NULL;
-nsc_path_t *_nsc_path_top = NULL;
-nsc_devval_t *_nsc_devval_top = NULL;
-
-extern nsc_def_t _nsc_disk_def[];
-extern nsc_def_t _nsc_cache_def[];
-
-extern nsc_mem_t *_nsc_local_mem;
-extern nsc_rmmap_t *_nsc_global_map;
-
-static clock_t _nsc_io_lbolt;
-
-static nsc_io_t *_nsc_find_io(char *, int, int *);
-nsc_io_t *_nsc_reserve_io(char *, int);
-static nsc_io_t *_nsc_alloc_io(int, char *, int);
-
-static int _nsc_open_fn(nsc_fd_t *, int);
-static int _nsc_close_fn(nsc_fd_t *);
-static int _nsc_alloc_fd(char *, int, int, nsc_fd_t **);
-static int _nsc_alloc_iodev(nsc_dev_t *, int, nsc_iodev_t **);
-static int _nsc_alloc_dev(char *, nsc_dev_t **);
-static int _nsc_reopen_io(char *, int);
-static int _nsc_reopen_dev(nsc_dev_t *, int);
-static int _nsc_relock_dev(nsc_dev_t *, nsc_fd_t *, nsc_iodev_t *);
-static int _nsc_reopen_fd(nsc_fd_t *, int);
-static int _nsc_decode_io(nsc_def_t *, nsc_io_t *);
-
-void _nsc_release_io(nsc_io_t *);
-static void _nsc_free_fd(nsc_fd_t *);
-static void _nsc_free_iodev(nsc_iodev_t *);
-static void _nsc_free_dev(nsc_dev_t *);
-static void _nsc_free_io(nsc_io_t *);
-static void _nsc_relink_fd(nsc_fd_t *, nsc_fd_t **, nsc_fd_t **, nsc_iodev_t *);
-
-static int _nsc_setval(nsc_dev_t *, char *, char *, int, int);
-static void r_nsc_setval(ncall_t *, int *);
-static void r_nsc_setval_all(ncall_t *, int *);
-
-extern void _nsc_add_disk(nsc_io_t *);
-extern void _nsc_add_cache(nsc_io_t *);
-
-
-/*
- * void
- * _nsc_init_dev (void)
- * Initialise device subsystem.
- *
- * Calling/Exit State:
- * Called at driver initialisation time to allocate necessary
- * data structures.
- */
-void
-_nsc_init_dev()
-{
- mutex_init(&_nsc_io_lock, NULL, MUTEX_DRIVER, NULL);
- mutex_init(&_nsc_devval_lock, NULL, MUTEX_DRIVER, NULL);
-
- _nsc_null_io = nsc_register_io("null", NSC_NULL, (nsc_def_t *)0);
-
- if (!_nsc_null_io)
- cmn_err(CE_PANIC, "nsctl: nsc_init_dev");
-
- ncall_register_svc(NSC_SETVAL_ALL, r_nsc_setval_all);
- ncall_register_svc(NSC_SETVAL, r_nsc_setval);
-}
-
-
-void
-_nsc_deinit_dev()
-{
- nsc_devval_t *dv;
- nsc_val_t *vp;
-
- mutex_enter(&_nsc_devval_lock);
-
- while ((dv = _nsc_devval_top) != NULL) {
- while ((vp = dv->dv_values) != NULL) {
- dv->dv_values = vp->sv_next;
- nsc_kmem_free(vp, sizeof (*vp));
- }
-
- _nsc_devval_top = dv->dv_next;
- nsc_kmem_free(dv, sizeof (*dv));
- }
-
- mutex_exit(&_nsc_devval_lock);
-
- ncall_unregister_svc(NSC_SETVAL_ALL);
- ncall_unregister_svc(NSC_SETVAL);
-
- mutex_destroy(&_nsc_devval_lock);
- mutex_destroy(&_nsc_io_lock);
-}
-
-
-/*
- * nsc_io_t *
- * nsc_register_io (char *name, int type, nsc_def_t *def)
- * Register an I/O module.
- *
- * Calling/Exit State:
- * Returns a token for use in future calls to nsc_unregister_io.
- * The ID and flags for the module are specified by 'type' and
- * the appropriate entry points are defined using 'def'. If
- * registration fails NULL is returned.
- *
- * Description:
- * Registers an I/O module for use by subsequent calls to
- * nsc_open.
- */
-nsc_io_t *
-nsc_register_io(name, type, def)
-char *name;
-int type;
-nsc_def_t *def;
-{
- nsc_io_t *io, *tp;
- int rc, id, flag;
- nsc_io_t **iop;
-
- id = (type & NSC_TYPES);
- flag = (type & ~NSC_TYPES);
-
- if ((!(id & NSC_ID) || (id & ~NSC_IDS)) &&
- (id != NSC_NULL || _nsc_null_io))
- return (NULL);
-
- if (!(io = _nsc_alloc_io(id, name, flag)))
- return (NULL);
-
- rc = _nsc_decode_io(def, io);
-
- if (!rc && id != NSC_NULL) {
- _nsc_free_io(io);
- return (NULL);
- }
-
- mutex_enter(&_nsc_io_lock);
-
- for (tp = _nsc_io_top; tp; tp = tp->next) {
- if (strcmp(tp->name, name) == 0 || tp->id == id) {
- mutex_exit(&_nsc_io_lock);
- _nsc_free_io(io);
- return (NULL);
- }
- }
-
- for (iop = &_nsc_io_top; *iop; iop = &(*iop)->next)
- if (id >= (*iop)->id)
- break;
-
- io->next = (*iop);
- (*iop) = io;
-
- _nsc_io_lbolt = nsc_lbolt();
-
- while ((rc = _nsc_reopen_io(NULL, 0)) != 0)
- if (rc != ERESTART)
- break;
-
- mutex_exit(&_nsc_io_lock);
- return (io);
-}
-
-
-/*
- * static int
- * _nsc_decode_io (nsc_def_t *def, nsc_io_t *io)
- * Decode I/O module definition.
- *
- * Calling/Exit State:
- * Returns TRUE if the definition contains an adequate
- * description of an I/O module.
- *
- * Description:
- * Decode the definition of an I/O module and supply
- * translation routines where possible for operations
- * that are not defined.
- */
-static int
-_nsc_decode_io(def, io)
-nsc_def_t *def;
-nsc_io_t *io;
-{
- nsc_decode_param(def, _nsc_io_def, (long *)io);
- nsc_decode_param(def, _nsc_disk_def, (long *)io);
- nsc_decode_param(def, _nsc_cache_def, (long *)io);
-
- _nsc_add_disk(io);
- _nsc_add_cache(io);
-
- return (1);
-}
-
-
-/*
- * int
- * nsc_unregister_io (nsc_io_t *io, int flag)
- * Un-register an I/O module.
- *
- * Calling/Exit State:
- * Returns 0 on success, otherwise returns an error code.
- *
- * Description:
- * The specified I/O module is un-registered if possible.
- * All open file descriptors using the module will be closed
- * in preparation for a subsequent re-open.
- *
- * If NSC_PCATCH is specified and a signal is received,
- * the unregister will be terminated and EINTR returned.
- */
-int
-nsc_unregister_io(nsc_io_t *io, int flag)
-{
- nsc_path_t *sp;
- nsc_io_t *xio;
- int rc = 0;
-
- if (io == _nsc_null_io)
- return (EINVAL);
-
- mutex_enter(&_nsc_io_lock);
-
- for (xio = _nsc_io_top; xio; xio = xio->next)
- if (xio == io)
- break;
-
- if (!xio || io->pend) {
- mutex_exit(&_nsc_io_lock);
- return (xio ? EALREADY : 0);
- }
-
- io->pend = 1;
-lp:
- for (sp = _nsc_path_top; sp; sp = sp->sp_next)
- if (sp->sp_io == io) {
- mutex_exit(&_nsc_io_lock);
-
- if ((rc = nsc_unregister_path(sp, flag)) != 0) {
- io->pend = 0;
- return (rc);
- }
-
- mutex_enter(&_nsc_io_lock);
- goto lp;
- }
-
- _nsc_io_lbolt = nsc_lbolt();
-
- while (io->refcnt && !rc) {
- while ((rc = _nsc_reopen_io(NULL, flag)) != 0)
- if (rc != ERESTART)
- break;
-
- if (rc || !io->refcnt)
- break;
-
- if (!cv_wait_sig(&io->cv, &_nsc_io_lock))
- rc = EINTR;
- }
-
- /*
- * We have tried to get rid of all the IO provider's clients.
- * If there are still anonymous buffers outstanding, then fail
- * the unregister.
- */
-
- if (!rc && io->abufcnt > 0)
- rc = EUSERS;
-
- if (rc)
- io->pend = 0;
-
- mutex_exit(&_nsc_io_lock);
-
- if (!rc)
- _nsc_free_io(io);
-
- return (rc);
-}
-
-
-/*
- * nsc_path_t *
- * nsc_register_path (char *path, int type, nsc_io_t *io)
- * Register interest in pathname.
- *
- * Calling/Exit State:
- * Returns a token for use in future calls to
- * nsc_unregister_path. The 'path' argument can contain
- * wild characters. If registration fails NULL is returned.
- * May not be called for io providers that support NSC_ANON.
- *
- * Description:
- * Registers an interest in any pathnames matching 'path'
- * which are opened with the specified type.
- */
-nsc_path_t *
-nsc_register_path(char *path, int type, nsc_io_t *io)
-{
- nsc_path_t *sp, **spp;
- int rc;
-
- if ((type & NSC_IDS) || !io || (io->provide & NSC_ANON) ||
- !(sp = nsc_kmem_zalloc(sizeof (*sp), KM_SLEEP, _nsc_local_mem)))
- return (NULL);
-
- sp->sp_path = nsc_strdup(path);
- sp->sp_type = type;
- sp->sp_io = io;
-
- mutex_enter(&_nsc_io_lock);
-
- for (spp = &_nsc_path_top; *spp; spp = &(*spp)->sp_next)
- if (io->id >= (*spp)->sp_io->id)
- break;
-
- sp->sp_next = (*spp);
- (*spp) = sp;
-
- _nsc_io_lbolt = nsc_lbolt();
-
- while ((rc = _nsc_reopen_io(path, 0)) != 0)
- if (rc != ERESTART)
- break;
-
- mutex_exit(&_nsc_io_lock);
- return (sp);
-}
-
-
-/*
- * int
- * nsc_unregister_path (nsc_path_t *sp, int flag)
- * Un-register interest in pathname.
- *
- * Calling/Exit State:
- * Returns 0 on success, otherwise returns an error code.
- *
- * Description:
- * Interest in the specified pathname is un-registered
- * if possible. All appropriate file descriptors will be
- * closed in preparation for a subsequent re-open.
- *
- * If NSC_PCATCH is specified and a signal is received,
- * the unregister will be terminated and EINTR returned.
- */
-int
-nsc_unregister_path(sp, flag)
-nsc_path_t *sp;
-int flag;
-{
- nsc_path_t *xsp, **spp;
- int rc;
-
- mutex_enter(&_nsc_io_lock);
-
- for (xsp = _nsc_path_top; xsp; xsp = xsp->sp_next)
- if (xsp == sp)
- break;
-
- if (!xsp || sp->sp_pend) {
- mutex_exit(&_nsc_io_lock);
- return (xsp ? EALREADY : 0);
- }
-
- sp->sp_pend = 1;
- _nsc_io_lbolt = nsc_lbolt();
-
- while ((rc = _nsc_reopen_io(sp->sp_path, flag)) != 0)
- if (rc != ERESTART) {
- sp->sp_pend = 0;
- mutex_exit(&_nsc_io_lock);
- return (rc);
- }
-
- for (spp = &_nsc_path_top; *spp; spp = &(*spp)->sp_next)
- if (*spp == sp)
- break;
-
- if (*spp)
- (*spp) = sp->sp_next;
-
- mutex_exit(&_nsc_io_lock);
-
- nsc_strfree(sp->sp_path);
- nsc_kmem_free(sp, sizeof (*sp));
- return (0);
-}
-
-
-/*
- * static int
- * _nsc_reopen_io (char *path, int flag)
- * Force re-open of all file descriptors.
- *
- * Calling/Exit State:
- * The _nsc_io_lock must be held across calls to
- * this function.
- *
- * Returns 0 if the force succeeds without releasing
- * _nsc_io_lock, otherwise returns an error code.
- *
- * Description:
- * A re-open is forced for all file descriptors as
- * appropriate. For performance reasons available
- * devices are re-opened before those that would block.
- */
-static int
-_nsc_reopen_io(path, flag)
-char *path;
-int flag;
-{
- nsc_dev_t *dp, *dev;
- int rc, errno = 0;
- int try, run;
-
- for (run = 1, try = (NSC_TRY | NSC_DEFER); run--; try = 0) {
- for (dev = _nsc_dev_top; dev; dev = dev->nsc_next) {
- if (path && !nsc_strmatch(dev->nsc_path, path))
- continue;
-
- if (!(rc = _nsc_reopen_dev(dev, flag | try)))
- continue;
-
- for (dp = _nsc_dev_top; dp; dp = dp->nsc_next)
- if (dp == dev)
- break;
-
- if (!dp)
- return (ERESTART);
-
- if (try && !(flag & NSC_TRY))
- run = 1;
- if (!run && errno != ERESTART)
- errno = rc;
- }
- }
-
- return (errno);
-}
-
-
-/*
- * static int
- * _nsc_reopen_dev (nsc_dev_t *dev, int flag)
- * Force re-open of entire device.
- *
- * Calling/Exit State:
- * The _nsc_io_lock must be held across calls to
- * this function.
- *
- * Returns 0 if the force succeeds without releasing
- * _nsc_io_lock, otherwise returns an error code.
- *
- * Description:
- * A re-open is forced for all file descriptors for the
- * device as appropriate.
- */
-static int
-_nsc_reopen_dev(dev, flag)
-nsc_dev_t *dev;
-int flag;
-{
- int rc, errno = 0;
- nsc_iodev_t *iodev;
- int try, run;
- nsc_fd_t *fd;
-
- mutex_enter(&dev->nsc_lock);
-
- for (run = 1, try = (NSC_TRY | NSC_DEFER); run--; try = 0)
- for (iodev = dev->nsc_list; iodev; iodev = iodev->si_next) {
- for (fd = iodev->si_open; fd; fd = fd->sf_next) {
- if (!(rc = _nsc_reopen_fd(fd, flag | try)))
- continue;
-
- if (rc == -ERESTART)
- return (ERESTART);
-
- if (!_nsc_relock_dev(dev, fd, iodev))
- return (ERESTART);
-
- if (try && !(flag & NSC_TRY))
- run = 1;
- if (!run && errno != ERESTART)
- errno = rc;
- }
- }
-
- for (run = 1, try = (NSC_TRY | NSC_DEFER); run--; try = 0)
- for (fd = dev->nsc_close; fd; fd = fd->sf_next) {
- if (!(rc = _nsc_reopen_fd(fd, flag | try)))
- continue;
-
- if (rc == -ERESTART)
- return (ERESTART);
-
- if (!_nsc_relock_dev(dev, fd, NULL))
- return (ERESTART);
-
- if (try && !(flag & NSC_TRY))
- run = 1;
- if (!run && errno != ERESTART)
- errno = rc;
- }
-
- mutex_exit(&dev->nsc_lock);
- return (errno);
-}
-
-
-/*
- * static int
- * _nsc_relock_dev (nsc_dev_t *dev, nsc_fd_t *fd, nsc_iodev_t *iodev)
- * Relock device structure if possible.
- *
- * Calling/Exit State:
- * The _nsc_io_lock must be held across calls to
- * this function.
- *
- * Checks whether the file descriptor is still part
- * of the specified device and I/O device. If so the
- * device lock is taken. Otherwise FALSE is returned.
- */
-static int
-_nsc_relock_dev(nsc_dev_t *dev, nsc_fd_t *fd, nsc_iodev_t *iodev)
-{
- nsc_fd_t *fp = NULL;
- nsc_iodev_t *iop;
- nsc_dev_t *dp;
-
- for (dp = _nsc_dev_top; dp; dp = dp->nsc_next)
- if (dp == dev)
- break;
-
- if (!dp)
- return (0);
-
- mutex_enter(&dev->nsc_lock);
-
- if (iodev)
- for (iop = dev->nsc_list; iop; iop = iop->si_next)
- if (iop == iodev)
- break;
-
- if (!iodev || iop) {
- fp = (iodev) ? iodev->si_open : dev->nsc_close;
-
- for (; fp; fp = fp->sf_next)
- if (fp == fd)
- break;
- }
-
- if (!fp) {
- mutex_exit(&dev->nsc_lock);
- return (0);
- }
-
- return (1);
-}
-
-
-/*
- * static int
- * _nsc_reopen_fd (nsc_fd_t *dev, int flag)
- * Force re-open of file descriptor.
- *
- * Calling/Exit State:
- * Both _nsc_io_lock and the device lock must be held
- * across calls to this function.
- *
- * Returns 0 if the force succeeds without releasing
- * any locks, otherwise returns an error code. If an
- * error code is returned the device lock is released.
- *
- * Description:
- * If appropriate the file descriptor is closed in order
- * to force a subsequent open using the currently available
- * resources.
- */
-static int
-_nsc_reopen_fd(fd, flag)
-nsc_fd_t *fd;
-int flag;
-{
- nsc_dev_t *dev = fd->sf_dev;
- nsc_iodev_t *iodev = fd->sf_iodev;
- int changed = 0;
- int rc;
-
- if (!fd->sf_pend && !iodev)
- return (0);
-
- if (fd->sf_pend == _NSC_OPEN)
- if (fd->sf_lbolt - _nsc_io_lbolt > 0)
- return (0);
-
- if (iodev &&
- (iodev->si_io ==
- _nsc_find_io(dev->nsc_path, fd->sf_type, &changed)) &&
- !changed)
- return (0);
-
- if (iodev)
- fd->sf_reopen = 1;
-
- mutex_exit(&_nsc_io_lock);
-
- dev->nsc_reopen = 1;
-
- rc = _nsc_close_fd(fd, flag);
-
- dev->nsc_reopen = 0;
-
- if (rc == EAGAIN && (flag & NSC_DEFER) && fd->sf_reopen)
- dev->nsc_drop = 1;
-
- mutex_exit(&dev->nsc_lock);
-
- if (rc == -ERESTART)
- delay(2); /* allow other threads cpu time */
-
- mutex_enter(&_nsc_io_lock);
- return (rc ? rc : ERESTART);
-}
-
-
-/*
- * nsc_fd_t *
- * nsc_open (char *path, int type, nsc_def_t *def, blind_t arg, int *sts)
- * Open file descriptor for pathname.
- *
- * Calling/Exit State:
- * Returns file descriptor if open succeeds, otherwise
- * returns 0 and puts error code in the location pointed
- * to by sts.
- *
- * Description:
- * Open the specified pathname using an appropriate access
- * method.
- */
-nsc_fd_t *
-nsc_open(path, type, def, arg, sts)
-char *path;
-int type;
-nsc_def_t *def;
-blind_t arg;
-int *sts;
-{
- int flag, rc;
- nsc_fd_t *fd;
-
- flag = (type & ~NSC_TYPES);
- type &= NSC_TYPES;
-
- if ((flag & NSC_READ) == 0)
- flag |= NSC_RDWR;
-
- if ((rc = _nsc_alloc_fd(path, type, flag, &fd)) != 0) {
- if (sts)
- *sts = rc;
- return (NULL);
- }
-
- fd->sf_arg = arg;
- fd->sf_aio = _nsc_null_io;
-
- nsc_decode_param(def, _nsc_fd_def, (long *)fd);
-
- mutex_enter(&fd->sf_dev->nsc_lock);
-
- while ((rc = _nsc_open_fd(fd, flag)) != 0)
- if (rc != ERESTART)
- break;
-
- mutex_exit(&fd->sf_dev->nsc_lock);
-
- if (rc) {
- _nsc_free_fd(fd);
- if (sts)
- *sts = rc;
- return (NULL);
- }
-
- return (fd);
-}
-
-
-/*
- * int
- * _nsc_open_fd (nsc_fd_t *fd, int flag)
- * Open file descriptor.
- *
- * Calling/Exit State:
- * The device lock must be held across calls to
- * this function.
- *
- * Returns 0 if the open succeeds, otherwise
- * returns an error code.
- *
- * Description:
- * Open the specified file descriptor.
- */
-int
-_nsc_open_fd(fd, flag)
-nsc_fd_t *fd;
-int flag;
-{
- nsc_dev_t *dev = fd->sf_dev;
- int rc;
-
- if (fd->sf_pend)
- return (_nsc_wait_dev(dev, flag));
-
- if (fd->sf_iodev)
- return (0);
- if (flag & NSC_NOBLOCK)
- return (EAGAIN);
-
- fd->sf_pend = _NSC_OPEN;
- fd->sf_lbolt = nsc_lbolt();
-
- mutex_exit(&dev->nsc_lock);
-
- rc = _nsc_open_fn(fd, flag);
-
- mutex_enter(&dev->nsc_lock);
- fd->sf_pend = 0;
-
- if (!rc)
- fd->sf_iodev->si_pend = 0;
-
- if (dev->nsc_wait || dev->nsc_refcnt <= 0)
- cv_broadcast(&dev->nsc_cv);
-
- return (rc ? rc : ERESTART);
-}
-
-
-/*
- * static int
- * _nsc_open_fn (nsc_fd_t *fd, int flag)
- * Allocate I/O device and open file descriptor.
- *
- * Calling/Exit State:
- * No locks may be held across this function.
- *
- * If the open succeeds an I/O device will be
- * attached to the file descriptor, marked as
- * pending and 0 returned. Otherwise, returns
- * an error code.
- *
- * Description:
- * Allocate an I/O device and open the specified
- * file descriptor.
- */
-static int
-_nsc_open_fn(fd, flag)
-nsc_fd_t *fd;
-int flag;
-{
- nsc_dev_t *dev = fd->sf_dev;
- nsc_iodev_t *iodev;
- int rc;
-
- if ((rc = _nsc_alloc_iodev(dev, fd->sf_type, &iodev)) != 0)
- return (rc);
-
- mutex_enter(&dev->nsc_lock);
-
- if (iodev->si_pend) {
- rc = _nsc_wait_dev(dev, flag);
- mutex_exit(&dev->nsc_lock);
- _nsc_free_iodev(iodev);
- return (rc);
- }
-
- iodev->si_pend = _NSC_OPEN;
- mutex_exit(&dev->nsc_lock);
-
- rc = (*iodev->si_io->open)(dev->nsc_path,
- (fd->sf_flag & ~NSC_RDWR), &fd->sf_cd, iodev);
-
- if (rc) {
- iodev->si_pend = 0;
- _nsc_free_iodev(iodev);
- return (rc);
- }
-
- /* save away the DevMaj and DevMin values */
- if (iodev->si_io->id == NSC_RAW_ID) {
- rc = _nsc_setval(dev, NULL, NSC_DEVMAJ,
- (int)getmajor((dev_t)fd->sf_cd), FALSE);
-#ifdef DEBUG
- if (rc != 1) {
- cmn_err(CE_NOTE, "!nsctl: could not set DevMaj (%s:%x)",
- dev->nsc_path, (int)getmajor((dev_t)fd->sf_cd));
- }
-#endif
-
- rc = _nsc_setval(dev, NULL, NSC_DEVMIN,
- (int)getminor((dev_t)fd->sf_cd), FALSE);
-#ifdef DEBUG
- if (rc != 1) {
- cmn_err(CE_NOTE, "!nsctl: could not set DevMin (%s:%x)",
- dev->nsc_path, (int)getminor((dev_t)fd->sf_cd));
- }
-#endif
- }
-
- fd->sf_iodev = iodev;
- _nsc_relink_fd(fd, &dev->nsc_close, &iodev->si_open, iodev);
-
- return (0);
-}
-
-
-/*
- * int
- * nsc_close (nsc_fd_t *fd)
- * Close file descriptor for pathname.
- *
- * Calling/Exit State:
- * Returns 0 if close succeeds, otherwise returns error
- * code.
- *
- * Description:
- * Close the specified file descriptor. It is assumed
- * that all other users of this file descriptor have
- * finished. Any reserve will be discarded before the
- * close is performed.
- */
-int
-nsc_close(fd)
-nsc_fd_t *fd;
-{
- int rc;
-
- if (!fd)
- return (0);
-
- while (fd->sf_reserve)
- nsc_release(fd);
-
- mutex_enter(&fd->sf_dev->nsc_lock);
-
- fd->sf_owner = NULL;
-
- while ((rc = _nsc_close_fd(fd, 0)) != 0)
- if (rc != ERESTART)
- break;
-
- nsc_decode_param(_nsc_fd_def, _nsc_fd_def, (long *)fd);
-
- mutex_exit(&fd->sf_dev->nsc_lock);
-
- if (!rc)
- _nsc_free_fd(fd);
- return (rc);
-}
-
-
-/*
- * int
- * _nsc_close_fd (nsc_fd_t *fd, int flag)
- * Close file descriptor.
- *
- * Calling/Exit State:
- * The device lock must be held across calls to
- * this function.
- *
- * Returns 0 if the close succeeds, otherwise
- * returns an error code.
- *
- * Description:
- * Close the specified file descriptor.
- */
-int
-_nsc_close_fd(fd, flag)
-nsc_fd_t *fd;
-int flag;
-{
- nsc_dev_t *dev = fd->sf_dev;
- nsc_iodev_t *iodev;
- int rc;
-
- if (fd->sf_pend) {
- if (fd->sf_pend == _NSC_CLOSE && dev->nsc_reopen != 0)
- return (-ERESTART);
-
- return (_nsc_wait_dev(dev, flag));
- }
-
- flag |= NSC_RDWR;
- iodev = fd->sf_iodev;
-
- if (!iodev)
- return (0);
-
- if ((rc = _nsc_detach_fd(fd, flag)) != 0)
- return (rc);
-
- if (iodev->si_pend)
- return (_nsc_wait_dev(dev, flag));
-
- if (iodev->si_open == fd && !fd->sf_next) {
- if ((rc = _nsc_detach_iodev(iodev, NULL, flag)) != 0)
- return (rc);
-
- if (dev->nsc_list == iodev && !iodev->si_next)
- if ((rc = _nsc_detach_dev(dev, NULL, flag)) != 0)
- return (rc);
- }
-
- if (flag & NSC_NOBLOCK)
- return (EAGAIN);
-
- fd->sf_pend = _NSC_CLOSE;
- iodev->si_pend = _NSC_CLOSE;
- mutex_exit(&dev->nsc_lock);
-
- rc = _nsc_close_fn(fd);
-
- mutex_enter(&dev->nsc_lock);
- fd->sf_pend = 0;
-
- fd->sf_reopen = 0;
- if (rc)
- iodev->si_pend = 0;
-
- if (dev->nsc_wait || dev->nsc_refcnt <= 0)
- cv_broadcast(&dev->nsc_cv);
-
- return (rc ? rc : ERESTART);
-}
-
-
-/*
- * static int
- * _nsc_close_fn (nsc_fd_t *fd)
- * Close file descriptor and free I/O device.
- *
- * Calling/Exit State:
- * No locks may be held across this function.
- *
- * Returns 0 if the close succeeds, otherwise
- * returns an error code.
- *
- * If the close succeeds the I/O device will be
- * detached from the file descriptor, released
- * and 0 returned. Otherwise, returns an error
- * code.
- *
- * Description:
- * Close the specified file descriptor and free
- * the I/O device.
- */
-static int
-_nsc_close_fn(fd)
-nsc_fd_t *fd;
-{
- nsc_iodev_t *iodev = fd->sf_iodev;
- nsc_dev_t *dev = fd->sf_dev;
- int last, rc;
-
- last = (iodev->si_open == fd && !fd->sf_next);
-
- if (last || (iodev->si_io->flag & NSC_REFCNT))
- if ((rc = (*iodev->si_io->close)(fd->sf_cd)) != 0)
- return (rc);
-
- fd->sf_iodev = NULL;
- _nsc_relink_fd(fd, &iodev->si_open, &dev->nsc_close, iodev);
-
- iodev->si_pend = 0;
- _nsc_free_iodev(iodev);
-
- return (0);
-}
-
-
-/*
- * void
- * nsc_set_owner (nsc_fd_t *fd, nsc_iodev_t *iodev)
- * Set owner associated with file descriptor.
- *
- * Calling/Exit State:
- * Sets the owner field in the file descriptor.
- */
-void
-nsc_set_owner(nsc_fd_t *fd, nsc_iodev_t *iodev)
-{
- if (fd) {
- mutex_enter(&fd->sf_dev->nsc_lock);
- fd->sf_owner = iodev;
- mutex_exit(&fd->sf_dev->nsc_lock);
- }
-}
-
-
-/*
- * char *
- * nsc_pathname (nsc_fd_t *fd)
- * Pathname associated with file descriptor.
- *
- * Calling/Exit State:
- * Returns a pointer to the pathname associated
- * with the given file descriptor.
- */
-char *
-nsc_pathname(fd)
-nsc_fd_t *fd;
-{
- return ((fd) ? (fd->sf_dev->nsc_path) : 0);
-}
-
-
-/*
- * int
- * nsc_fdpathcmp(nsc_fd_t *fd, uint64_t phash, char *path)
- * Compare fd to pathname and hash
- *
- * Calling/Exit State:
- * Returns comparison value like strcmp(3C).
- *
- * Description:
- * Does an optimised comparison of the pathname and associated hash
- * value (as returned from nsc_strhash()) against the pathname of
- * the filedescriptor, fd.
- */
-int
-nsc_fdpathcmp(nsc_fd_t *fd, uint64_t phash, char *path)
-{
- int rc = -1;
-
- if (fd != NULL && fd->sf_dev->nsc_phash == phash)
- rc = strcmp(fd->sf_dev->nsc_path, path);
-
- return (rc);
-}
-
-
-static int
-_nsc_setval(nsc_dev_t *dev, char *path, char *name, int val, int do_ncall)
-{
- nsc_devval_t *dv;
- nsc_rval_t *rval;
- ncall_t *ncall;
- nsc_val_t *vp;
- uint64_t phash;
- char *pp;
- int rc;
-
- ASSERT(dev != NULL || path != NULL);
-#ifdef DEBUG
- if (dev != NULL && path != NULL) {
- ASSERT(strcmp(dev->nsc_path, path) == 0);
- }
-#endif
-
- pp = (dev != NULL) ? dev->nsc_path : path;
-
- if (strlen(name) >= NSC_SETVAL_MAX) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!nsc_setval: max name size(%d) exceeded(%d)",
- NSC_SETVAL_MAX-1, (int)strlen(name));
-#endif
- return (0);
- }
-
- phash = nsc_strhash(pp);
-
- mutex_enter(&_nsc_devval_lock);
-
- if (dev != NULL)
- dv = dev->nsc_values;
- else {
- for (dv = _nsc_devval_top; dv != NULL; dv = dv->dv_next) {
- if (phash == dv->dv_phash &&
- strcmp(pp, dv->dv_path) == 0)
- /* found dv for device */
- break;
- }
- }
-
- if (dv == NULL) {
- dv = nsc_kmem_zalloc(sizeof (*dv), KM_SLEEP, _nsc_local_mem);
- if (dv == NULL) {
- mutex_exit(&_nsc_devval_lock);
- return (0);
- }
-
- (void) strncpy(dv->dv_path, pp, sizeof (dv->dv_path));
- dv->dv_phash = phash;
-
- dv->dv_next = _nsc_devval_top;
- _nsc_devval_top = dv;
- if (dev != NULL)
- dev->nsc_values = dv;
- }
-
- for (vp = dv->dv_values; vp; vp = vp->sv_next) {
- if (strcmp(vp->sv_name, name) == 0) {
- vp->sv_value = val;
- break;
- }
- }
-
- if (vp == NULL) {
- vp = nsc_kmem_zalloc(sizeof (*vp), KM_SLEEP, _nsc_local_mem);
- if (vp != NULL) {
- (void) strncpy(vp->sv_name, name, sizeof (vp->sv_name));
- vp->sv_value = val;
- vp->sv_next = dv->dv_values;
- dv->dv_values = vp;
- }
- }
-
- mutex_exit(&_nsc_devval_lock);
-
- /*
- * phoenix: ncall the new value to the other node now.
- */
-
- if (vp && do_ncall) {
- /* CONSTCOND */
- ASSERT(sizeof (nsc_rval_t) <= NCALL_DATA_SZ);
-
- rval = nsc_kmem_zalloc(sizeof (*rval), KM_SLEEP,
- _nsc_local_mem);
- if (rval == NULL) {
- goto out;
- }
-
- rc = ncall_alloc(ncall_mirror(ncall_self()), 0, 0, &ncall);
- if (rc == 0) {
- (void) strncpy(rval->path, pp, sizeof (rval->path));
- (void) strncpy(rval->name, name, sizeof (rval->name));
- rval->value = val;
-
- rc = ncall_put_data(ncall, rval, sizeof (*rval));
- if (rc == 0) {
- /*
- * Send synchronously and read a reply
- * so that we know that the remote
- * setval has completed before this
- * function returns and hence whilst
- * the device is still reserved on this
- * node.
- */
- if (ncall_send(ncall, 0, NSC_SETVAL) == 0)
- (void) ncall_read_reply(ncall, 1, &rc);
- }
-
- ncall_free(ncall);
- }
-
- nsc_kmem_free(rval, sizeof (*rval));
- }
-
-out:
- return (vp ? 1 : 0);
-}
-
-
-/* ARGSUSED */
-
-static void
-r_nsc_setval(ncall_t *ncall, int *ap)
-{
- nsc_rval_t *rval;
- int rc;
-
- rval = nsc_kmem_zalloc(sizeof (*rval), KM_SLEEP, _nsc_local_mem);
- if (rval == NULL) {
- ncall_reply(ncall, ENOMEM);
- return;
- }
-
- rc = ncall_get_data(ncall, rval, sizeof (*rval));
- if (rc != 0) {
- ncall_reply(ncall, EFAULT);
- return;
- }
-
- if (_nsc_setval(NULL, rval->path, rval->name, rval->value, FALSE))
- rc = 0;
- else
- rc = ENOMEM;
-
- ncall_reply(ncall, rc);
- nsc_kmem_free(rval, sizeof (*rval));
-}
-
-
-/* ARGSUSED */
-
-static void
-r_nsc_setval_all(ncall_t *ncall, int *ap)
-{
- nsc_rval_t *in = NULL, *out = NULL;
- nsc_devval_t *dv;
- nsc_val_t *vp;
- ncall_t *np;
- uint64_t phash;
- int rc;
-
- /* CONSTCOND */
- ASSERT(sizeof (nsc_rval_t) <= NCALL_DATA_SZ);
-
- in = nsc_kmem_zalloc(sizeof (*in), KM_SLEEP, _nsc_local_mem);
- out = nsc_kmem_zalloc(sizeof (*out), KM_SLEEP, _nsc_local_mem);
- if (in == NULL || out == NULL) {
- if (in != NULL) {
- nsc_kmem_free(in, sizeof (*in));
- in = NULL;
- }
- if (out != NULL) {
- nsc_kmem_free(out, sizeof (*out));
- out = NULL;
- }
- ncall_reply(ncall, ENOMEM);
- }
-
- rc = ncall_get_data(ncall, in, sizeof (*in));
- if (rc != 0) {
- ncall_reply(ncall, EFAULT);
- return;
- }
-
- phash = nsc_strhash(in->path);
-
- (void) strncpy(out->path, in->path, sizeof (out->path));
-
- rc = ncall_alloc(ncall_mirror(ncall_self()), 0, 0, &np);
- if (rc != 0) {
- ncall_reply(ncall, ENOMEM);
- return;
- }
-
- mutex_enter(&_nsc_devval_lock);
-
- for (dv = _nsc_devval_top; dv; dv = dv->dv_next) {
- if (dv->dv_phash == phash &&
- strcmp(dv->dv_path, in->path) == 0)
- break;
- }
-
- if (dv) {
- for (vp = dv->dv_values; vp; vp = vp->sv_next) {
- if (strcmp(vp->sv_name, NSC_DEVMIN) == 0 ||
- strcmp(vp->sv_name, NSC_DEVMAJ) == 0) {
- /* ignore the implicit DevMin/DevMaj values */
- continue;
- }
-
- (void) strncpy(out->name, vp->sv_name,
- sizeof (out->name));
- out->value = vp->sv_value;
-
- rc = ncall_put_data(np, out, sizeof (*out));
- if (rc == 0) {
- /*
- * Send synchronously and read a reply
- * so that we know that the remote
- * setval has completed before this
- * function returns.
- */
- if (ncall_send(np, 0, NSC_SETVAL) == 0)
- (void) ncall_read_reply(np, 1, &rc);
- }
-
- ncall_reset(np);
- }
-
- ncall_free(np);
- rc = 0;
- } else {
- rc = ENODEV;
- }
-
- mutex_exit(&_nsc_devval_lock);
-
- ncall_reply(ncall, rc);
-
- nsc_kmem_free(out, sizeof (*out));
- nsc_kmem_free(in, sizeof (*in));
-}
-
-
-/*
- * int
- * nsc_setval (nsc_fd_t *fd, char *name, int val)
- * Set value for device.
- *
- * Calling/Exit State:
- * Returns 1 if the value has been set, otherwise 0.
- * Must be called with the fd reserved.
- *
- * Description:
- * Sets the specified global variable for the device
- * to the value provided.
- */
-int
-nsc_setval(nsc_fd_t *fd, char *name, int val)
-{
- if (!fd)
- return (0);
-
- if (!nsc_held(fd))
- return (0);
-
- return (_nsc_setval(fd->sf_dev, NULL, name, val, TRUE));
-}
-
-
-/*
- * int
- * nsc_getval (nsc_fd_t *fd, char *name, int *vp)
- * Get value from device.
- *
- * Calling/Exit State:
- * Returns 1 if the value has been found, otherwise 0.
- * Must be called with the fd reserved, except for "DevMaj" / "DevMin".
- *
- * Description:
- * Finds the value of the specified device variable for
- * the device and returns it in the location pointed to
- * by vp.
- */
-int
-nsc_getval(nsc_fd_t *fd, char *name, int *vp)
-{
- nsc_devval_t *dv;
- nsc_val_t *val;
-
- if (!fd)
- return (0);
-
- /*
- * Don't check for nsc_held() for the device number values
- * since these are magically created and cannot change when
- * the fd is not reserved.
- */
-
- if (strcmp(name, NSC_DEVMAJ) != 0 &&
- strcmp(name, NSC_DEVMIN) != 0 &&
- !nsc_held(fd))
- return (0);
-
- mutex_enter(&_nsc_devval_lock);
-
- dv = fd->sf_dev->nsc_values;
- val = NULL;
-
- if (dv != NULL) {
- for (val = dv->dv_values; val; val = val->sv_next) {
- if (strcmp(val->sv_name, name) == 0) {
- *vp = val->sv_value;
- break;
- }
- }
- }
-
- mutex_exit(&_nsc_devval_lock);
-
- return (val ? 1 : 0);
-}
-
-
-/*
- * char *
- * nsc_shared (nsc_fd_t *fd)
- * Device is currently shared.
- *
- * Calling/Exit State:
- * The device lock must be held across calls to this
- * this function.
- *
- * Returns an indication of whether the device accessed
- * by the file descriptor is currently referenced by more
- * than one user.
- *
- * This is only intended for use in performance critical
- * situations.
- */
-int
-nsc_shared(fd)
-nsc_fd_t *fd;
-{
- nsc_iodev_t *iodev;
- int cnt = 0;
-
- if (!fd)
- return (0);
- if (!fd->sf_iodev)
- return (1);
-
- for (iodev = fd->sf_dev->nsc_list; iodev; iodev = iodev->si_next)
- for (fd = iodev->si_open; fd; fd = fd->sf_next)
- if (!fd->sf_owner && cnt++)
- return (1);
-
- return (0);
-}
-
-
-/*
- * kmutex_t *
- * nsc_lock_addr (nsc_fd_t *fd)
- * Address of device lock.
- *
- * Calling/Exit State:
- * Returns a pointer to the spin lock associated with the
- * device.
- *
- * Description:
- * This is only intended for use in performance critical
- * situations in conjunction with nsc_reserve_lk.
- */
-kmutex_t *
-nsc_lock_addr(fd)
-nsc_fd_t *fd;
-{
- return (&fd->sf_dev->nsc_lock);
-}
-
-
-/*
- * int
- * _nsc_call_io (long f, blind_t a, blind_t b, blind_t c)
- * Call information function.
- *
- * Calling/Exit State:
- * Returns result from function or 0 if not available.
- * f represents the offset into the I/O structure at which
- * the required function can be found and a, b, c are the
- * desired arguments.
- *
- * Description:
- * Calls the requested function for the first available
- * cache interface.
- */
-int
-_nsc_call_io(long f, blind_t a, blind_t b, blind_t c)
-{
- nsc_io_t *io;
- int (*fn)();
- int rc;
-
- io = _nsc_reserve_io(NULL, NSC_SDBC_ID);
- if (!io)
- io = _nsc_reserve_io(NULL, NSC_NULL);
-
- fn = (blindfn_t)(((long *)io)[f]);
- rc = (*fn)(a, b, c);
-
- _nsc_release_io(io);
- return (rc);
-}
-
-
-/*
- * nsc_io_t *
- * _nsc_reserve_io (char *, int type)
- * Reserve I/O module.
- *
- * Calling/Exit State:
- * Returns address of I/O structure matching specified
- * type, or NULL.
- *
- * Description:
- * Searches for an appropriate I/O module and increments
- * the reference count to prevent it being unregistered.
- */
-nsc_io_t *
-_nsc_reserve_io(path, type)
-char *path;
-int type;
-{
- nsc_io_t *io;
-
- mutex_enter(&_nsc_io_lock);
-
- if ((io = _nsc_find_io(path, type, NULL)) != 0)
- io->refcnt++;
-
- mutex_exit(&_nsc_io_lock);
- return (io);
-}
-
-
-/*
- * static nsc_io_t *
- * _nsc_find_io (char *path, int type, int *changed)
- * Find I/O module.
- *
- * Calling/Exit State:
- * The _nsc_io_lock must be held across calls to
- * this function.
- *
- * Returns address of I/O structure matching specified
- * type, or NULL.
- *
- * 'changed' will be set to non-zero if there is a pending
- * nsc_path_t that matches the criteria for the requested type.
- * This allows nsctl to distinguish between multiple
- * nsc_register_path's done by the same I/O provider.
- *
- * Description:
- * Searches for an appropriate I/O module.
- *
- * 1. If <type> is a single module id find the specified I/O
- * module by module id.
- *
- * 2. Find the highest module that provides any of the I/O types
- * included in <type>, taking into account any modules
- * registered via the nsc_register_path() interface if <path>
- * is non-NULL.
- *
- * 3. Find an I/O module following the rules in (2), but whose
- * module id is less than the id OR'd into <type>.
- *
- * If no module is found by the above algorithms and NSC_NULL was
- * included in <type>, return the _nsc_null_io module. Otherwise
- * return NULL.
- */
-static nsc_io_t *
-_nsc_find_io(char *path, int type, int *changed)
-{
- nsc_path_t *sp = NULL;
- nsc_path_t *pp = NULL;
- nsc_io_t *io;
-
- type &= NSC_TYPES;
-
- if (path) {
- for (sp = _nsc_path_top; sp; sp = sp->sp_next) {
- if ((type & NSC_ID) &&
- sp->sp_io->id >= (type & NSC_IDS))
- continue;
-
- if (sp->sp_pend || (type & sp->sp_type) == 0)
- continue;
-
- if (nsc_strmatch(path, sp->sp_path))
- break;
- }
-
- if (sp) {
- /* look for matching pending paths */
- for (pp = _nsc_path_top; pp; pp = pp->sp_next) {
- if (pp->sp_pend &&
- (type & pp->sp_type) &&
- nsc_strmatch(path, pp->sp_path)) {
- break;
- }
- }
- }
- }
-
- for (io = _nsc_io_top; io; io = io->next) {
- if (io->pend)
- continue;
-
- if (type & NSC_ID) {
- if ((type & ~NSC_IDS) == 0) {
- if (io->id == type)
- break;
- continue;
- }
-
- if (io->id >= (type & NSC_IDS))
- continue;
- }
-
- if (io->provide & type)
- break;
- }
-
- if (pp && (!io || pp->sp_io->id >= io->id)) {
- /*
- * Mark this as a path change.
- */
- if (changed) {
- *changed = 1;
- }
- }
-
- if (sp && (!io || sp->sp_io->id >= io->id))
- io = sp->sp_io;
-
- if (!io && !(type & NSC_NULL))
- return (NULL);
-
- if (!io)
- io = _nsc_null_io;
-
- return (io);
-}
-
-
-/*
- * void
- * _nsc_release_io (nsc_io_t *)
- * Release I/O module.
- *
- * Description:
- * Releases reference to I/O structure and wakes up
- * anybody waiting on it.
- */
-void
-_nsc_release_io(io)
-nsc_io_t *io;
-{
- mutex_enter(&_nsc_io_lock);
-
- io->refcnt--;
- cv_broadcast(&io->cv);
-
- mutex_exit(&_nsc_io_lock);
-}
-
-
-/*
- * static int
- * _nsc_alloc_fd (char *path, int type, int flag, nsc_fd_t **fdp)
- * Allocate file descriptor structure.
- *
- * Calling/Exit State:
- * Stores address of file descriptor through fdp and
- * returns 0 on success, otherwise returns error code.
- *
- * Description:
- * A new file descriptor is allocated and linked in to
- * the file descriptor chain which is protected by the
- * device lock.
- *
- * On return the file descriptor must contain all the
- * information necessary to perform an open. Details
- * specific to user callbacks are not required yet.
- */
-static int
-_nsc_alloc_fd(path, type, flag, fdp)
-char *path;
-int type, flag;
-nsc_fd_t **fdp;
-{
- nsc_dev_t *dev;
- nsc_fd_t *fd;
- int rc;
-
- if (!(fd = (nsc_fd_t *)nsc_kmem_zalloc(
- sizeof (*fd), KM_SLEEP, _nsc_local_mem)))
- return (ENOMEM);
-
- if ((rc = _nsc_alloc_dev(path, &dev)) != 0) {
- nsc_kmem_free(fd, sizeof (*fd));
- return (rc);
- }
-
- mutex_enter(&dev->nsc_lock);
-
- fd->sf_type = type;
- fd->sf_flag = flag;
- fd->sf_dev = dev;
- fd->sf_next = dev->nsc_close;
- dev->nsc_close = fd;
-
- mutex_exit(&dev->nsc_lock);
-
- *fdp = fd;
- return (0);
-}
-
-
-/*
- * static int
- * _nsc_free_fd (nsc_fd_t *)
- * Free file descriptor.
- *
- * Description:
- * The file descriptor is removed from the chain and free'd
- * once pending activity has completed.
- */
-static void
-_nsc_free_fd(fd)
-nsc_fd_t *fd;
-{
- nsc_dev_t *dev = fd->sf_dev;
- nsc_fd_t **fdp;
-
- if (!fd)
- return;
-
- mutex_enter(&dev->nsc_lock);
-
- for (fdp = &dev->nsc_close; *fdp; fdp = &(*fdp)->sf_next)
- if (*fdp == fd) {
- *fdp = fd->sf_next;
- break;
- }
-
- if (dev->nsc_wait || dev->nsc_refcnt <= 0)
- cv_broadcast(&dev->nsc_cv);
-
- while (fd->sf_pend)
- (void) _nsc_wait_dev(dev, 0);
-
- mutex_exit(&dev->nsc_lock);
-
- _nsc_free_dev(dev);
-
- nsc_kmem_free(fd, sizeof (*fd));
-}
-
-
-/*
- * static void
- * _nsc_relink_fd (nsc_fd_t *fd, nsc_fd_t **from,
- * nsc_fd_t **to, nsc_iodev_t *iodev)
- * Relink file descriptor.
- *
- * Description:
- * Remove the file descriptor from the 'from' chain and
- * add it to the 'to' chain. The busy flag in iodev is
- * used to prevent modifications to the chain whilst a
- * callback is in progress.
- */
-static void
-_nsc_relink_fd(nsc_fd_t *fd, nsc_fd_t **from, nsc_fd_t **to, nsc_iodev_t *iodev)
-{
- nsc_dev_t *dev = fd->sf_dev;
- nsc_fd_t **fdp;
-
- mutex_enter(&dev->nsc_lock);
-
- while (iodev->si_busy)
- (void) _nsc_wait_dev(dev, 0);
-
- for (fdp = from; *fdp; fdp = &(*fdp)->sf_next)
- if (*fdp == fd) {
- *fdp = fd->sf_next;
- break;
- }
-
- fd->sf_next = (*to);
- (*to) = fd;
-
- mutex_exit(&dev->nsc_lock);
-}
-
-
-/*
- * static int
- * _nsc_alloc_iodev (nsc_dev_t *dev, int type, nsc_iodev_t **iodevp)
- * Allocate I/O device structure.
- *
- * Calling/Exit State:
- * Stores address of I/O device structure through iodevp
- * and returns 0 on success, otherwise returns error code.
- *
- * Description:
- * If an entry for the I/O device already exists increment
- * the reference count and return the address, otherwise
- * allocate a new structure.
- *
- * A new structure is allocated before scanning the chain
- * to avoid calling the memory allocator with a spin lock
- * held. If an entry is found the new structure is free'd.
- *
- * The I/O device chain is protected by the device lock.
- */
-static int
-_nsc_alloc_iodev(dev, type, iodevp)
-nsc_dev_t *dev;
-int type;
-nsc_iodev_t **iodevp;
-{
- nsc_iodev_t *iodev, *ip;
- nsc_io_t *io;
-
- if (!(iodev = (nsc_iodev_t *)nsc_kmem_zalloc(
- sizeof (*iodev), KM_SLEEP, _nsc_local_mem)))
- return (ENOMEM);
-
- mutex_init(&iodev->si_lock, NULL, MUTEX_DRIVER, NULL);
- cv_init(&iodev->si_cv, NULL, CV_DRIVER, NULL);
-
- if (!(io = _nsc_reserve_io(dev->nsc_path, type))) {
- mutex_destroy(&iodev->si_lock);
- cv_destroy(&iodev->si_cv);
- nsc_kmem_free(iodev, sizeof (*iodev));
- return (ENXIO);
- }
-
- iodev->si_refcnt++;
- iodev->si_io = io;
- iodev->si_dev = dev;
-
- mutex_enter(&_nsc_io_lock);
- dev->nsc_refcnt++;
- mutex_exit(&_nsc_io_lock);
-
- mutex_enter(&dev->nsc_lock);
-
- for (ip = dev->nsc_list; ip; ip = ip->si_next)
- if (ip->si_io == io) {
- ip->si_refcnt++;
- break;
- }
-
- if (!ip) {
- iodev->si_next = dev->nsc_list;
- dev->nsc_list = iodev;
- }
-
- mutex_exit(&dev->nsc_lock);
-
- if (ip) {
- _nsc_free_iodev(iodev);
- iodev = ip;
- }
-
- *iodevp = iodev;
- return (0);
-}
-
-
-/*
- * static int
- * _nsc_free_iodev (nsc_iodev_t *iodev)
- * Free I/O device structure.
- *
- * Description:
- * Decrements the reference count of a previously allocated
- * I/O device structure. If this is the last reference it
- * is removed from the device chain and free'd once pending
- * activity has completed.
- */
-static void
-_nsc_free_iodev(nsc_iodev_t *iodev)
-{
- nsc_iodev_t **ipp;
- nsc_dev_t *dev;
-
- if (!iodev)
- return;
-
- dev = iodev->si_dev;
-
- mutex_enter(&dev->nsc_lock);
-
- if (--iodev->si_refcnt > 0) {
- mutex_exit(&dev->nsc_lock);
- return;
- }
-
- for (ipp = &dev->nsc_list; *ipp; ipp = &(*ipp)->si_next)
- if (*ipp == iodev) {
- *ipp = iodev->si_next;
- break;
- }
-
- if (dev->nsc_wait || dev->nsc_refcnt <= 0)
- cv_broadcast(&dev->nsc_cv);
-
- while (iodev->si_pend || iodev->si_rpend || iodev->si_busy)
- (void) _nsc_wait_dev(dev, 0);
-
- mutex_exit(&dev->nsc_lock);
-
- _nsc_release_io(iodev->si_io);
- _nsc_free_dev(dev);
-
- mutex_destroy(&iodev->si_lock);
- cv_destroy(&iodev->si_cv);
-
- nsc_kmem_free(iodev, sizeof (*iodev));
-}
-
-
-/*
- * static int
- * _nsc_alloc_dev (char *path, nsc_dev_t **devp)
- * Allocate device structure.
- *
- * Calling/Exit State:
- * Stores address of device structure through devp
- * and returns 0 on success, otherwise returns error
- * code.
- *
- * Description:
- * If an entry for the device already exists increment
- * the reference count and return the address, otherwise
- * allocate a new structure.
- *
- * A new structure is allocated before scanning the device
- * chain to avoid calling the memory allocator with a spin
- * lock held. If the device is found the new structure is
- * free'd.
- *
- * The device chain is protected by _nsc_io_lock.
- */
-static int
-_nsc_alloc_dev(char *path, nsc_dev_t **devp)
-{
- nsc_dev_t *dev, *dp, **ddp;
- nsc_devval_t *dv;
- nsc_rval_t *rval;
- ncall_t *ncall;
- int rc;
-
- if (!(dev = (nsc_dev_t *)nsc_kmem_zalloc(
- sizeof (*dev), KM_SLEEP, _nsc_local_mem)))
- return (ENOMEM);
-
- dev->nsc_refcnt++;
-
- mutex_init(&dev->nsc_lock, NULL, MUTEX_DRIVER, NULL);
- cv_init(&dev->nsc_cv, NULL, CV_DRIVER, NULL);
-
- dev->nsc_phash = nsc_strhash(path);
- dev->nsc_path = nsc_strdup(path);
-
- mutex_enter(&_nsc_io_lock);
-
- dev->nsc_next = _nsc_dev_pend;
- _nsc_dev_pend = dev;
-
- mutex_exit(&_nsc_io_lock);
-
- mutex_enter(&_nsc_io_lock);
-
- for (dp = _nsc_dev_top; dp; dp = dp->nsc_next)
- if (dp->nsc_phash == dev->nsc_phash &&
- strcmp(dp->nsc_path, dev->nsc_path) == 0) {
- dp->nsc_refcnt++;
- break;
- }
-
- if (!dp) {
- for (ddp = &_nsc_dev_pend; *ddp; ddp = &(*ddp)->nsc_next)
- if (*ddp == dev) {
- *ddp = dev->nsc_next;
- break;
- }
-
- dev->nsc_next = _nsc_dev_top;
- _nsc_dev_top = dev;
- }
-
- mutex_exit(&_nsc_io_lock);
-
- if (dp) {
- _nsc_free_dev(dev);
- dev = dp;
- }
-
- /*
- * Try and find the device/values header for this device
- * and link it back to the device structure.
- */
-
- mutex_enter(&_nsc_devval_lock);
-
- if (dev->nsc_values == NULL) {
- for (dv = _nsc_devval_top; dv; dv = dv->dv_next) {
- if (dv->dv_phash == dev->nsc_phash &&
- strcmp(dv->dv_path, dev->nsc_path) == 0) {
- dev->nsc_values = dv;
- break;
- }
- }
- }
-
- mutex_exit(&_nsc_devval_lock);
-
- /*
- * Refresh the device/values from the other node
- */
-
- rval = nsc_kmem_zalloc(sizeof (*rval), KM_SLEEP, _nsc_local_mem);
- if (rval == NULL) {
- goto out;
- }
-
- rc = ncall_alloc(ncall_mirror(ncall_self()), 0, 0, &ncall);
- if (rc == 0) {
- (void) strncpy(rval->path, path, sizeof (rval->path));
-
- rc = ncall_put_data(ncall, rval, sizeof (*rval));
- if (rc == 0) {
- /*
- * Send synchronously and read a reply
- * so that we know that the updates
- * have completed before this
- * function returns.
- */
- if (ncall_send(ncall, 0, NSC_SETVAL_ALL) == 0)
- (void) ncall_read_reply(ncall, 1, &rc);
- }
-
- ncall_free(ncall);
- }
-
- nsc_kmem_free(rval, sizeof (*rval));
-
-out:
- *devp = dev;
- return (0);
-}
-
-
-/*
- * static void
- * _nsc_free_dev (nsc_dev_t *dev)
- * Free device structure.
- *
- * Description:
- * Decrements the reference count of a previously allocated
- * device structure. If this is the last reference it is
- * removed from the device chain and free'd once pending
- * activity has completed.
- *
- * Whilst waiting for pending activity to cease the device is
- * relinked onto the pending chain.
- */
-static void
-_nsc_free_dev(dev)
-nsc_dev_t *dev;
-{
- nsc_dev_t **ddp;
-
- if (!dev)
- return;
-
- mutex_enter(&_nsc_io_lock);
-
- if (--dev->nsc_refcnt > 0) {
- mutex_exit(&_nsc_io_lock);
- return;
- }
-
- for (ddp = &_nsc_dev_top; *ddp; ddp = &(*ddp)->nsc_next)
- if (*ddp == dev) {
- *ddp = dev->nsc_next;
- dev->nsc_next = _nsc_dev_pend;
- _nsc_dev_pend = dev;
- break;
- }
-
- mutex_exit(&_nsc_io_lock);
-
- mutex_enter(&dev->nsc_lock);
-
- while (dev->nsc_pend || dev->nsc_rpend || dev->nsc_wait) {
- cv_wait(&dev->nsc_cv, &dev->nsc_lock);
- }
-
- mutex_exit(&dev->nsc_lock);
-
- mutex_enter(&_nsc_io_lock);
-
- for (ddp = &_nsc_dev_pend; *ddp; ddp = &(*ddp)->nsc_next)
- if (*ddp == dev) {
- *ddp = dev->nsc_next;
- break;
- }
-
- mutex_exit(&_nsc_io_lock);
-
- mutex_destroy(&dev->nsc_lock);
- cv_destroy(&dev->nsc_cv);
- nsc_strfree(dev->nsc_path);
-
- nsc_kmem_free(dev, sizeof (*dev));
-}
-
-
-/*
- * static nsc_io_t *
- * _nsc_alloc_io (int id, char *name, int flag)
- * Allocate an I/O structure.
- *
- * Calling/Exit State:
- * Returns the address of the I/O structure, or NULL.
- */
-static nsc_io_t *
-_nsc_alloc_io(id, name, flag)
-int id;
-char *name;
-int flag;
-{
- nsc_io_t *io;
-
- if (!(io = (nsc_io_t *)nsc_kmem_zalloc(
- sizeof (*io), KM_NOSLEEP, _nsc_local_mem)))
- return (NULL);
-
- cv_init(&io->cv, NULL, CV_DRIVER, NULL);
-
- io->id = id;
- io->name = name;
- io->flag = flag;
-
- return (io);
-}
-
-
-/*
- * static void
- * _nsc_free_io (int id, char *name, int flag)
- * Free an I/O structure.
- *
- * Calling/Exit State:
- * Free the I/O structure and remove it from the chain.
- */
-static void
-_nsc_free_io(io)
-nsc_io_t *io;
-{
- nsc_io_t **iop;
-
- mutex_enter(&_nsc_io_lock);
-
- for (iop = &_nsc_io_top; *iop; iop = &(*iop)->next)
- if (*iop == io)
- break;
-
- if (*iop)
- (*iop) = io->next;
-
- mutex_exit(&_nsc_io_lock);
-
- cv_destroy(&io->cv);
- nsc_kmem_free(io, sizeof (*io));
-}
diff --git a/usr/src/uts/common/avs/ns/nsctl/nsc_dev.h b/usr/src/uts/common/avs/ns/nsctl/nsc_dev.h
deleted file mode 100644
index 5aee2e66a6..0000000000
--- a/usr/src/uts/common/avs/ns/nsctl/nsc_dev.h
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _NSC_DEV_H
-#define _NSC_DEV_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef __NSC_GEN__
-Error: Illegal #include - private file.
-#endif
-
-
-#include <sys/nsctl/nsc_gen.h>
-#include <sys/nsc_ddi.h>
-
-/*
- * Interface to I/O module.
- */
-
-typedef struct nsc_io_s {
- struct nsc_io_s *next; /* Link to next I/O module */
- kcondvar_t cv; /* Blocking variable */
- int id; /* Module id */
- int flag; /* Flags */
- char *name; /* Module name */
- int refcnt; /* Reference count */
- int abufcnt; /* # of allocated anonymous buffers */
- int pend; /* Unregister pending */
- int (*open)(); /* Open device */
- int (*close)(); /* Close device */
- int (*attach)(); /* Attach device */
- int (*detach)(); /* Detach device */
- int (*flush)(); /* Flush device */
- int (*alloc_buf)(); /* Allocate buffer */
- int (*free_buf)(); /* Free buffer */
- int (*read)(); /* Read buffer */
- int (*write)(); /* Write buffer */
- int (*zero)(); /* Zero buffer */
- int (*copy)(); /* Copy buffer between handles */
- int (*copy_direct)(); /* Copy buffer between handle & disk */
- int (*uncommit)(); /* Uncommit buffer */
- struct nsc_buf_s *(*alloc_h)(); /* Allocate handle */
- int (*free_h)(); /* Free handle */
- int (*uread)(); /* User read */
- int (*uwrite)(); /* User write */
- int (*trksize)(); /* Set track size */
- int (*discard)(); /* Discard pinned data */
- int (*sizes)(); /* Return size of cache */
- int (*getpin)(); /* Get pinned info */
- int (*nodehints)(); /* Return current node hints */
- int (*partsize)(); /* Partition size */
- int (*maxfbas)(); /* Maximum I/O size */
- int (*control)(); /* Module control function */
- long provide; /* Interface provided */
-} nsc_io_t;
-
-
-typedef struct nsc_path_s {
- struct nsc_path_s *sp_next; /* Link to next path */
- char *sp_path; /* Pathname */
- int sp_type; /* Open type */
- nsc_io_t *sp_io; /* I/O module */
- int sp_pend; /* Unregister pending */
-} nsc_path_t;
-
-
-/*
- * Note: NSC_MAXPATH currently defined here and in nsctl.h
- */
-#if !defined(NSC_MAXPATH)
-#define NSC_MAXPATH 64
-#endif
-
-
-#define NSC_SETVAL_MAX 32
-
-typedef struct nsc_val_s {
- struct nsc_val_s *sv_next; /* Link to next value */
- char sv_name[NSC_SETVAL_MAX]; /* Name of value */
- int sv_value; /* Value of name */
-} nsc_val_t;
-
-
-typedef struct nsc_devval_s {
- struct nsc_devval_s *dv_next; /* Next dev/val header */
- nsc_val_t *dv_values; /* The values */
- char dv_path[NSC_MAXPATH]; /* Path name of device */
- uint64_t dv_phash; /* Hash of pathname */
-} nsc_devval_t;
-
-
-/* used for ncall */
-typedef struct nsc_rval_s {
- char path[NSC_MAXPATH]; /* Path name of dev */
- char name[NSC_SETVAL_MAX]; /* Name of value */
- int value; /* Value of name */
-} nsc_rval_t;
-
-
-extern int _nsc_maxdev;
-
-#define _NSC_OPEN 0x0004 /* Open in progress */
-#define _NSC_CLOSE 0x0008 /* Close in progress */
-#define _NSC_PINNED 0x0010 /* Pinned data reported */
-#define _NSC_ATTACH 0x0020 /* Available for I/O */
-#define _NSC_DETACH 0x0040 /* Detach in progress */
-#define _NSC_OWNER 0x0080 /* Owner detach in progress */
-
-
-typedef struct nsc_iodev_s {
- struct nsc_iodev_s *si_next; /* Link to next I/O device */
- struct nsc_fd_s *si_open; /* Open file descriptors */
- kmutex_t si_lock; /* Lock to protect I/O chain */
- kcondvar_t si_cv; /* Blocking variable */
- int si_refcnt; /* Reference count */
- int si_busy; /* Callback in progress */
- int si_pend; /* Operation is pending */
- int si_rpend; /* Reserve is pending */
- int si_avail; /* Available for I/O */
- nsc_io_t *si_io; /* Interface to I/O module */
- void *si_active; /* Active I/O chain */
- struct nsc_dev_s *si_dev; /* Device structure */
-} nsc_iodev_t;
-
-
-typedef struct nsc_dev_s {
- struct nsc_dev_s *nsc_next; /* Link to next device */
- struct nsc_fd_s *nsc_close; /* Closed file descriptors */
- nsc_iodev_t *nsc_list; /* Active I/O modules */
- char *nsc_path; /* Pathname */
- uint64_t nsc_phash; /* Pathname hash */
- kmutex_t nsc_lock; /* Lock to protect state */
- int nsc_refcnt; /* Reference count */
- kcondvar_t nsc_cv; /* Blocking variable */
- int nsc_wait; /* Count of waiters */
- int nsc_pend; /* Operation is pending */
- int nsc_rpend; /* Reserve is pending */
- int nsc_drop; /* Detach on release */
- int nsc_reopen; /* Doing reopen */
- nsc_devval_t *nsc_values; /* Values - see nsc_setval() */
-} nsc_dev_t;
-
-
-/*
- * Storage file descriptor.
- */
-
-typedef struct nsc_fd_s {
- struct nsc_fd_s *sf_next; /* Link to next descriptor */
- nsc_iodev_t *sf_iodev; /* I/O device structure */
- nsc_iodev_t *sf_owner; /* Parent I/O device */
- nsc_dev_t *sf_dev; /* Device structure */
- nsc_io_t *sf_aio; /* Active I/O module */
- int sf_avail; /* Availability for I/O */
- int sf_pend; /* Operation is pending */
- int sf_type; /* Open type */
- int sf_flag; /* Open flags */
- clock_t sf_lbolt; /* Open timestamp */
- int sf_reopen; /* Re-open required */
- blind_t sf_cd; /* Underlying I/O descriptor */
- blind_t sf_arg; /* Argument for callbacks */
- int sf_reserve; /* Device is reserved */
- int sf_mode; /* Type of reserve */
- void (*sf_pinned)(); /* Callback - Data pinned */
- void (*sf_unpinned)(); /* Callback - Data unpinned */
- int (*sf_attach)(); /* Callback - Attach */
- int (*sf_detach)(); /* Callback - Detach */
- int (*sf_flush)(); /* Callback - Flush */
-} nsc_fd_t;
-
-
-/*
- * External definitions.
- */
-
-extern nsc_io_t *_nsc_null_io;
-
-#ifdef _KERNEL
-extern int _nsc_open_fd(nsc_fd_t *, int);
-extern int _nsc_close_fd(nsc_fd_t *, int);
-extern int _nsc_detach_fd(nsc_fd_t *, int);
-extern int _nsc_detach_iodev(nsc_iodev_t *, nsc_fd_t *, int);
-extern int _nsc_detach_dev(nsc_dev_t *, nsc_iodev_t *, int);
-extern int _nsc_call_io(long, blind_t, blind_t, blind_t);
-extern int _nsc_wait_dev(nsc_dev_t *, int);
-extern void _nsc_wake_dev(nsc_dev_t *, int *);
-#endif /* _KERNEL */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _NSC_DEV_H */
diff --git a/usr/src/uts/common/avs/ns/nsctl/nsc_disk.c b/usr/src/uts/common/avs/ns/nsctl/nsc_disk.c
deleted file mode 100644
index 5c514f8331..0000000000
--- a/usr/src/uts/common/avs/ns/nsctl/nsc_disk.c
+++ /dev/null
@@ -1,554 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/ksynch.h>
-#include <sys/errno.h>
-#include <sys/file.h>
-#include <sys/open.h>
-#include <sys/cred.h>
-#include <sys/kmem.h>
-#include <sys/uio.h>
-#include <sys/ddi.h>
-#include <sys/sdt.h>
-
-#define __NSC_GEN__
-#include "nsc_dev.h"
-#include "nsc_disk.h"
-#include "../nsctl.h"
-
-
-#define _I(x) (((long)(&((nsc_io_t *)0)->x))/sizeof (long))
-
-nsc_def_t _nsc_disk_def[] = {
- "UserRead", (uintptr_t)nsc_ioerr, _I(uread),
- "UserWrite", (uintptr_t)nsc_ioerr, _I(uwrite),
- "PartSize", (uintptr_t)nsc_null, _I(partsize),
- "MaxFbas", (uintptr_t)nsc_null, _I(maxfbas),
- "Control", (uintptr_t)nsc_ioerr, _I(control),
- 0, 0, 0
-};
-
-
-extern nsc_mem_t *_nsc_local_mem;
-
-static int _nsc_uread(dev_t, uio_t *, cred_t *, nsc_fd_t *);
-static int _nsc_uwrite(dev_t, uio_t *, cred_t *, nsc_fd_t *);
-static int _nsc_rw_uio(nsc_fd_t *, uio_t *, uio_rw_t);
-
-static int _nsc_free_dhandle(nsc_dbuf_t *);
-static int _nsc_alloc_dbuf(blind_t, nsc_off_t, nsc_size_t, int, nsc_dbuf_t **);
-static int _nsc_free_dbuf(nsc_dbuf_t *);
-static void _nsc_wait_dbuf(nsc_dbuf_t *);
-static int _nsc_read_dbuf(nsc_dbuf_t *, nsc_off_t, nsc_size_t, int);
-static int _nsc_write_dbuf(nsc_dbuf_t *, nsc_off_t, nsc_size_t, int);
-static int _nsc_zero_dbuf(nsc_dbuf_t *, nsc_off_t, nsc_size_t, int);
-static int _nsc_dbuf_io(int (*)(), nsc_dbuf_t *, nsc_off_t, nsc_size_t, int);
-
-static nsc_dbuf_t *_nsc_alloc_dhandle(void (*)(), void (*)(), void (*)());
-
-
-/*
- * void
- * _nsc_add_disk (nsc_io_t *io)
- * Add disk interface functions.
- *
- * Calling/Exit State:
- * Updates the I/O module with the appropriate
- * interface routines.
- *
- * Description:
- * Add functions to the I/O module to provide a disk
- * or cache interface as appropriate.
- */
-void
-_nsc_add_disk(nsc_io_t *io)
-{
- if ((io->alloc_buf != nsc_ioerr && io->free_buf != nsc_fatal) ||
- (io->flag & NSC_FILTER)) {
- if (io->uread == nsc_ioerr)
- io->uread = _nsc_uread;
-
- if (io->uwrite == nsc_ioerr &&
- (io->write != nsc_fatal || (io->flag & NSC_FILTER)))
- io->uwrite = _nsc_uwrite;
-
- return;
- }
-
- if (io->alloc_h != (nsc_buf_t *(*)())nsc_null ||
- io->free_h != nsc_fatal || io->alloc_buf != nsc_ioerr ||
- io->free_buf != nsc_fatal || io->read != nsc_fatal ||
- io->write != nsc_fatal || io->zero != nsc_fatal)
- return;
-
- if (io->uread == nsc_ioerr && io->uwrite == nsc_ioerr)
- return;
-
- /*
- * Layer the generic nsc_buf_t provider onto a uio_t provider.
- */
-
- io->alloc_h = (nsc_buf_t *(*)())_nsc_alloc_dhandle;
- io->free_h = _nsc_free_dhandle;
- io->alloc_buf = _nsc_alloc_dbuf;
- io->free_buf = _nsc_free_dbuf;
-
- io->read = _nsc_read_dbuf;
- io->write = _nsc_write_dbuf;
- io->zero = _nsc_zero_dbuf;
-
- io->provide |= NSC_ANON;
-}
-
-
-int
-nsc_uread(nsc_fd_t *fd, void *uiop, void *crp)
-{
- return (*fd->sf_aio->uread)(fd->sf_cd, uiop, crp, fd);
-}
-
-
-int
-nsc_uwrite(nsc_fd_t *fd, void *uiop, void *crp)
-{
- if ((fd->sf_avail & NSC_WRITE) == 0)
- return (EIO);
-
- return (*fd->sf_aio->uwrite)(fd->sf_cd, uiop, crp, fd);
-}
-
-
-int
-nsc_partsize(nsc_fd_t *fd, nsc_size_t *valp)
-{
- *valp = 0;
- return (*fd->sf_aio->partsize)(fd->sf_cd, valp);
-}
-
-
-int
-nsc_maxfbas(nsc_fd_t *fd, int flag, nsc_size_t *valp)
-{
- *valp = 0;
- return (*fd->sf_aio->maxfbas)(fd->sf_cd, flag, valp);
-}
-
-int
-nsc_control(nsc_fd_t *fd, int command, void *argp, int argl)
-{
- return (*fd->sf_aio->control)(fd->sf_cd, command, argp, argl);
-}
-
-
-/* ARGSUSED */
-
-static int
-_nsc_uread(dev_t dev, uio_t *uiop, cred_t *crp, nsc_fd_t *fd)
-{
- return (_nsc_rw_uio(fd, uiop, UIO_READ));
-}
-
-
-/* ARGSUSED */
-
-static int
-_nsc_uwrite(dev_t dev, uio_t *uiop, cred_t *crp, nsc_fd_t *fd)
-{
- return (_nsc_rw_uio(fd, uiop, UIO_WRITE));
-}
-
-
-static int
-_nsc_rw_uio(nsc_fd_t *fd, uio_t *uiop, uio_rw_t rw)
-{
- nsc_size_t buflen, len, limit, chunk;
- nsc_off_t pos, off;
- nsc_buf_t *buf;
- nsc_vec_t *vec;
- size_t n;
- int rc;
-
- pos = FPOS_TO_FBA(uiop);
- off = FPOS_TO_OFF(uiop);
- len = FBA_LEN(uiop->uio_resid + off);
-
- DTRACE_PROBE3(_nsc_rw_uio_io,
- uint64_t, pos,
- uint64_t, off,
- uint64_t, len);
-
- /* prevent non-FBA bounded I/O - this is a disk driver! */
- if (off != 0 || FBA_OFF(uiop->uio_resid) != 0)
- return (EINVAL);
-
- if ((rc = nsc_partsize(fd, &limit)) != 0)
- return (rc);
-
- if ((rc = nsc_maxfbas(fd, 0, &chunk)) != 0)
- return (rc);
-
- DTRACE_PROBE2(_nsc_rw_uio_limit,
- uint64_t, limit,
- uint64_t, chunk);
-
- if (limit && pos >= limit) {
- if (pos > limit || rw == UIO_WRITE)
- return (ENXIO);
- return (0);
- }
-
- if (limit && pos + len > limit)
- len = limit - pos;
-
- while (len > 0) {
- buflen = min(len, chunk);
-
- buf = NULL; /* always use a temporary buffer */
- if ((rc = nsc_alloc_buf(fd, pos, buflen,
- (rw == UIO_READ) ? NSC_RDBUF : NSC_WRBUF, &buf)) > 0)
- return (rc);
-
- vec = buf->sb_vec;
-
- for (rc = 0;
- !rc && uiop->uio_resid && vec->sv_addr;
- vec++, off = 0) {
- n = min(vec->sv_len - off, uiop->uio_resid);
- rc = uiomove((char *)vec->sv_addr + off,
- n, rw, uiop);
- }
-
- if (rw == UIO_WRITE) {
- if (rc) {
- (void) nsc_uncommit(buf, pos, buflen, 0);
- } else if ((rc = nsc_write(buf, pos, buflen, 0)) < 0) {
- rc = 0;
- }
- }
-
- (void) nsc_free_buf(buf);
-
- len -= buflen;
- pos += buflen;
- }
-
- return (rc);
-}
-
-
-/* ARGSUSED */
-
-static nsc_dbuf_t *
-_nsc_alloc_dhandle(void (*d_cb)(), void (*r_cb)(), void (*w_cb)())
-{
- nsc_dbuf_t *h;
-
- if ((h = nsc_kmem_zalloc(sizeof (nsc_dbuf_t),
- KM_SLEEP, _nsc_local_mem)) == NULL)
- return (NULL);
-
- h->db_disc = d_cb;
- h->db_flag = NSC_HALLOCATED;
-
- return (h);
-}
-
-
-static int
-_nsc_free_dhandle(nsc_dbuf_t *h)
-{
- nsc_kmem_free(h, sizeof (*h));
- return (0);
-}
-
-
-static int
-_nsc_alloc_dbuf(blind_t cd, nsc_off_t pos, nsc_size_t len,
- int flag, nsc_dbuf_t **hp)
-{
- nsc_dbuf_t *h = *hp;
- int rc;
-
- if (cd == NSC_ANON_CD) {
- flag &= ~(NSC_READ | NSC_WRITE | NSC_RDAHEAD);
- } else {
- if (h->db_maxfbas == 0) {
- rc = nsc_maxfbas(h->db_fd, 0, &h->db_maxfbas);
- if (rc != 0)
- return (rc);
- else if (h->db_maxfbas == 0)
- return (EIO);
- }
-
- if (len > h->db_maxfbas)
- return (ENOSPC);
- }
-
- if (flag & NSC_NODATA) {
- ASSERT(!(flag & NSC_RDBUF));
- h->db_addr = NULL;
- } else {
- if (h->db_disc)
- (*h->db_disc)(h);
-
- if (!(h->db_addr = nsc_kmem_alloc(FBA_SIZE(len), KM_SLEEP, 0)))
- return (ENOMEM);
- }
-
- h->db_pos = pos;
- h->db_len = len;
- h->db_error = 0;
- h->db_flag |= flag;
-
- if (flag & NSC_NODATA) {
- h->db_vec = NULL;
- } else {
- h->db_vec = &h->db_bvec[0];
- h->db_bvec[0].sv_len = FBA_SIZE(len);
- h->db_bvec[0].sv_addr = (void *)h->db_addr;
- h->db_bvec[0].sv_vme = 0;
-
- h->db_bvec[1].sv_len = 0;
- h->db_bvec[1].sv_addr = 0;
- h->db_bvec[1].sv_vme = 0;
- }
-
- if ((flag & NSC_RDAHEAD) || (cd == NSC_ANON_CD))
- return (NSC_DONE);
-
- _nsc_wait_dbuf(h);
-
- if (flag & NSC_RDBUF) {
- if ((rc = _nsc_dbuf_io(nsc_uread, h, pos, len, flag)) != 0) {
- (void) _nsc_free_dbuf(h);
- return (rc);
- }
- }
-
- return (NSC_DONE);
-}
-
-
-static void
-_nsc_wait_dbuf(nsc_dbuf_t *h)
-{
- nsc_iodev_t *iodev = h->db_fd->sf_iodev;
- void (*fn)() = h->db_disc;
- nsc_dbuf_t *hp;
-
- mutex_enter(&iodev->si_lock);
-
- h->db_next = iodev->si_active;
- iodev->si_active = h;
-
- /* CONSTCOND */
-
- while (1) {
- for (hp = h->db_next; hp; hp = hp->db_next)
- if (h->db_pos + h->db_len > hp->db_pos &&
- h->db_pos < hp->db_pos + hp->db_len) break;
-
- if (!hp)
- break;
-
- if (fn)
- (*fn)(h), fn = NULL;
-
- cv_wait(&iodev->si_cv, &iodev->si_lock);
- }
-
- mutex_exit(&iodev->si_lock);
-}
-
-
-static int
-_nsc_free_dbuf(nsc_dbuf_t *h)
-{
- nsc_dbuf_t **hpp, *hp;
- nsc_iodev_t *iodev;
- int wake = 0;
-
- if (h->db_fd && !(h->db_flag & NSC_ABUF)) {
- iodev = h->db_fd->sf_iodev;
-
- mutex_enter(&iodev->si_lock);
-
- hpp = (nsc_dbuf_t **)&iodev->si_active;
-
- for (; *hpp; hpp = &hp->db_next) {
- if ((hp = *hpp) == h) {
- *hpp = h->db_next;
- break;
- }
-
- if (h->db_pos + h->db_len > hp->db_pos &&
- h->db_pos < hp->db_pos + hp->db_len) wake = 1;
-
- }
- if (wake)
- cv_broadcast(&iodev->si_cv);
-
- mutex_exit(&iodev->si_lock);
- }
-
- if (!(h->db_flag & NSC_NODATA) && h->db_addr)
- nsc_kmem_free(h->db_addr, FBA_SIZE(h->db_len));
-
- h->db_addr = NULL;
- h->db_flag &= NSC_HALLOCATED; /* clear flags, preserve NSC_HALLOCATED */
-
- if ((h->db_flag & NSC_HALLOCATED) == 0)
- (void) _nsc_free_dhandle(h);
-
-
- return (0);
-}
-
-
-static int
-_nsc_read_dbuf(nsc_dbuf_t *h, nsc_off_t pos, nsc_size_t len, int flag)
-{
- return (_nsc_dbuf_io(nsc_uread, h, pos, len, flag));
-}
-
-
-static int
-_nsc_write_dbuf(nsc_dbuf_t *h, nsc_off_t pos, nsc_size_t len, int flag)
-{
- return (_nsc_dbuf_io(nsc_uwrite, h, pos, len, flag));
-}
-
-
-static int
-_nsc_zero_dbuf(nsc_dbuf_t *h, nsc_off_t pos, nsc_size_t len, int flag)
-{
- return (_nsc_dbuf_io(NULL, h, pos, len, flag));
-}
-
-
-static int
-_nsc_dbuf_io(int (*fn)(), nsc_dbuf_t *h, nsc_off_t pos,
- nsc_size_t len, int flag)
-{
- nsc_vec_t *vp = NULL;
- cred_t *crp = NULL;
- iovec_t *iovp;
- nsc_size_t thisio; /* bytes in this io */
- nsc_size_t todo; /* anticipated bytes to go */
- nsc_size_t truedo; /* actual bytes to go */
- nsc_off_t xpos; /* offset of this io */
- int destidx;
- nsc_size_t firstentryfix; /* value used for first entry */
-
- int (*iofn)();
- int rc = 0;
-
- if (!h->db_vec || (h->db_flag & NSC_ABUF))
- return (EIO);
-
- if (pos < h->db_pos || pos + len > h->db_pos + h->db_len)
- return (EINVAL);
-
- if (!len)
- return (0);
- if (fn == nsc_uread && (flag & NSC_RDAHEAD))
- return (0);
-
- if (h->db_disc)
- (*h->db_disc)(h);
-
- crp = ddi_get_cred();
- bzero(&h->db_uio, sizeof (uio_t));
- bzero(&h->db_iov[0], (_NSC_DBUF_NVEC * sizeof (iovec_t)));
-
- todo = FBA_SIZE(len);
-
- /*
- * determine where in the vector array we should start.
- */
- vp = h->db_vec;
- xpos = pos - h->db_pos;
- for (; xpos >= FBA_NUM(vp->sv_len); vp++)
- xpos -= FBA_NUM(vp->sv_len);
-
- firstentryfix = FBA_SIZE(xpos);
-
- xpos = pos;
-
- /*
- * Loop performing i/o to the underlying driver.
- */
- while (todo) {
- destidx = 0;
- thisio = 0;
- iofn = fn;
-
- /*
- * Copy up to _NSC_DBUF_NVEC vector entries from the
- * nsc_vec_t into the iovec_t so that the number of
- * i/o operations is minimised.
- */
- while (destidx < _NSC_DBUF_NVEC && todo) {
- iovp = &h->db_iov[destidx];
-
- ASSERT(FBA_LEN(vp->sv_len) == FBA_NUM(vp->sv_len));
- ASSERT((vp->sv_len - firstentryfix) && vp->sv_addr);
-
- truedo = min(vp->sv_len - firstentryfix, todo);
- iovp->iov_base = (caddr_t)vp->sv_addr + firstentryfix;
- firstentryfix = 0;
- iovp->iov_len = (size_t)truedo;
- if (!iofn) {
- bzero(iovp->iov_base, iovp->iov_len);
- }
- thisio += truedo;
- todo -= truedo;
- destidx++;
- vp++;
- }
-
- h->db_uio.uio_iovcnt = destidx;
- h->db_uio.uio_iov = &h->db_iov[0];
- h->db_uio.uio_segflg = UIO_SYSSPACE;
- h->db_uio.uio_resid = (size_t)thisio;
-
- SET_FPOS(&h->db_uio, xpos);
-
- if (!iofn) {
- iofn = nsc_uwrite;
- }
-
- rc = (*iofn)(h->db_fd, &h->db_uio, crp);
- if (rc != 0) {
- break;
- }
-
- ASSERT(FBA_LEN(thisio) == FBA_NUM(thisio));
- xpos += FBA_LEN(thisio);
- }
-
- return (rc);
-}
diff --git a/usr/src/uts/common/avs/ns/nsctl/nsc_disk.h b/usr/src/uts/common/avs/ns/nsctl/nsc_disk.h
deleted file mode 100644
index f7d52260df..0000000000
--- a/usr/src/uts/common/avs/ns/nsctl/nsc_disk.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _NSC_DISK_H
-#define _NSC_DISK_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef __NSC_GEN__
-Error: Illegal #include - private file.
-#endif
-
-#include <sys/types.h>
-#include <sys/file.h>
-#include <sys/uio.h>
-
-#include <sys/nsctl/nsc_dev.h>
-#include <sys/nsctl/nsctl.h>
-
-#define _NSC_DBUF_NVEC 5
-
-/*
- * Buffer structure for disk I/O.
- */
-
-typedef struct nsc_dbuf_s {
- nsc_buf_t db_buf; /* Generic buffer header */
- void (*db_disc)(); /* Disconnect callback */
- uio_t db_uio; /* Scatter/gather list */
- iovec_t db_iov[_NSC_DBUF_NVEC]; /* Data transfer address */
- char *db_addr; /* Address of data buffer */
- nsc_vec_t db_bvec[2]; /* Pointers to data */
- struct nsc_dbuf_s *db_next; /* Link to next buffer */
- nsc_size_t db_maxfbas; /* Maxfbas value for the device */
-} nsc_dbuf_t;
-
-
-#define db_fd db_buf.sb_fd
-#define db_pos db_buf.sb_pos
-#define db_len db_buf.sb_len
-#define db_flag db_buf.sb_flag
-#define db_error db_buf.sb_error
-#define db_vec db_buf.sb_vec
-
-
-/*
- * Sector Mode definitions.
- */
-
-#define FPOS_TO_FBA(u) ((nsc_off_t)(FBA_NUM((u)->uio_loffset)))
-#define FPOS_TO_OFF(u) ((nsc_off_t)(FBA_OFF((u)->uio_loffset)))
-#define SET_FPOS(u, f) ((u)->uio_loffset = (offset_t)FBA_SIZE((offset_t)f))
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _NSC_DISK_H */
diff --git a/usr/src/uts/common/avs/ns/nsctl/nsc_freeze.c b/usr/src/uts/common/avs/ns/nsctl/nsc_freeze.c
deleted file mode 100644
index b86fc9e65d..0000000000
--- a/usr/src/uts/common/avs/ns/nsctl/nsc_freeze.c
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/errno.h>
-#include <sys/cmn_err.h>
-#include <sys/ksynch.h>
-#include <sys/kmem.h>
-#include <sys/ddi.h>
-
-#define __NSC_GEN__
-#include "nsc_dev.h"
-#include "../nsctl.h"
-
-/*
- * (Un)Freeze Module
- *
- * This module provides a means to 'freeze' a device and ensure
- * that no SP software has an open reference to that device. Later
- * the device can be 'unfrozen' and the SP software can resume
- * normal operations.
- *
- * This module is required because it is possible to place a virtual
- * volume driver (RAID-0, 1 or 5) into a state whereby it needs to be
- * disabled for corrective action. The (un)freeze facility provides a
- * method of doing this without downtime.
- *
- * A device that is frozen should be frozen on all nodes. It is the
- * responsibility of the management software or the user to perform
- * the freeze and unfreeze on the required nodes.
- */
-
-extern nsc_mem_t *_nsc_local_mem;
-
-typedef struct _nsc_frz_s {
- struct _nsc_frz_s *next;
- nsc_path_t *token;
- char path[NSC_MAXPATH];
-} _nsc_frz_t;
-
-
-extern int _nsc_frz_stop(char *, int *); /* forward decl */
-
-static _nsc_frz_t *_nsc_frz_top;
-static nsc_def_t _nsc_frz_def[];
-static kmutex_t _nsc_frz_sleep;
-static nsc_io_t *_nsc_frz_io;
-
-
-void
-_nsc_init_frz(void)
-{
- mutex_init(&_nsc_frz_sleep, NULL, MUTEX_DRIVER, NULL);
-
- _nsc_frz_io = nsc_register_io("frz",
- NSC_FREEZE_ID | NSC_FILTER, _nsc_frz_def);
-
- if (!_nsc_frz_io)
- cmn_err(CE_WARN, "nsctl: _nsc_init_frz: register failed");
-}
-
-
-void
-_nsc_deinit_frz(void)
-{
- if (_nsc_frz_io)
- (void) nsc_unregister_io(_nsc_frz_io, 0);
-
- _nsc_frz_io = NULL;
-
- mutex_destroy(&_nsc_frz_sleep);
-}
-
-
-/*
- * int _nsc_frz_start(char *path, int *rvp)
- * Freeze a device
- *
- * Calling/Exit State:
- * Must be called from a context that can block.
- * Returns 0 for success, or one of the following error codes:
- * EINVAL - invalid 'path' argument
- * ENOMEM - failed to allocate memory
- * EALREADY - 'path' is already frozen
- *
- * Description:
- * Registers 'path' to be accessed through the NSC_FREEZE_ID
- * io module, and forces any open file descriptors for 'path'
- * to be re-opened as appropriate.
- */
-int
-_nsc_frz_start(path, rvp)
-char *path;
-int *rvp;
-{
- _nsc_frz_t *frz, *xfrz;
- int rc;
-
- *rvp = 0;
-
- if (strlen(path) >= NSC_MAXPATH)
- return (EINVAL);
-
- frz = nsc_kmem_zalloc(sizeof (*frz), KM_SLEEP, _nsc_local_mem);
- if (!frz)
- return (ENOMEM);
-
- (void) strcpy(frz->path, path);
-
- mutex_enter(&_nsc_frz_sleep);
-
- for (xfrz = _nsc_frz_top; xfrz; xfrz = xfrz->next)
- if (strcmp(frz->path, xfrz->path) == 0)
- break;
-
- if (!xfrz) {
- frz->next = _nsc_frz_top;
- _nsc_frz_top = frz;
- }
-
- mutex_exit(&_nsc_frz_sleep);
-
- if (xfrz) {
- nsc_kmem_free(frz, sizeof (*frz));
- return (EALREADY);
- }
-
- frz->token = nsc_register_path(path, NSC_DEVICE, _nsc_frz_io);
-
- if (!frz->token) {
- (void) _nsc_frz_stop(path, &rc);
- return (EINVAL);
- }
-
- return (0);
-}
-
-
-/*
- * int _nsc_frz_stop(char *path, int *rvp)
- * Unfreeze a device
- *
- * Calling/Exit State:
- * Must be called from a context that can block.
- * Returns 0 or an error code.
- *
- * Description:
- * Removes the path registration for the NSC_FREEZE_ID io module
- * and forces any re-opens as appropriate.
- */
-int
-_nsc_frz_stop(path, rvp)
-char *path;
-int *rvp;
-{
- _nsc_frz_t **xfrz, *frz = NULL;
- int rc = 0;
-
- *rvp = 0;
-
- mutex_enter(&_nsc_frz_sleep);
-
- for (xfrz = &_nsc_frz_top; *xfrz; xfrz = &(*xfrz)->next)
- if (strcmp(path, (*xfrz)->path) == 0) {
- frz = *xfrz;
- break;
- }
-
- if (!frz) {
- mutex_exit(&_nsc_frz_sleep);
- return (EINVAL);
- }
-
- if (frz->token)
- rc = nsc_unregister_path(frz->token, NSC_PCATCH);
-
- if (rc) {
- mutex_exit(&_nsc_frz_sleep);
- return (rc);
- }
-
- (*xfrz) = frz->next;
-
- mutex_exit(&_nsc_frz_sleep);
-
- nsc_kmem_free(frz, sizeof (*frz));
-
- return (0);
-}
-
-
-/*
- * int _nsc_frz_isfrozen(char *path, int *rvp)
- * Tests whether a device is frozen.
- *
- * Calling/Exit State:
- * Returns 0 or EINVAL.
- * Sets *rvp to 1 if the device was not frozen, and 0 otherwise.
- * This function returns historical information.
- */
-int
-_nsc_frz_isfrozen(path, rvp)
-char *path;
-int *rvp;
-{
- _nsc_frz_t *frz;
-
- *rvp = 1;
-
- if (! _nsc_frz_io)
- return (EINVAL);
-
- mutex_enter(&_nsc_frz_sleep);
-
- for (frz = _nsc_frz_top; frz; frz = frz->next)
- if (strcmp(frz->path, path) == 0) {
- *rvp = 0;
- break;
- }
-
- mutex_exit(&_nsc_frz_sleep);
-
- return (0);
-}
-
-
-/*
- * static int
- * _nsc_frz_open(char *path, int flag, blind_t *cdp)
- * Dummy open function.
- *
- * Description:
- * This is the "Open" function for the I/O module.
- * It is just a dummy.
- */
-
-/* ARGSUSED */
-
-static int
-_nsc_frz_open(path, flag, cdp)
-char *path;
-int flag;
-blind_t *cdp;
-{
- *cdp = 0;
- return (0);
-}
-
-
-/*
- * static int
- * _nsc_frz_close()
- * Dummy close function.
- *
- * Description:
- * This is the "Close" function for the I/O module.
- * It is just a dummy.
- */
-static int
-_nsc_frz_close() { return (0); }
-
-
-/*
- * static int
- * _nsc_frz_attach()
- * Attach a device to this i/o module.
- *
- * Calling/Exit State:
- * Returns EACCES in all cricumstances.
- *
- * Description:
- * This function is called by the nsctl module when it wishes
- * to attach the device to this I/O module (ie. as part of
- * nsc_reserve() processing). This function unconditionally
- * returns an error which forces the nsc_reserve() to fail, and
- * so no access to possible to the underlying device.
- */
-static int
-_nsc_frz_attach() { return (EACCES); }
-
-
-static nsc_def_t _nsc_frz_def[] = {
- "Open", (uintptr_t)_nsc_frz_open, 0,
- "Close", (uintptr_t)_nsc_frz_close, 0,
- "Attach", (uintptr_t)_nsc_frz_attach, 0,
- "Provide", 0, 0,
- 0, 0, 0
-};
diff --git a/usr/src/uts/common/avs/ns/nsctl/nsc_gen.c b/usr/src/uts/common/avs/ns/nsctl/nsc_gen.c
deleted file mode 100644
index 77a6165fcb..0000000000
--- a/usr/src/uts/common/avs/ns/nsctl/nsc_gen.c
+++ /dev/null
@@ -1,1106 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/cmn_err.h>
-#include <sys/errno.h>
-#include <sys/ksynch.h>
-#include <sys/kmem.h>
-#include <sys/ddi.h>
-#include <sys/varargs.h>
-#if defined(DEBUG) && !defined(DS_DDICT)
-#include <sys/kobj.h>
-#endif
-
-#include <sys/ncall/ncall.h>
-
-#define __NSC_GEN__
-#include "nsc_gen.h"
-#include "nsc_mem.h"
-#include "../nsctl.h"
-#ifdef DS_DDICT
-#include "../contract.h"
-#endif
-
-
-static kcondvar_t _nsc_delay_cv;
-static kmutex_t _nsc_delay_mutex;
-
-static nsc_service_t *_nsc_services;
-static kmutex_t _nsc_svc_mutex;
-
-static int _nsc_rmmap_inuse(nsc_rmmap_t *, ulong_t *, size_t *);
-
-static void _nsc_sprint_dec(char **, int, int, int);
-static void _nsc_sprint_hex(char **, unsigned int, int, int, int, int);
-
-clock_t HZ;
-
-extern nsc_rmhdr_t *_nsc_rmhdr_ptr;
-
-void
-_nsc_init_gen()
-{
- HZ = drv_usectohz(1000000);
-}
-
-
-void
-nsc_decode_param(nsc_def_t *args, nsc_def_t *def, long *v)
-{
- nsc_def_t *dp;
-
- for (; def && def->name; def++) {
- for (dp = args; dp && dp->name; dp++) {
- if (strcmp(dp->name, def->name) == 0) {
- v[def->offset] = dp->value;
- break;
- }
- }
-
- if ((!dp || !dp->name) && !v[def->offset])
- v[def->offset] = def->value;
- }
-}
-
-
-clock_t
-nsc_lbolt()
-{
-#ifdef _SunOS_5_6
- clock_t lbolt;
- time_t time;
-
- if (drv_getparm(LBOLT, &lbolt) == 0)
- return (lbolt);
-
- if (drv_getparm(TIME, &time) != 0)
- return ((clock_t)0);
-
- time %= (60 * 60 * 24 * 365);
-
- return (clock_t)(time * HZ);
-#else
- return (ddi_get_lbolt());
-#endif
-}
-
-
-time_t
-nsc_time()
-{
- time_t time;
-
- if (drv_getparm(TIME, &time) != 0)
- return ((time_t)0);
-
- return (time);
-}
-
-
-int
-nsc_node_up(int node)
-{
- return (node == ncall_self());
-}
-
-
-
-/*
- * HACK increment nodeid in data parameter
- */
-int
-nsc_nodeid_data()
-{
- int data;
- return ((data = nsc_node_id()) == 0 ? 1 : data);
-}
-
-
-int
-nsc_node_id(void)
-{
- return (ncall_self());
-}
-
-char *
-nsc_node_name()
-{
- return (ncall_nodename(ncall_self()));
-}
-
-
-/*
- * int
- * _nsc_rmmap_init (nsc_rmmap_t *map, char *name, int nslot,
- * size_t size, ulong_t offset)
- * Initialise a global resource map.
- *
- * Calling/Exit State:
- * Returns TRUE if the map was successfully created. Otherwise
- * returns FALSE.
- *
- * Description:
- * Initialises a global resource map. If the map already exists
- * the arguments are validated against it.
- */
-int
-_nsc_rmmap_init(nsc_rmmap_t *map, char *name,
- int nslot, size_t size, ulong_t offset)
-{
- nsc_rmmap_t *nvmap = NULL;
-
- if (!size)
- return (0);
-
- mutex_enter(&_nsc_global_lock);
-
- if (_nsc_rm_nvmem_base)
- nvmap = _nsc_global_nvmemmap_lookup(map);
-
- if (!map->size)
- map->size = size;
- if (!map->inuse)
- map->inuse = nslot;
- if (!map->offset)
- map->offset = offset;
-
- if (!map->name[0])
- (void) strncpy(map->name, name, _NSC_MAXNAME);
-
- /* actually we only need to do this if an update occurred above */
- if (nvmap) {
- (void) nsc_commit_mem(map, nvmap,
- sizeof (nsc_rmmap_t), nsc_cm_errhdlr);
- }
-
- if (strncmp(map->name, name, _NSC_MAXNAME) ||
- (uint32_t)size != map->size || (int32_t)offset != map->offset) {
- mutex_exit(&_nsc_global_lock);
- return (0);
- }
-
- mutex_exit(&_nsc_global_lock);
- return (1);
-}
-
-
-/*
- * ulong_t
- * _nsc_rmmap_alloc (nsc_rmmap_t *map, char *name,
- * size_t size, void (*alloc)())
- * Allocate entry in a global resource map.
- *
- * Calling/Exit State:
- * On success, returns the base of the allocated area. Otherwise,
- * returns NULL. The function 'alloc' will be called if the
- * allocated area is not currently in use.
- *
- * Description:
- * Allocates an entry in the global resource map. If the entry
- * already exists but is a different size an error is returned.
- */
-ulong_t
-_nsc_rmmap_alloc(nsc_rmmap_t *map, char *name, size_t size, void (*alloc)())
-{
- int i, nslot = map[0].inuse;
- size_t want = size;
- ulong_t offset;
- nsc_rmmap_t *nvmap = NULL;
-
- if (!size)
- return (0);
-
- mutex_enter(&_nsc_global_lock);
- if (_nsc_rm_nvmem_base)
- nvmap = _nsc_global_nvmemmap_lookup(map);
-
- for (i = 1; i < nslot; i++) {
- if (!map[i].inuse || !map[i].size)
- continue;
- if (strncmp(map[i].name, name, _NSC_MAXNAME))
- continue;
- if ((uint32_t)size == map[i].size) {
- map[i].inuse |= (1 << nsc_node_id());
- if (nvmap) {
- (void) nsc_commit_mem(&map[i], &nvmap[i],
- sizeof (nsc_rmmap_t), nsc_cm_errhdlr);
- }
- mutex_exit(&_nsc_global_lock);
- return (map[i].offset);
- }
-
- mutex_exit(&_nsc_global_lock);
- return (0);
- }
-
- offset = map[0].offset;
-
- while ((int32_t)offset < (map[0].offset + map[0].size)) {
- if (_nsc_rmmap_inuse(map, &offset, &want))
- continue;
-
- if (size > want) {
- offset += want;
- want = size;
- continue;
- }
-
- for (i = 1; i < nslot; i++)
- if (!map[i].inuse || !map[i].size)
- break;
-
- if (i == nslot)
- break;
-
- bzero(&map[i], sizeof (map[i]));
- (void) strncpy(map[i].name, name, _NSC_MAXNAME);
-
- map[i].size = size;
- map[i].offset = offset;
- map[i].inuse = (1 << nsc_node_id());
- if (nvmap) { /* update the map and hdr dirty bit. */
- (void) nsc_commit_mem(&map[i], &nvmap[i],
- sizeof (nsc_rmmap_t), nsc_cm_errhdlr);
- }
-
- if (alloc)
- (*alloc)(offset, size);
-
- mutex_exit(&_nsc_global_lock);
- return (offset);
- }
-
- mutex_exit(&_nsc_global_lock);
- return (0);
-}
-
-
-/*
- * void
- * _nsc_rmmap_free (nsc_rmmap_t *map, char *name)
- * Free entry in a global resource map.
- *
- * Description:
- * Frees an entry in the global resource map.
- */
-void
-_nsc_rmmap_free(nsc_rmmap_t *map, char *name, nsc_mem_t *mp)
-{
- int i, nslot = map[0].inuse;
- nsc_rmmap_t *nvmap = NULL;
-
- mutex_enter(&_nsc_global_lock);
- if (_nsc_rm_nvmem_base)
- nvmap = _nsc_global_nvmemmap_lookup(map);
-
- for (i = 1; i < nslot; i++) {
- if (!map[i].inuse || !map[i].size)
- continue;
- if (strncmp(map[i].name, name, _NSC_MAXNAME))
- continue;
-
- map[i].inuse &= ~(1 << nsc_node_id());
- if (nvmap) {
- /*
- * if dirty, set the inuse bit so this area
- * will not be _nsc_global_zero'd on restart.
- */
- if (mp && (mp->type & NSC_MEM_NVDIRTY)) {
- map[i].inuse |= (1 << nsc_node_id());
- }
-
- (void) nsc_commit_mem(&map[i], &nvmap[i],
- sizeof (nsc_rmmap_t), nsc_cm_errhdlr);
- }
- mutex_exit(&_nsc_global_lock);
- return;
- }
-
- mutex_exit(&_nsc_global_lock);
-
- cmn_err(CE_WARN, "!nsctl: _nsc_rmmap_free: invalid free");
-}
-
-
-/*
- * size_t
- * _nsc_rmmap_size (nsc_rmmap_t *map, char *name)
- * Find size of area in map.
- *
- * Calling/Exit State:
- * Returns the size of the specified area in the map,
- * or 0 if it is currently unallocated.
- */
-size_t
-_nsc_rmmap_size(nsc_rmmap_t *map, char *name)
-{
- int i, nslot = map[0].inuse;
- size_t size = 0;
-
- mutex_enter(&_nsc_global_lock);
-
- for (i = 1; i < nslot; i++) {
- if (!map[i].inuse || !map[i].size)
- continue;
-
- if (strncmp(map[i].name, name, _NSC_MAXNAME) == 0) {
- size = map[i].size;
- break;
- }
- }
-
- mutex_exit(&_nsc_global_lock);
- return (size);
-}
-
-
-/*
- * size_t
- * _nsc_rmmap_avail (nsc_rmmap_t *map)
- * Find available space in global resource map.
- *
- * Calling/Exit State:
- * Returns the size of the largest available area in
- * the global resource map.
- */
-size_t
-_nsc_rmmap_avail(nsc_rmmap_t *map)
-{
- size_t size, avail = 0;
- ulong_t offset;
-
- mutex_enter(&_nsc_global_lock);
-
- size = 1;
- offset = map[0].offset;
-
- while ((int32_t)offset < (map[0].offset + map[0].size))
- if (!_nsc_rmmap_inuse(map, &offset, &size)) {
- if (size > avail)
- avail = size;
- offset += size;
- size = 1;
- }
-
- mutex_exit(&_nsc_global_lock);
- return (avail);
-}
-
-
-/*
- * static int
- * _nsc_rmmap_inuse (nsc_rmmap_t *map, ulong_t *offsetp, size_t *sizep)
- * Check if a section of the map is in use.
- *
- * Calling/Exit State:
- * The global lock must be held across calls to the function.
- *
- * Returns TRUE if the specified area is currently in use and
- * updates offset to point just past the section that was found
- * to be in use.
- *
- * Otherwise, returns FALSE and updates size to reflect the
- * amount of free space at the specified offset.
- *
- * Description:
- * Checks the specified global map to determine if any part
- * of the area is in use.
- */
-static int
-_nsc_rmmap_inuse(nsc_rmmap_t *map, ulong_t *offsetp, size_t *sizep)
-{
- size_t avail, size = (*sizep);
- ulong_t offset = (*offsetp);
- int i, nslot;
-
- nslot = map[0].inuse;
- avail = map[0].offset + map[0].size - offset;
-
- for (i = 1; i < nslot; i++) {
- if (!map[i].size || !map[i].inuse)
- continue;
- if ((int32_t)(offset + size) > map[i].offset &&
- (int32_t)offset < (map[i].offset + map[i].size)) {
- (*offsetp) = map[i].offset + map[i].size;
- return (1);
- }
-
- if (map[i].offset >= (int32_t)offset)
- if (avail > map[i].offset - offset)
- avail = map[i].offset - offset;
- }
-
- (*sizep) = avail;
- return (0);
-}
-
-/*
- * int
- * nsc_delay_sig (clock_t tics)
- * Delay for a number of clock ticks.
- *
- * Calling/Exit State:
- * Returns FALSE if the delay was interrupted by a
- * signal, TRUE otherwise.
- *
- * Description:
- * Delays execution for the specified number of ticks
- * or until a signal is received.
- */
-int
-nsc_delay_sig(clock_t tics)
-{
- clock_t target, remain, rc;
-
- target = nsc_lbolt() + tics;
- rc = 1;
-
- mutex_enter(&_nsc_delay_mutex);
-
- /* CONSTCOND */
-
- while (1) {
- remain = target - nsc_lbolt();
-
- if (remain <= 0 || rc == -1) {
- /* timeout */
- break;
- }
-
- rc = cv_timedwait_sig(&_nsc_delay_cv,
- &_nsc_delay_mutex, target);
-
- if (rc == 0) {
- /* signalled */
- mutex_exit(&_nsc_delay_mutex);
- return (FALSE);
- }
- }
-
- mutex_exit(&_nsc_delay_mutex);
-
- return (TRUE);
-}
-
-
-/*
- * void
- * nsc_sprintf (char *s, char *fmt, ...)
- * String printf.
- *
- * Calling/Exit State:
- * Builds a NULL terminated string in the buffer
- * pointed to by 's', using the format 'fmt'.
- *
- * Description:
- * Simple version of sprintf supporting fairly
- * basic formats.
- */
-
-/* PRINTFLIKE2 */
-
-void
-nsc_sprintf(char *s, char *fmt, ...)
-{
- int alt, zero, len;
- char c, *cp;
- va_list p;
-
- va_start(p, fmt);
-
- /* CONSTCOND */
-
- while (1) {
- alt = 0, zero = 0, len = 0;
-
- if ((c = *fmt++) != '%') {
- if (!c)
- break;
- *s++ = c;
- continue;
- }
-
- if ((c = *fmt++) == 0) {
- *s++ = '%';
- break;
- }
-
- alt = (c == '#');
- if (alt && !(c = *fmt++))
- break;
-
- zero = (c == '0');
- if (zero && !(c = *fmt++))
- break;
-
- while ((len ? '0' : '1') <= c && c <= '9') {
- len = (len * 10) + (c - '0');
- if (!(c = *fmt++))
- break;
- }
-
- if (c == 's') {
- cp = (char *)va_arg(p, caddr_t);
- while (*cp)
- *s++ = *cp++;
- continue;
- }
-
- if (c == 'd' || c == 'u') {
- _nsc_sprint_dec(&s, va_arg(p, int), zero, len);
- continue;
- }
-
- if (c == 'x' || c == 'X') {
- _nsc_sprint_hex(&s, va_arg(p, uint_t),
- (c == 'X'), alt, zero, len);
- continue;
- }
-
- *s++ = '%';
- if (alt)
- *s++ = '#';
- if (zero)
- *s++ = '0';
-
- if (len)
- _nsc_sprint_dec(&s, len, 0, 0);
- *s++ = c;
- }
-
- if (alt || zero || len) {
- *s++ = '%';
-
- if (alt)
- *s++ = '#';
- if (zero)
- *s++ = '0';
-
- if (len)
- _nsc_sprint_dec(&s, len, 0, 0);
- }
-
- va_end(p);
- *s = 0;
-}
-
-
-/*
- * static void
- * _nsc_sprint_dec (char **sptr, int n, int zero, int len)
- * Decimal to string conversion.
- *
- * Calling/Exit State:
- * Stores a character representation of 'n' in the
- * buffer referenced by 'sptr' and updates the pointer
- * accordingly.
- *
- * Description:
- * Generates a string representation of a signed decimal
- * integer.
- */
-
-static void
-_nsc_sprint_dec(char **sptr, int n, int zero, int len)
-{
- unsigned int v = (n < 0) ? (-n) : n;
- char c[20];
- int i;
-
- for (i = 0; v; i++) {
- c[i] = (v % 10) + '0';
- v /= 10;
- }
-
- len -= (i ? i : 1);
-
- if (n < 0 && !zero)
- for (len--; len > 0; len--)
- *(*sptr)++ = ' ';
-
- if (n < 0) {
- *(*sptr)++ = '-';
- len--;
- }
-
- for (; len > 0; len--)
- *(*sptr)++ = (zero ? '0' : ' ');
-
- if (!i)
- *(*sptr)++ = '0';
-
- while (i--)
- *(*sptr)++ = c[i];
-}
-
-
-/*
- * static void
- * _nsc_sprint_hex (char **sptr, unsigned int v,
- * int up, int alt, int zero, int len)
- * Hexadecimal to string conversion.
- *
- * Calling/Exit State:
- * Stores a character representation of 'v' in the
- * buffer referenced by 'sptr' and updates the pointer
- * accordingly.
- *
- * Description:
- * Generates a string representation of an unsigned
- * hexadecimal integer.
- */
-
-static void
-_nsc_sprint_hex(char **sptr, uint_t v, int up, int alt, int zero, int len)
-{
- char *str = "0123456789abcdef";
- char c[20];
- int i;
-
- if (up)
- str = "0123456789ABCDEF";
-
- for (i = 0; v; i++) {
- c[i] = str[(v % 16)];
- v /= 16;
- }
-
- if (alt) {
- *(*sptr)++ = '0';
- *(*sptr)++ = (up ? 'X' : 'x');
- }
-
- for (len -= (i ? i : 1); len > 0; len--)
- *(*sptr)++ = (zero ? '0' : ' ');
-
- if (!i)
- *(*sptr)++ = '0';
- while (i--)
- *(*sptr)++ = c[i];
-}
-
-
-/*
- * char *
- * nsc_strdup (char *s)
- * Duplicate string.
- *
- * Calling/Exit State:
- * Returns the address of the new string.
- *
- * Description:
- * Allocates a suitably sized area of memory and
- * copies the string into it. The string should be
- * free'd using nsc_strfree().
- */
-char *
-nsc_strdup(char *s)
-{
- char *cp;
-
- if (s == NULL)
- return (NULL);
-
- cp = nsc_kmem_alloc(strlen(s) + 1, KM_SLEEP, NULL);
- (void) strcpy(cp, s);
- return (cp);
-}
-
-
-/*
- * void
- * nsc_strfree (char *s)
- * Free string.
- *
- * Description:
- * Frees a string previously allocated by nsc_strdup.
- */
-void
-nsc_strfree(char *s)
-{
- if (s)
- nsc_kmem_free(s, strlen(s) + 1);
-}
-
-
-/*
- * int
- * nsc_strmatch (char *s, char *pat)
- * Match string against pattern.
- *
- * Calling/Exit State:
- * Returns TRUE if the string matches against the
- * pattern, FALSE otherwise.
- *
- * Description:
- * Compares string against regular expression which
- * can contain '*', '?' and '[]' constructs.
- */
-int
-nsc_strmatch(char *s, char *pat)
-{
- int neg;
-
- for (; *pat; pat++, s++) {
- if (*pat == '*') {
- while (*pat == '*')
- pat++;
-
- if (!*pat)
- return (1);
-
- for (; *s; s++)
- if (*pat == '[' || *pat == '?' || *pat == *s)
- if (nsc_strmatch(s, pat))
- return (1);
- return (0);
- }
-
- if (!*s)
- return (0);
-
- if (*pat == '[') {
- if ((neg = (*++pat == '^')) != 0)
- pat++;
-
- while (*pat) {
- if (*pat == *s)
- break;
-
- if (pat[1] == '-' && pat[2] != ']') {
- if (*pat <= *s && *s <= pat[2])
- break;
- pat += 2;
- }
-
- if (*++pat == ']') {
- if (neg)
- goto lp;
- else
- return (0);
- }
- }
-
- while (*pat && *++pat != ']')
- ;
-
- if (!*pat || neg)
- return (0);
-lp:
- continue;
- }
-
- if (*pat != '?' && *pat != *s)
- return (0);
- }
-
- return (!*s);
-}
-
-
-/*
- * uint64_t
- * nsc_strhash(char *str)
- * Calculate a simple hash for the specified string
- *
- * Calling/Exit State:
- * Returns a simple hash of the NULL terminated string, str.
- *
- * Description:
- */
-uint64_t
-nsc_strhash(char *str)
-{
- uint64_t hash = (uint64_t)0;
-
- if (str == NULL)
- return (hash);
-
- while (*str != '\0') {
- hash <<= 1;
- hash += (uint64_t)*str;
- str++;
- }
-
- return (hash);
-}
-
-
-/*
- * int
- * nsc_fatal(void)
- * Fatal error stub function
- *
- * Calling/Exit State:
- * Returns EINVAL (non-DEBUG) or forces a panic.
- *
- * Description:
- * This is a stub function suitable for default actions in
- * nsctl i/o provider definitions. It should be used when
- * calling the stub would be a programming error. The most
- * common reason for nsc_fatal() being called is that an
- * nsctl client module has called an nsc_fd_t i/o function
- * without the fd already reserved.
- *
- * The function will display a diagnostic message and when
- * built -DDEBUG will force a panic and display the textual
- * name of the symbol closest to the caller address of this
- * function.
- */
-int
-nsc_fatal()
-{
- void *caller = nsc_caller();
-#ifdef DEBUG
- caddr_t caller_sym = NULL;
- ulong_t offset = 0UL;
-
-#ifndef DS_DDICT
- caller_sym = kobj_getsymname((uintptr_t)caller, &offset);
-#endif /* !DS_DDICT */
-
- cmn_err(CE_WARN, "!nsctl: nsc_fatal called at 0x%p (%s+0x%lx)",
- caller, caller_sym ? caller_sym : "?", offset);
-
- /*
- * Force TRAP due to NULL pointer dereference
- * - CE_PANIC can result in the stack trace being unreadable
- * by (k)adb.
- */
- *(int *)0 = 0x12345678;
-
-#else /* !DEBUG */
-
- cmn_err(CE_WARN, "!nsctl: nsc_fatal called at 0x%p", caller);
-
-#endif /* DEBUG */
-
- return (EINVAL);
-}
-
-
-int nsc_null() { return (0); }
-int nsc_true() { return (1); }
-int nsc_inval() { return (-1); }
-int nsc_ioerr() { return (EIO); }
-
-/*ARGSUSED*/
-int
-nsc_commit_mem(void *src, void *dst, size_t len, nsc_mem_err_cb err_action)
-{
-
- return (0);
-}
-
-static int _nsc_nvmem_errs;
-
-/* ARGSUSED */
-void
-nsc_cm_errhdlr(void *src, void *dst, size_t len, int errval)
-{
- static int _nsc_baddma_already_seen = 0;
-
- if (!(_nsc_baddma_already_seen % 100)) {
- cmn_err(CE_WARN, "!nsc_cm_errhdlr: media down, forced_wrthru");
-
- _nsc_baddma_already_seen += 1;
-
- if (_nsc_baddma_already_seen >= 100) {
- cmn_err(CE_WARN,
- "!nsc_cm_errhdlr: this message "
- "displayed every 100 errors");
- }
- }
-
- (void) nsc_node_hints_set(NSC_FORCED_WRTHRU);
-
- _nsc_nvmem_errs++;
-}
-
-
-void
-_nsc_init_svc(void)
-{
- mutex_init(&_nsc_svc_mutex, NULL, MUTEX_DRIVER, NULL);
- mutex_init(&_nsc_delay_mutex, NULL, MUTEX_DRIVER, NULL);
- cv_init(&_nsc_delay_cv, NULL, CV_DRIVER, NULL);
-}
-
-
-void
-_nsc_deinit_svc(void)
-{
- if (_nsc_services != NULL) {
- cmn_err(CE_PANIC,
- "nsctl: services registered in _nsc_deinit_svc");
- /* NOTREACHED */
- }
-
- cv_destroy(&_nsc_delay_cv);
- mutex_destroy(&_nsc_delay_mutex);
- mutex_destroy(&_nsc_svc_mutex);
-}
-
-
-nsc_svc_t *
-nsc_register_svc(char *name, void (*service_fn)(intptr_t))
-{
- nsc_service_t *sp, *new;
- nsc_svc_t *svc;
-
- new = nsc_kmem_zalloc(sizeof (*new), KM_SLEEP, 0);
- if (new == NULL)
- return (NULL);
-
- svc = nsc_kmem_zalloc(sizeof (*svc), KM_SLEEP, 0);
- if (svc == NULL) {
- nsc_kmem_free(new, sizeof (*new));
- return (NULL);
- }
-
- mutex_enter(&_nsc_svc_mutex);
-
- for (sp = _nsc_services; sp != NULL; sp = sp->s_next)
- if (strcmp(name, sp->s_name) == 0)
- break;
-
- if (sp == NULL) {
- sp = new;
- sp->s_name = nsc_strdup(name);
- if (sp->s_name == NULL) {
- mutex_exit(&_nsc_svc_mutex);
- nsc_kmem_free(new, sizeof (*new));
- nsc_kmem_free(svc, sizeof (*svc));
- return (NULL);
- }
-
- rw_init(&sp->s_rwlock, NULL, RW_DRIVER, NULL);
- sp->s_next = _nsc_services;
- _nsc_services = sp;
- }
-
- rw_enter(&sp->s_rwlock, RW_WRITER);
-
- svc->svc_fn = service_fn;
- svc->svc_svc = sp;
-
- if (svc->svc_fn != NULL) {
- svc->svc_next = sp->s_servers;
- sp->s_servers = svc;
- } else {
- svc->svc_next = sp->s_clients;
- sp->s_clients = svc;
- }
-
- rw_exit(&sp->s_rwlock);
- mutex_exit(&_nsc_svc_mutex);
-
- if (sp != new)
- nsc_kmem_free(new, sizeof (*new));
-
- return (svc);
-}
-
-
-int
-nsc_unregister_svc(nsc_svc_t *svc)
-{
- nsc_service_t *sp, **spp;
- nsc_svc_t **svcp;
-
- if (svc == NULL)
- return (EINVAL);
-
- sp = svc->svc_svc;
- if (sp == NULL)
- return (EINVAL);
-
- mutex_enter(&_nsc_svc_mutex);
- rw_enter(&sp->s_rwlock, RW_WRITER);
-
- svcp = (svc->svc_fn == NULL) ? &sp->s_clients : &sp->s_servers;
- for (; *svcp; svcp = &((*svcp)->svc_next))
- if (svc == (*svcp))
- break;
-
- if (*svcp)
- (*svcp) = svc->svc_next;
-
- nsc_kmem_free(svc, sizeof (*svc));
-
- if (sp->s_servers == NULL && sp->s_clients == NULL) {
- for (spp = &_nsc_services; *spp; spp = &((*spp)->s_next))
- if ((*spp) == sp)
- break;
-
- if (*spp)
- (*spp) = sp->s_next;
-
- rw_exit(&sp->s_rwlock);
- mutex_exit(&_nsc_svc_mutex);
-
- rw_destroy(&sp->s_rwlock);
- nsc_strfree(sp->s_name);
-
- nsc_kmem_free(sp, sizeof (*sp));
- return (0);
- }
-
- rw_exit(&sp->s_rwlock);
- mutex_exit(&_nsc_svc_mutex);
-
- return (0);
-}
-
-
-int
-nsc_call_svc(nsc_svc_t *svc, intptr_t arg)
-{
- nsc_service_t *sp;
- nsc_svc_t *svcp;
- int found;
-
- if (svc == NULL)
- return (EINVAL);
-
- sp = svc->svc_svc;
- if (sp == NULL)
- return (EINVAL);
-
- rw_enter(&sp->s_rwlock, RW_READER);
-
- found = (sp->s_servers != NULL);
-
- for (svcp = sp->s_servers; svcp; svcp = svcp->svc_next)
- (*svcp->svc_fn)(arg);
-
- rw_exit(&sp->s_rwlock);
-
- if (found == 0)
- return (ENOSYS);
-
- return (0);
-}
diff --git a/usr/src/uts/common/avs/ns/nsctl/nsc_gen.h b/usr/src/uts/common/avs/ns/nsctl/nsc_gen.h
deleted file mode 100644
index fc5ec68c48..0000000000
--- a/usr/src/uts/common/avs/ns/nsctl/nsc_gen.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _NSC_GEN_H
-#define _NSC_GEN_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef __NSC_GEN__
-Error: Illegal #include - private file.
-#endif
-
-
-/*
- * Global resource map.
- */
-
-#define _NSC_MAXNAME 20
-
-typedef struct nsc_rmmap_s {
- char name[_NSC_MAXNAME]; /* Description */
- int32_t offset; /* Offset into arena */
- uint32_t size; /* Length of area */
- int32_t inuse; /* Bitmap of nodes using area */
- int32_t pad[2]; /* For future expansion */
-} nsc_rmmap_t;
-
-
-#ifdef _KERNEL
-#include <sys/nsctl/nsc_mem.h>
-
-extern kmutex_t _nsc_global_lock;
-extern int _nsc_global_lock_init;
-
-extern int _nsc_rmmap_init(nsc_rmmap_t *, char *, int, size_t, ulong_t);
-extern ulong_t _nsc_rmmap_alloc(nsc_rmmap_t *, char *, size_t, void (*)());
-extern void _nsc_rmmap_free(nsc_rmmap_t *, char *, nsc_mem_t *);
-extern size_t _nsc_rmmap_size(nsc_rmmap_t *, char *);
-extern size_t _nsc_rmmap_avail(nsc_rmmap_t *);
-
-extern nsc_rmmap_t *_nsc_global_nvmemmap_lookup(nsc_rmmap_t *);
-extern void nsc_cm_errhdlr(void *, void *, size_t, int);
-extern caddr_t _nsc_rm_nvmem_base;
-
-/*
- * Inter-module function (callback) services.
- */
-
-typedef struct nsc_svc_s {
- struct nsc_svc_s *svc_next; /* linked list */
- struct nsc_service_s *svc_svc; /* back link */
- void (*svc_fn)(intptr_t); /* service function, or NULL (client) */
-} nsc_svc_t;
-
-typedef struct nsc_service_s {
- struct nsc_service_s *s_next; /* linked list */
- char *s_name; /* name of service */
- nsc_svc_t *s_servers; /* providers of the service */
- nsc_svc_t *s_clients; /* clients of the service */
- krwlock_t s_rwlock; /* lock */
-} nsc_service_t;
-
-extern void _nsc_init_svc(void);
-extern void _nsc_deinit_svc(void);
-
-#endif /* _KERNEL */
-
-
-/*
- * ncall usage (NCALL_NSC .. NCALL_NSC+9)
- */
-
-/* inter-node setval */
-#define NSC_SETVAL (NCALL_NSC + 1)
-#define NSC_SETVAL_ALL (NCALL_NSC + 2)
-
-#define NSC_UNUSED3 (NCALL_NSC + 3)
-#define NSC_UNUSED4 (NCALL_NSC + 4)
-
-/* ncall-io io provider */
-#define NSC_NCIO_PARTSIZE (NCALL_NSC + 5)
-#define NSC_NCIO_READ (NCALL_NSC + 6)
-#define NSC_NCIO_WRITE (NCALL_NSC + 7)
-
-#define NSC_UNUSED8 (NCALL_NSC + 8)
-#define NSC_UNUSED9 (NCALL_NSC + 9)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _NSC_GEN_H */
diff --git a/usr/src/uts/common/avs/ns/nsctl/nsc_ioctl.h b/usr/src/uts/common/avs/ns/nsctl/nsc_ioctl.h
deleted file mode 100644
index 2fffd75d20..0000000000
--- a/usr/src/uts/common/avs/ns/nsctl/nsc_ioctl.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _NSC_IOCTL_H
-#define _NSC_IOCTL_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/dkio.h>
-#include <sys/vtoc.h>
-#ifdef DKIOCPARTITION
-#include <sys/efi_partition.h>
-#endif
-
-/*
- * Ioctl definitions for Storage Device.
- */
-
-#define _NSC_(x) (('S'<<16)|('D'<<8)|(x))
-
-#define NSCIOC_OPEN _NSC_(1)
-#define NSCIOC_RESERVE _NSC_(2)
-#define NSCIOC_RELEASE _NSC_(3)
-#define NSCIOC_PARTSIZE _NSC_(4)
-#define NSCIOC_FREEZE _NSC_(5)
-#define NSCIOC_UNFREEZE _NSC_(6)
-#define NSCIOC_ISFROZEN _NSC_(7)
-#define NSCIOC_POWERMSG _NSC_(8) /* UPS/PCU power state */
-#define NSCIOC_NSKERND _NSC_(9)
-#define NSCIOC_GLOBAL_SIZES _NSC_(10) /* size of RM segs */
-#define NSCIOC_GLOBAL_DATA _NSC_(11)
-#define NSCIOC_NVMEM_CLEAN _NSC_(12) /* mark nvm nsc_global clean */
-#define NSCIOC_NVMEM_CLEANF _NSC_(13) /* force mark clean */
-#define NSCIOC_BSIZE _NSC_(14) /* get partition size */
-
-
-/*
- * Structure definitions.
- */
-
-
-struct nscioc_open {
- char path[NSC_MAXPATH]; /* Pathname */
- int flag; /* Flags */
- int mode; /* Open modes */
- int pad[15];
-};
-
-
-struct nscioc_partsize {
- uint64_t partsize;
-};
-
-
-struct nskernd {
- uint64_t data1;
- uint64_t data2;
- char char1[NSC_MAXPATH];
- char char2[NSC_MAXPATH];
- int command;
-};
-
-
-struct nscioc_bsize {
- uint64_t vtoc; /* (struct vtoc *) */
- uint64_t dki_info; /* (struct dk_cinfo *) */
- uint64_t raw_fd; /* dev_t of slice/partition */
- uint64_t p64; /* (struct partition64 *) */
- int efi; /* do we have an EFI partition table? */
-};
-
-
-#ifdef _KERNEL
-extern int nskernd_command(intptr_t, int, int *);
-extern int nskern_bsize(struct nscioc_bsize *, int *);
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _NSC_IOCTL_H */
diff --git a/usr/src/uts/common/avs/ns/nsctl/nsc_mem.c b/usr/src/uts/common/avs/ns/nsctl/nsc_mem.c
deleted file mode 100644
index 81fafd8971..0000000000
--- a/usr/src/uts/common/avs/ns/nsctl/nsc_mem.c
+++ /dev/null
@@ -1,939 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/cmn_err.h>
-#include <sys/ksynch.h>
-#include <sys/kmem.h>
-#include <sys/map.h>
-#include <sys/errno.h>
-#include <sys/ddi.h>
-
-
-#define __NSC_GEN__
-#include "nsc_dev.h"
-#include "nsc_gen.h"
-#include "nsc_mem.h"
-#include "../nsctl.h"
-#ifdef DS_DDICT
-#include "../contract.h"
-#endif
-
-
-static size_t _nsc_rm_size;
-caddr_t _nsc_rm_base;
-caddr_t _nsc_rm_nvmem_base;
-size_t _nsc_rmhdr_size;
-
-static kmutex_t _nsc_mem_lock;
-static nsc_mem_t *_nsc_anon_mem;
-static nsc_mem_t *_nsc_rmhdr_mem;
-
-nsc_mem_t *_nsc_mem_top;
-
-nsc_rmhdr_t *_nsc_rmhdr_ptr;
-nsc_rmmap_t *_nsc_global_map;
-nsc_mem_t *_nsc_local_mem;
-
-static void *_nsc_mem_alloc(size_t *, int, nsc_mem_t *);
-static void *_nsc_rm_alloc(size_t *, nsc_mem_t *);
-static int _nsc_mem_free(void *, size_t);
-static int _nsc_rm_free(void *, size_t);
-static size_t _nsc_rm_avail(nsc_mem_t *);
-
-extern void nscsetup(void);
-extern void _nsc_mark_pages(caddr_t, size_t, int);
-extern int _nsc_lock_all_rm(void);
-extern void _nsc_unlock_all_rm(void);
-extern void _nsc_set_max_devices(int);
-
-/*
- * void
- * _nsc_init_mem (void)
- * Initialise memory allocation system.
- *
- * Calling/Exit State:
- * Called at driver initialisation time to allocate necessary
- * data structures.
- */
-void
-_nsc_init_mem()
-{
- mutex_init(&_nsc_mem_lock, NULL, MUTEX_DRIVER, NULL);
-
- _nsc_anon_mem = nsc_register_mem("anon:kmem", NSC_MEM_LOCAL, 0);
- _nsc_local_mem = nsc_register_mem("nsctl:kmem", NSC_MEM_LOCAL, 0);
-
- if (!_nsc_anon_mem)
- cmn_err(CE_PANIC, "nsctl: nsc_init_mem");
-}
-
-
-/*
- * void
- * _nsc_deinit_mem (void)
- * De-initialise memory alloation system.
- *
- * Calling/Exit State:
- * Called at driver unload time to de-allocate
- * resources.
- */
-
-
-void
-_nsc_deinit_mem()
-{
- if (_nsc_rm_nvmem_base)
- nsc_kmem_free(_nsc_rm_base, _nsc_rmhdr_size);
-
- _nsc_rm_nvmem_base = NULL;
- _nsc_rm_base = NULL;
-}
-
-/*
- * int
- * _nsc_clear_dirty(int force)
- * mark the global area clean by clearing the header dirty bit number.
- *
- * returns 0 if successfully cleared, valid errno otherwise
- *
- * this function should only be called at system shutdown.
- */
-/*ARGSUSED*/
-int
-_nsc_clear_dirty(int force)
-{
- int rc = 0;
-
-#ifdef DEBUG
- ulong_t longzeros = 0;
- if (force) {
- if (_nsc_rm_nvmem_base) {
- if (nsc_commit_mem((void *)&longzeros,
- (void *)&((nsc_rmhdr_t *)
- _nsc_rm_nvmem_base)->rh_dirty,
- sizeof (ulong_t), nsc_cm_errhdlr) < 0) {
- cmn_err(CE_WARN,
- "!nsctl: _nsc_clear_magic: "
- "hdr force clear failed 0x%p",
- (void *)_nsc_rm_nvmem_base);
- } else {
- cmn_err(CE_WARN,
- "!nsctl: _nsc_clear_magic: "
- "hdr force cleared 0x%p",
- (void *)_nsc_rm_nvmem_base);
- _nsc_rmhdr_ptr->rh_dirty = 0;
- }
-
- return (0);
- } else
- return (EINVAL);
- }
-
- if (_nsc_rm_nvmem_base) {
- if (_nsc_global_lock_init) {
- mutex_enter(&_nsc_global_lock);
- if (!_nsc_check_mapinuse()) {
- if (nsc_commit_mem((void *)&longzeros,
- (void *)&((nsc_rmhdr_t *)
- _nsc_rm_nvmem_base)->rh_dirty,
- sizeof (ulong_t), nsc_cm_errhdlr) < 0) {
- cmn_err(CE_WARN,
- "!nsctl: _nsc_clear_magic: "
- "hdr clear failed 0x%p",
- (void *)_nsc_rm_nvmem_base);
- } else {
- cmn_err(CE_WARN,
- "!nsctl: _nsc_clear_magic: "
- "hdr cleared 0x%p",
- (void *)_nsc_rm_nvmem_base);
- _nsc_rmhdr_ptr->rh_dirty = 0;
- }
- rc = 0;
- } else {
- cmn_err(CE_WARN,
- "!nsctl: _nsc_clear_magic: "
- "global area in use. cannot clear magic");
- rc = EBUSY;
- }
- mutex_exit(&_nsc_global_lock);
- } else {
- cmn_err(CE_WARN,
- "!nsctl: _nsc_clear_magic: cannot clear magic");
- rc = EINVAL;
- }
- } else
- rc = EINVAL;
-#else
-
- rc = ENOTTY;
-
-#endif /* DEBUG */
-
- return (rc);
-}
-
-/*
- * int
- * _nsc_check_mapinuse()
- * check if any global maps are still inuse;
- *
- * return 1 if any non-nsctl map is in use, 0 otherwise
- * should be called with _nsc_global_lock held
- *
- * for nvmem support. if a client of nsctl is still
- * using the global maps then the global area will not
- * be marked clean.
- */
-int
-_nsc_check_mapinuse(void)
-{
- nsc_rmmap_t *rmap = _nsc_rmhdr_ptr->map;
- nsc_rmmap_t *rmapend;
-
- rmapend = (nsc_rmmap_t *)
- ((char *)_nsc_rmhdr_ptr + _nsc_rmhdr_ptr->size);
-
- for (; rmap < rmapend; ++rmap)
- if ((rmap->inuse) && !(_nsc_is_nsctl_map(rmap->name)))
- return (1);
-
- return (0);
-
-}
-
-/* names of maps in the global area that belong to nsctl */
-static char *nsctl_mapnames[] = {
- "nsc_global",
- "nsc_lock"
-};
-
-int
-_nsc_is_nsctl_map(char *mapname)
-{
- int i;
-
- for (i = 0; i < sizeof (nsctl_mapnames)/sizeof (char *); ++i)
- if (strncmp(mapname, nsctl_mapnames[i], _NSC_MAXNAME) == 0)
- return (1);
-
- return (0);
-}
-
-
-/*
- * nsc_mem_t *
- * nsc_register_mem(char *name, int type, int flag)
- * Register a category of memory usage.
- *
- * Calling/Exit State:
- * Returns a token for use in future calls to nsc_kmem_alloc.
- * type is NSC_MEM_LOCAL, or NSC_MEM_GLOBAL.
- * flag is passed through to kmem_alloc on allocate.
- *
- * Description:
- * The parameters associated with a category can be changed
- * by making a subsequent call to nsc_register_mem.
- */
-nsc_mem_t *
-nsc_register_mem(char *name, int type, int flag)
-{
- nsc_mem_t *mp, *new;
-
- new = kmem_zalloc(sizeof (*new), KM_NOSLEEP);
-
- mutex_enter(&_nsc_mem_lock);
-
- for (mp = _nsc_mem_top; mp; mp = mp->next)
- if (strcmp(mp->name, name) == 0)
- break;
-
- if (!mp && !(mp = new)) {
- mutex_exit(&_nsc_mem_lock);
- return (NULL);
- }
-
- mp->type = type;
- mp->flag = flag;
-
- mp->hwm = mp->used;
- mp->pagehwm = mp->pages;
- mp->nalloc -= mp->nfree;
- mp->nfree = 0;
-
- if (!mp->name) {
- mp->name = name;
- mp->next = _nsc_mem_top;
- _nsc_mem_top = mp;
- }
-
- mutex_exit(&_nsc_mem_lock);
-
- if (new && mp != new)
- kmem_free(new, sizeof (*new));
-
- return (mp);
-}
-
-
-/*
- * void
- * nsc_unregister_mem(nsc_mem_t *)
- * Un-register a category of memory usage.
- *
- * Description:
- * The specified category is un-registered. For correct
- * operation this should only be called when all memory
- * associated with the category has been free'd.
- */
-void
-nsc_unregister_mem(nsc_mem_t *mp)
-{
- nsc_mem_t **mpp;
-
- if (!mp)
- return;
-
- mutex_enter(&_nsc_mem_lock);
-
- for (mpp = &_nsc_mem_top; *mpp; mpp = &(*mpp)->next)
- if (*mpp == mp)
- break;
-
- if (*mpp != NULL) {
- *mpp = mp->next;
- kmem_free(mp, sizeof (*mp));
- }
-
- mutex_exit(&_nsc_mem_lock);
-}
-
-/*
- * void
- * _nsc_global_setup
- * Setup global variables.
- *
- * Calling/Exit State:
- * Called to setup the global header.
- */
-void
-_nsc_global_setup()
-{
- nsc_rmhdr_t *hdr = (void *)_nsc_rm_base;
- size_t size;
-
- if (!hdr || !_nsc_global_lock_init || _nsc_rmhdr_ptr)
- return;
-
- mutex_enter(&_nsc_global_lock);
-
- if (!hdr->magic || (_nsc_rm_nvmem_base && !hdr->rh_dirty)) {
- size = sizeof (nsc_rmhdr_t) +
- (sizeof (nsc_rmmap_t) * (_NSC_GLSLOT - 1));
-
- size = (size + _NSC_GLALIGN) & ~_NSC_GLALIGN;
- bzero(_nsc_rm_base, size);
-
- hdr->magic = _NSCTL_HDRMAGIC;
- hdr->ver = _NSCTL_HDRVER3;
- hdr->size = size;
- hdr->maxdev = nsc_max_devices();
-
- hdr->map[0].inuse = _NSC_GLSLOT;
- if (_nsc_rm_nvmem_base) {
- if (hdr->rh_dirty) { /* corrupted */
- cmn_err(CE_WARN,
- "!nsctl: _nsc_global_setup: nv bad header");
- mutex_exit(&_nsc_global_lock);
- return;
- }
- if (nsc_commit_mem((void *)_nsc_rm_base,
- (void *)_nsc_rm_nvmem_base,
- size, nsc_cm_errhdlr) < 0)
- cmn_err(CE_WARN, "!_nsc_global_setup: "
- "nvmem header not updated");
- }
- }
-
- _nsc_rmhdr_ptr = hdr;
- mutex_exit(&_nsc_global_lock);
-
- if (hdr->magic != _NSCTL_HDRMAGIC || (hdr->ver != _NSCTL_HDRVER &&
- hdr->ver != _NSCTL_HDRVER3)) {
- cmn_err(CE_WARN, "!nsctl: _nsc_global_setup: bad header");
- return;
- }
-
- if (hdr->ver == _NSCTL_HDRVER3 && hdr->maxdev != nsc_max_devices()) {
- _nsc_set_max_devices(hdr->maxdev);
- cmn_err(CE_WARN,
- "!nsctl: _nsc_global_setup: setting nsc_max_devices to %d",
- hdr->maxdev);
- }
-
- if (!_nsc_rmmap_init(hdr->map, "nsc_global", _NSC_GLSLOT,
- _nsc_rm_size - hdr->size, hdr->size)) {
- cmn_err(CE_WARN,
- "!nsctl: _nsc_global_setup: global map init failed");
- return;
- }
-
- _nsc_global_map = hdr->map;
-
- (void) nsc_kmem_alloc(hdr->size, 0, _nsc_rmhdr_mem);
-}
-
-/*
- * int
- * _nsc_need_global_mem ()
- * Expected global memory usage.
- *
- * Calling/Exit State:
- * Returns the amount of global memory expected to be
- * used by internal data structures.
- *
- * Remarks:
- * This is provided purely as a configuration aid to
- * systems without global memory and as such is not
- * declared in nsctl.h.
- */
-int
-_nsc_need_global_mem()
-{
- int size = sizeof (nsc_rmhdr_t) +
- (sizeof (nsc_rmmap_t) * (_NSC_GLSLOT - 1));
-
- size = (size + _NSC_GLALIGN) & ~_NSC_GLALIGN;
- return (size);
-}
-
-
-/*
- * void *
- * nsc_kmem_alloc (size_t size, int flag, nsc_mem_t *mem)
- * Allocate memory of the specified type.
- *
- * Calling/Exit State:
- * Returns a pointer to a word aligned area of memory.
- * If mem is zero then an anonymous category is used.
- *
- * Description:
- * Allocates the required memory and updates the usage
- * statistics stored in mem.
- *
- * Remarks:
- * VME memory is guaranteed to be eight byte aligned.
- */
-void *
-nsc_kmem_alloc(size_t size, int flag, nsc_mem_t *mem)
-{
- void *vp;
-
- if (!mem)
- mem = _nsc_anon_mem;
-
- if ((vp = _nsc_mem_alloc(&size, flag, mem)) == NULL)
- return (NULL);
-
- mutex_enter(&_nsc_mem_lock);
-
- mem->nalloc++;
- mem->used += size;
- mem->pages += btopr(size);
-
- if (mem->used > mem->hwm)
- mem->hwm = mem->used;
- if (mem->pages > mem->pagehwm)
- mem->pagehwm = mem->pages;
-
- mutex_exit(&_nsc_mem_lock);
- return (vp);
-}
-
-
-/*
- * void *
- * _nsc_mem_alloc (size_t *sizep, int flag, nsc_mem_t *mem)
- * Allocate memory of the specified type.
- *
- * Calling/Exit State:
- * Returns a pointer to a word aligned area of memory.
- *
- * Description:
- * Uses the type field to determine whether to allocate RM,
- * VME or kernel memory. For types other then RM a copy of
- * mem is stored immediately prior to the returned area.
- * size is updated to reflect the header.
- *
- * Remarks:
- * A two word header is user for VME memory to ensure
- * eight byte alignment.
- */
-static void *
-_nsc_mem_alloc(size_t *sizep, int flag, nsc_mem_t *mem)
-{
- size_t size = *sizep;
- void *vp;
-
- if (mem->type & NSC_MEM_GLOBAL)
- return (_nsc_rm_alloc(sizep, mem));
-
- flag |= mem->flag;
- size += sizeof (nsc_mem_t *);
-
- if (flag & KM_NOSLEEP)
- flag &= ~KM_SLEEP;
-
- vp = kmem_alloc(size, flag);
- if (!vp)
- return (NULL);
-
- *sizep = size;
-
- *(nsc_mem_t **)vp = mem;
-
- return (void *)((nsc_mem_t **)vp + 1);
-}
-
-
-/*
- * void
- * nsc_kmem_free (void *addr, size_t size)
- * Free a previously allocated area of memory.
- *
- * Calling/Exit State:
- * The memory specified by addr is returned to the free pool.
- *
- * Description:
- * Updates the usage statistics appropriately.
- */
-void
-nsc_kmem_free(void *addr, size_t size)
-{
- caddr_t caddr = (caddr_t)addr;
- caddr_t rm_base;
- int rc;
-
- if (_nsc_rm_nvmem_base)
- rm_base = _nsc_rm_nvmem_base;
- else
- rm_base = _nsc_rm_base;
-
- if (rm_base <= caddr && caddr < rm_base + _nsc_rm_size)
- rc = _nsc_rm_free(addr, size);
- else
- rc = _nsc_mem_free(addr, size);
-
- if (rc < 0)
- cmn_err(CE_PANIC, "nsctl: nsc_kmem_free: invalid free");
-}
-
-
-/*
- * nsc_mem_t *
- * _nsc_mem_free (void *addr, size_t size)
- * Free a previously allocated area of memory.
- *
- * Calling/Exit State:
- * Frees the VME or kernel memory at addr and updates
- * the associated mem structure.
- */
-static int
-_nsc_mem_free(void *addr, size_t size)
-{
- nsc_mem_t *mp, *tp;
-
- addr = (void *)((nsc_mem_t **)addr - 1);
- size += sizeof (nsc_mem_t *);
-
- mutex_enter(&_nsc_mem_lock);
-
- mp = *(nsc_mem_t **)addr;
-
- for (tp = _nsc_mem_top; tp; tp = tp->next)
- if (tp == mp)
- break;
-
- if (tp == NULL) {
- mutex_exit(&_nsc_mem_lock);
- return (-1);
- }
-
- mp->nfree++;
- mp->used -= size;
- mp->pages -= btopr(size);
-
- *(nsc_mem_t **)addr = NULL;
-
- mutex_exit(&_nsc_mem_lock);
-
- kmem_free(addr, size);
-
- return (0);
-}
-
-
-/*
- * void *
- * nsc_kmem_zalloc(size_t size, int flags, nsc_mem_t *mem)
- * Allocate and zero memory.
- *
- * Calling/Exit State:
- * Same as nsc_kmem_alloc(), except that the memory is zeroed.
- */
-void *
-nsc_kmem_zalloc(size_t size, int flag, nsc_mem_t *mem)
-{
- void *vp = nsc_kmem_alloc(size, flag, mem);
-
- if (vp)
- bzero((char *)vp, size);
-
- return (vp);
-}
-
-
-/*
- * void
- * nsc_mem_sizes (nsc_mem_t *mem, size_t *usedp, size_t *hwmp, size_t *reqp)
- * Access size information for category.
- *
- * Calling/Exit State:
- * If the corresponding pointer is non-zero returns
- * respectively, the number of bytes currently allocated, the
- * high water mark in bytes and an estimate of the number of
- * bytes needed for the category assuming that each request
- * is satisfied from a different page.
- *
- * Remarks:
- * The reqp parameter is used to estimate the amount of special
- * purpose memory needed to support the category.
- */
-void
-nsc_mem_sizes(nsc_mem_t *mem, size_t *usedp, size_t *hwmp, size_t *reqp)
-{
- if (!mem)
- mem = _nsc_anon_mem;
-
- if (usedp)
- *usedp = mem->used;
- if (hwmp)
- *hwmp = mem->hwm;
- if (reqp)
- *reqp = (size_t)ptob(mem->pagehwm);
-}
-
-
-/*
- * size_t
- * nsc_mem_avail (nsc_mem_t *mem)
- * Memory available for use by category.
- *
- * Calling/Exit State:
- * Returns the number of bytes of memory currently
- * available for use by the category.
- *
- * Remarks:
- * Reduces the memory available to allow for one unit
- * of allocation overhead.
- *
- * Only implemented for NSC_MEM_GLOBAL.
- */
-size_t
-nsc_mem_avail(nsc_mem_t *mem)
-{
- if (!mem)
- mem = _nsc_anon_mem;
-
- if (mem->type & NSC_MEM_GLOBAL)
- return (_nsc_rm_avail(mem));
-
-#ifdef DEBUG
- cmn_err(CE_WARN, "!nsc_mem_avail: called for non-global memory!");
-#endif
-
- return (0);
-}
-
-
-/*
- * void
- * _nsc_global_zero (ulong_t offset, size_t size)
- * Zero global memory.
- *
- * Description:
- * Zeroes an area of global memory at the specified offset.
- */
-
-#define ZSIZE 4096
-static char _nsc_nvmem_zeroes[ZSIZE];
-
-static void
-_nsc_global_zero(ulong_t offset, size_t size)
-{
- int i;
- int rc;
- int failed = 0;
-
- if (_nsc_rm_nvmem_base) {
- for (i = 0; i < (int)(size / ZSIZE); ++i) {
- rc = nsc_commit_mem((void *)_nsc_nvmem_zeroes,
- (void *)(_nsc_rm_nvmem_base + offset +
- i * ZSIZE),
- ZSIZE, nsc_cm_errhdlr);
-
- if (rc < 0)
- ++failed;
-
- }
- rc = nsc_commit_mem((void *)_nsc_nvmem_zeroes,
- (void *)(_nsc_rm_nvmem_base + offset + i * ZSIZE),
- size % ZSIZE,
- nsc_cm_errhdlr);
- if ((rc < 0) || failed)
- cmn_err(CE_WARN, "!_nsc_global_zero: clear mem failed");
- return;
- }
-
- if (_nsc_rm_base)
- bzero(_nsc_rm_base + offset, size);
-}
-
-
-/*
- * void *
- * _nsc_rm_alloc (size_t *sizep, nsc_mem_t *mem)
- * Allocate next available section of RM.
- *
- * Calling/Exit State:
- * Returns a pointer to an area of global memory.
- *
- * Description:
- * Only one allocation request is allowed for each
- * category of global memory.
- */
-static void *
-_nsc_rm_alloc(size_t *sizep, nsc_mem_t *mem)
-{
- size_t avail, size = (*sizep);
- ulong_t offset = 0;
- caddr_t retaddr;
-
- if (!_nsc_global_map) {
- cmn_err(CE_WARN, "!_nsc_rm_alloc: no map");
- return (NULL);
- }
-
- mutex_enter(&_nsc_mem_lock);
-
- if (mem->base || mem->pend) {
- mutex_exit(&_nsc_mem_lock);
- cmn_err(CE_WARN, "!_nsc_rm_alloc: invalid alloc");
- return (NULL);
- }
-
- mem->pend = 1;
- mutex_exit(&_nsc_mem_lock);
-
- size = (size + _NSC_GLALIGN) & ~_NSC_GLALIGN;
-
- /* CONSTCOND */
-
- while (1) {
- if (strcmp(mem->name, "nsctl:rmhdr") == 0)
- break;
-
- offset = _nsc_rmmap_alloc(_nsc_global_map,
- mem->name, size, _nsc_global_zero);
-
- if (offset)
- break;
-
- if (mem->type & NSC_MEM_RESIZE) {
- avail = _nsc_rmmap_size(_nsc_global_map, mem->name);
-
- if (avail && avail != size) {
- size = avail;
- continue;
- }
- }
-
- mem->pend = 0;
- cmn_err(CE_WARN,
- "!_nsc_rm_alloc: alloc %ld bytes - %ld available",
- size, _nsc_rm_avail(mem));
- return (NULL);
- }
-
- _nsc_mark_pages(_nsc_rm_base + offset, size, 1);
-
- if (_nsc_rm_nvmem_base)
- retaddr = _nsc_rm_nvmem_base + offset;
- else
- retaddr = _nsc_rm_base + offset;
-
- mutex_enter(&_nsc_mem_lock);
-
- mem->base = retaddr;
- mem->pend = 0;
-
- mutex_exit(&_nsc_mem_lock);
-
- (*sizep) = size;
- return (retaddr);
-}
-
-
-/*
- * nsc_mem_t *
- * _nsc_rm_free (void *addr, size_t size)
- * Free an area of RM.
- *
- * Calling/Exit State:
- * Returns 0 on success, -1 on failure.
- */
-static int
-_nsc_rm_free(void *addr, size_t size)
-{
- caddr_t caddr = (caddr_t)addr;
- nsc_mem_t *mp;
-
- mutex_enter(&_nsc_mem_lock);
-
- for (mp = _nsc_mem_top; mp; mp = mp->next)
- if (mp->base == caddr)
- break;
-
- if (!mp) {
- mutex_exit(&_nsc_mem_lock);
- return (-1);
- }
-
- mp->nfree++;
- mp->used -= size;
- mp->pages -= btopr(size);
- mp->pend = 1;
-
- if (!mp->used)
- mp->base = 0;
-
- mutex_exit(&_nsc_mem_lock);
-
- if (_nsc_global_map)
- _nsc_rmmap_free(_nsc_global_map, mp->name, mp);
-
- _nsc_mark_pages(addr, size, 0);
-
- mp->pend = 0;
- return (0);
-}
-
-
-/*
- * static size_t
- * _nsc_rm_avail (mem)
- * Amount of RM available.
- *
- * Calling/Exit State:
- * Returns 0 if the specified category has already been
- * allocated. Returns the size of the region if it already
- * exists, otherwise the number of bytes of global memory
- * available.
- */
-static size_t
-_nsc_rm_avail(nsc_mem_t *mem)
-{
- size_t size;
-
- if (!_nsc_global_map || mem->base || mem->pend)
- return (0);
-
- if ((size = _nsc_rmmap_size(_nsc_global_map, mem->name)) != 0)
- return (size);
-
- return (_nsc_rmmap_avail(_nsc_global_map));
-}
-
-
-/*
- * nvram support
- * given a map address, return the address of the copy
- * in nvram.
- * Assumes that _nsc_rm_nvmem_base is valid.
- */
-nsc_rmmap_t *
-_nsc_global_nvmemmap_lookup(nsc_rmmap_t *hp)
-{
- size_t offset;
-
- /* LINTED */
- offset = (caddr_t)hp - _nsc_rm_base;
- return ((nsc_rmmap_t *)(_nsc_rm_nvmem_base + offset));
-}
-
-int
-_nsc_get_global_sizes(void *arg, int *rvp)
-{
- if (!_nsc_rmhdr_ptr)
- return (EINVAL);
-
- if (copyout(&_nsc_rmhdr_ptr->size, arg,
- sizeof (_nsc_rmhdr_ptr->size)) < 0)
- return (EFAULT);
-
- *rvp = 0;
- return (0);
-}
-
-int
-_nsc_get_global_data(void *arg, int *rvp)
-{
- size_t size;
-
- if (!_nsc_rmhdr_ptr)
- return (EINVAL);
-
- size = _nsc_rmhdr_ptr->size;
-
- if (copyout(_nsc_rmhdr_ptr, arg, size) < 0)
- return (EFAULT);
-
- if (_nsc_rm_nvmem_base) {
- char *taddr;
-
- if ((taddr = kmem_alloc(size, KM_NOSLEEP)) == NULL)
- return (ENOMEM);
-
- if (copyout(taddr, (char *)arg + size, size) < 0) {
- kmem_free(taddr, size);
- return (EFAULT);
- }
-
- kmem_free(taddr, size);
- }
-
- *rvp = 0;
- return (0);
-}
diff --git a/usr/src/uts/common/avs/ns/nsctl/nsc_mem.h b/usr/src/uts/common/avs/ns/nsctl/nsc_mem.h
deleted file mode 100644
index 08fce89029..0000000000
--- a/usr/src/uts/common/avs/ns/nsctl/nsc_mem.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _NSC_MEM_H
-#define _NSC_MEM_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef __NSC_GEN__
-Error: Illegal #include - private file.
-#endif
-
-
-/*
- * Macro definitions.
- */
-
-
-/*
- * Definition of control structure.
- */
-typedef struct nsc_mem_s {
- struct nsc_mem_s *next; /* Link to next type */
- char *name; /* Description */
- int type; /* Memory type */
- int flag; /* Allocation flags */
- size_t used; /* Current usage */
- size_t hwm; /* High Water Mark */
- int pages; /* Usage in pages */
- int pagehwm; /* Page High Water Mark */
- caddr_t base; /* Base address of RM area */
- int nalloc; /* Number of allocates */
- int nfree; /* Number of frees */
- int pend; /* Operation pending */
-} nsc_mem_t;
-
-
-/*
- * Definition of global memory header
- */
-
-#define _NSCTL_HDRMAGIC 0x5344474c /* Magic number for header */
-#define _NSCTL_HDRVER 2 /* Version number for header */
-#define _NSCTL_HDRVER3 3 /* Version number for header */
-#define _NSC_GLSLOT 125 /* Number of global slots */
-#define _NSC_GLALIGN 4095 /* Alignment between areas */
-
-
-typedef struct nsc_rmhdr_s {
- uint32_t magic; /* Magic number */
- uint32_t ver; /* Version number of header */
- uint32_t size; /* Size of header section */
- int32_t rh_dirty; /* dirty bit for nvmem */
- int32_t maxdev; /* Configured nsc_max_devices */
- int32_t pad[14]; /* Future expansion */
- nsc_rmmap_t map[1]; /* Start of map array */
-} nsc_rmhdr_t;
-
-extern nsc_rmmap_t *_nsc_global_nvmemmap_lookup(nsc_rmmap_t *);
-
-extern int _nsc_get_global_sizes(void *, int *);
-extern int _nsc_get_global_data(void *, int *);
-extern int _nsc_clear_dirty(int);
-extern int _nsc_check_mapinuse(void);
-extern int _nsc_is_nsctl_map(char *);
-
-extern caddr_t _nsc_rm_base;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _NSC_MEM_H */
diff --git a/usr/src/uts/common/avs/ns/nsctl/nsc_ncallio.c b/usr/src/uts/common/avs/ns/nsctl/nsc_ncallio.c
deleted file mode 100644
index c39574e95e..0000000000
--- a/usr/src/uts/common/avs/ns/nsctl/nsc_ncallio.c
+++ /dev/null
@@ -1,757 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/ksynch.h>
-#include <sys/errno.h>
-#include <sys/file.h>
-#include <sys/open.h>
-#include <sys/cred.h>
-#include <sys/kmem.h>
-#include <sys/ddi.h>
-
-#include <sys/ncall/ncall.h>
-
-#define __NSC_GEN__
-#include "nsc_dev.h"
-#include "nsc_ncallio.h"
-#include "../nsctl.h"
-
-
-extern nsc_mem_t *_nsc_local_mem;
-
-extern void _nsc_init_ncio(void);
-extern void _nsc_deinit_ncio(void);
-
-static nsc_io_t *nsc_ncio_io;
-static kmutex_t nsc_ncio_lock;
-static nsc_ncio_dev_t *nsc_ncio_top;
-
-
-/*
- * ncall-io io provider - client side.
- */
-
-
-static int
-nsc_ncio_split(char *node_and_path, char **pathp)
-{
- char *cp;
- int i, snode;
-
- snode = 0;
- for (cp = node_and_path; *cp && *cp != ':'; cp++) {
- i = *cp - '0';
- if (i < 0 || i > 9)
- break;
-
- snode = (10 * snode) + i;
- }
-
- if (*cp != ':') {
- cmn_err(CE_WARN,
- "ncio: failed to convert %s to node and path",
- node_and_path);
- return (-1);
- }
-
- *pathp = cp + 1;
- return (snode);
-}
-
-
-/*
- * nsc_ncio_open()
- *
- * The pathname that is used with the NSC_NCALL io provider should be
- * of the form "<node>:<pathname>", where <node> is the decimal ncall
- * nodeid of the server machine and <pathname> is the pathname of the
- * device on the server node.
- */
-
-/* ARGSUSED */
-static int
-nsc_ncio_open(char *node_and_path, int flag, blind_t *cdp, void *iodev)
-{
- nsc_ncio_dev_t *ncp, *new;
- char *path = NULL;
- uint64_t phash;
- int snode;
-
- snode = nsc_ncio_split(node_and_path, &path);
- if (snode < 0)
- return (EINVAL);
-
- new = nsc_kmem_zalloc(sizeof (*new), KM_SLEEP, _nsc_local_mem);
- phash = nsc_strhash(path);
-
- if (new) {
- (void) strncpy(new->path, path, sizeof (new->path));
- new->phash = phash;
- new->snode = snode;
- }
-
- mutex_enter(&nsc_ncio_lock);
-
- for (ncp = nsc_ncio_top; ncp; ncp = ncp->next)
- if (ncp->phash == phash && strcmp(path, ncp->path) == 0)
- break;
-
- if (ncp == NULL && new != NULL) {
- ncp = new;
- new = NULL;
- ncp->next = nsc_ncio_top;
- nsc_ncio_top = ncp;
- }
-
- if (ncp != NULL)
- ncp->ref++;
-
- mutex_exit(&nsc_ncio_lock);
-
- if (new)
- nsc_kmem_free(new, sizeof (*new));
-
- if (!ncp)
- return (ENOMEM);
-
- *cdp = (blind_t)ncp;
- return (0);
-}
-
-
-static int
-nsc_ncio_close(nsc_ncio_dev_t *ncp)
-{
- nsc_ncio_dev_t **ncpp;
- int found, free;
-
- if (ncp == NULL)
- return (EINVAL);
-
- found = 0;
- free = 0;
-
- mutex_enter(&nsc_ncio_lock);
-
- for (ncpp = &nsc_ncio_top; *ncpp; ncpp = &((*ncpp)->next)) {
- if (*ncpp == ncp) {
- found = 1;
- break;
- }
- }
-
- if (!found) {
- mutex_exit(&nsc_ncio_lock);
- return (ENODEV);
- }
-
- ncp->ref--;
- if (ncp->ref == 0) {
- *ncpp = ncp->next;
- free = 1;
- }
-
- mutex_exit(&nsc_ncio_lock);
-
- if (free)
- nsc_kmem_free(ncp, sizeof (*ncp));
-
- return (0);
-}
-
-
-/* ARGSUSED1 */
-static nsc_buf_t *
-nsc_ncio_alloch(void (*d_cb)(), void (*r_cb)(), void (*w_cb)())
-{
- nsc_ncio_buf_t *h;
-
- if ((h = nsc_kmem_zalloc(sizeof (*h), KM_SLEEP,
- _nsc_local_mem)) == NULL)
- return (NULL);
-
- h->disc = d_cb;
- h->bufh.sb_flag = NSC_HALLOCATED;
-
- return (&h->bufh);
-}
-
-
-static int
-nsc_ncio_freeh(nsc_ncio_buf_t *h)
-{
- nsc_kmem_free(h, sizeof (*h));
- return (0);
-}
-
-
-static int
-nsc_ncio_rwb(nsc_ncio_buf_t *h, nsc_off_t pos, nsc_size_t len,
- int flag, const int rwflag)
-{
- nsc_ncio_rw_t *rw;
- ncall_t *ncall;
- int ncall_flag;
- int ncall_proc;
- int ncall_len;
- int rc, err;
-
- if (h->bufh.sb_flag & NSC_ABUF)
- return (EIO);
-
- if (pos < h->bufh.sb_pos ||
- (pos + len) > (h->bufh.sb_pos + h->bufh.sb_len)) {
- return (EINVAL);
- }
-
- if (!len)
- return (0);
-
- if (rwflag == NSC_READ && (flag & NSC_RDAHEAD))
- return (0);
-
- /* CONSTCOND */
- if (sizeof (*rw) > NCALL_DATA_SZ) {
- /* CONSTCOND */
- ASSERT(sizeof (*rw) <= NCALL_DATA_SZ);
- return (ENXIO);
- }
-
- if (rwflag == NSC_READ) {
- ncall_flag = NCALL_RDATA;
- ncall_proc = NSC_NCIO_READ;
- ncall_len = sizeof (*rw) - sizeof (rw->rw_data);
- } else {
- ncall_flag = 0;
- ncall_proc = NSC_NCIO_WRITE;
- ncall_len = sizeof (*rw);
- }
-
- rw = &h->rw;
-
- if (rwflag == 0) {
- /* zero */
- bzero(rw->rw_data, sizeof (rw->rw_data));
- }
-
- if (h->disc)
- (*h->disc)(h);
-
- rc = ncall_alloc(rw->rw_snode, 0, 0, &ncall);
- if (rc != 0) {
- return (rc);
- }
-
- rw->rw_pos = (uint64_t)pos;
- rw->rw_len = (uint64_t)len;
- rc = ncall_put_data(ncall, rw, ncall_len);
- if (rc != 0) {
- return (rc);
- }
-
- rc = ncall_send(ncall, ncall_flag, ncall_proc);
- if (rc != 0) {
- return (rc);
- }
-
- rc = ncall_read_reply(ncall, 1, &err);
- if (rc != 0 || err != 0) {
- return (rc ? rc : err);
- }
-
- if (rwflag == NSC_READ) {
- rc = ncall_get_data(ncall, rw, sizeof (*rw));
- if (rc != 0) {
- return (rc);
- }
- }
-
- ncall_free(ncall);
- return (0);
-}
-
-
-static int
-nsc_ncio_read(nsc_ncio_buf_t *h, nsc_off_t pos, nsc_size_t len, int flag)
-{
- return (nsc_ncio_rwb(h, pos, len, flag, NSC_READ));
-}
-
-
-static int
-nsc_ncio_write(nsc_ncio_buf_t *h, nsc_off_t pos, nsc_size_t len, int flag)
-{
- return (nsc_ncio_rwb(h, pos, len, flag, NSC_WRITE));
-}
-
-
-static int
-nsc_ncio_zero(nsc_ncio_buf_t *h, nsc_off_t pos, nsc_size_t len, int flag)
-{
- return (nsc_ncio_rwb(h, pos, len, flag, 0));
-}
-
-
-static void
-nsc_wait_ncio(nsc_ncio_buf_t *h)
-{
- nsc_iodev_t *iodev = h->bufh.sb_fd->sf_iodev;
- void (*fn)() = h->disc;
- nsc_ncio_buf_t *hp;
-
- mutex_enter(&iodev->si_lock);
-
- h->next = iodev->si_active;
- iodev->si_active = h;
-
- /* CONSTCOND */
-
- while (1) {
- for (hp = h->next; hp; hp = hp->next) {
- if ((h->bufh.sb_pos + h->bufh.sb_len) >
- hp->bufh.sb_pos &&
- h->bufh.sb_pos <
- (hp->bufh.sb_pos + hp->bufh.sb_len)) {
- /* found overlapping io in progress */
- break;
- }
- }
-
- if (!hp)
- break;
-
- if (fn) {
- (*fn)(h);
- fn = NULL;
- }
-
- cv_wait(&iodev->si_cv, &iodev->si_lock);
- }
-
- mutex_exit(&iodev->si_lock);
-}
-
-
-static int
-nsc_ncio_freeb(nsc_ncio_buf_t *h)
-{
- nsc_ncio_buf_t **hpp, *hp;
- nsc_iodev_t *iodev;
- int wake = 0;
-
- if ((h->bufh.sb_flag & NSC_HACTIVE) &&
- h->bufh.sb_fd && !(h->bufh.sb_flag & NSC_ABUF)) {
- iodev = h->bufh.sb_fd->sf_iodev;
-
- mutex_enter(&iodev->si_lock);
-
- for (hpp = (nsc_ncio_buf_t **)&iodev->si_active;
- *hpp; hpp = &hp->next) {
- if ((hp = *hpp) == h) {
- *hpp = h->next;
- break;
- }
-
- if ((h->bufh.sb_pos + h->bufh.sb_len) >
- hp->bufh.sb_pos &&
- h->bufh.sb_pos <
- (hp->bufh.sb_pos + hp->bufh.sb_len)) {
- wake = 1;
- }
- }
-
- if (wake)
- cv_broadcast(&iodev->si_cv);
-
- mutex_exit(&iodev->si_lock);
- }
-
- /* clear flags, preserve NSC_HALLOCATED */
- h->bufh.sb_flag &= NSC_HALLOCATED;
-
- if ((h->bufh.sb_flag & NSC_HALLOCATED) == 0)
- (void) nsc_ncio_freeh(h);
-
- return (0);
-}
-
-
-static int
-nsc_ncio_allocb(nsc_ncio_dev_t *ncp, nsc_off_t pos, nsc_size_t len,
- int flag, nsc_ncio_buf_t **hp)
-{
- nsc_ncio_buf_t *h = *hp;
- int rc;
-
- if (h == NULL) {
- cmn_err(CE_WARN, "nsc_ncio_allocb: NULL handle!");
- return (EIO);
- }
-
- if (FBA_SIZE(len) > NSC_NCIO_MAXDATA) {
- /* too large */
- return (ENXIO);
- }
-
- if ((blind_t)ncp == NSC_ANON_CD) {
- flag &= ~(NSC_READ | NSC_WRITE | NSC_RDAHEAD);
- }
-
- if (h->disc)
- (*h->disc)(h);
-
- h->bufh.sb_pos = pos;
- h->bufh.sb_len = len;
- h->bufh.sb_error = 0;
- h->bufh.sb_flag |= flag | NSC_HACTIVE;
- h->bufh.sb_vec = &h->vec[0];
-
- if (!((blind_t)ncp == NSC_ANON_CD)) {
- (void) strncpy(h->rw.rw_path, ncp->path,
- sizeof (h->rw.rw_path));
- h->rw.rw_snode = ncp->snode;
- }
-
- h->vec[0].sv_len = FBA_SIZE(len);
- h->vec[0].sv_addr = (uchar_t *)&h->rw.rw_data[0];
- h->vec[0].sv_vme = 0;
-
- h->vec[1].sv_len = 0;
- h->vec[1].sv_addr = 0;
- h->vec[1].sv_vme = 0;
-
- if ((flag & NSC_RDAHEAD) || ((blind_t)ncp == NSC_ANON_CD))
- return (NSC_DONE);
-
- nsc_wait_ncio(h);
-
- if (flag & NSC_READ) {
- if ((rc = nsc_ncio_read(h, pos, len, flag)) != 0) {
- (void) nsc_ncio_freeb(h);
- return (rc);
- }
- }
-
- return (NSC_DONE);
-}
-
-
-static int
-nsc_ncio_partsize(nsc_ncio_dev_t *ncp, nsc_size_t *rvalp)
-{
- *rvalp = (nsc_size_t)ncp->partsize;
- return (0);
-}
-
-
-/* ARGSUSED */
-static int
-nsc_ncio_maxfbas(nsc_ncio_dev_t *ncp, int flag, nsc_size_t *ptr)
-{
- if (flag == NSC_CACHEBLK)
- *ptr = 1;
- else
- *ptr = FBA_NUM(NSC_NCIO_MAXDATA);
-
- return (0);
-}
-
-
-static int
-nsc_ncio_attach(nsc_ncio_dev_t *ncp)
-{
- nsc_ncio_size_t *size;
- ncall_t *ncall;
- int sizeh, sizel;
- int rc, err;
-
- /* CONSTCOND */
- if (sizeof (*size) > NCALL_DATA_SZ) {
- /* CONSTCOND */
- ASSERT(sizeof (*size) <= NCALL_DATA_SZ);
- return (ENXIO);
- }
-
- size = kmem_zalloc(sizeof (*size), KM_SLEEP);
- (void) strncpy(size->path, ncp->path, sizeof (size->path));
-
- rc = ncall_alloc(ncp->snode, 0, 0, &ncall);
- if (rc != 0) {
- kmem_free(size, sizeof (*size));
- return (rc);
- }
-
- rc = ncall_put_data(ncall, size, sizeof (*size));
- kmem_free(size, sizeof (*size));
- size = NULL;
- if (rc != 0)
- return (rc);
-
- rc = ncall_send(ncall, 0, NSC_NCIO_PARTSIZE);
- if (rc != 0)
- return (0);
-
- rc = ncall_read_reply(ncall, 3, &err, &sizeh, &sizel);
- if (rc != 0 || err != 0)
- return (rc ? rc : err);
-
- ncall_free(ncall);
-
- ncp->partsize = (uint64_t)(((uint64_t)sizeh << 32) | (uint64_t)sizel);
- return (0);
-}
-
-
-static nsc_def_t nsc_ncio_def[] = {
- { "Open", (uintptr_t)nsc_ncio_open, 0 },
- { "Close", (uintptr_t)nsc_ncio_close, 0 },
- { "Attach", (uintptr_t)nsc_ncio_attach, 0 },
- { "AllocHandle", (uintptr_t)nsc_ncio_alloch, 0 },
- { "FreeHandle", (uintptr_t)nsc_ncio_freeh, 0 },
- { "AllocBuf", (uintptr_t)nsc_ncio_allocb, 0 },
- { "FreeBuf", (uintptr_t)nsc_ncio_freeb, 0 },
- { "Read", (uintptr_t)nsc_ncio_read, 0 },
- { "Write", (uintptr_t)nsc_ncio_write, 0 },
- { "Zero", (uintptr_t)nsc_ncio_zero, 0 },
- { "PartSize", (uintptr_t)nsc_ncio_partsize, 0 },
- { "MaxFbas", (uintptr_t)nsc_ncio_maxfbas, 0 },
- { "Provide", NSC_NCALL, 0 },
- { 0, 0, 0 }
-};
-
-
-/*
- * ncall-io io provider - server side.
- */
-
-/* ARGSUSED1 */
-static void
-nsc_rncio_partsize(ncall_t *ncall, int *ap)
-{
- nsc_ncio_size_t *size;
- nsc_size_t partsize;
- int sizeh, sizel;
- nsc_fd_t *fd;
- int rc;
-
- size = kmem_alloc(sizeof (*size), KM_SLEEP);
- rc = ncall_get_data(ncall, size, sizeof (*size));
- if (rc != 0) {
- ncall_reply(ncall, EFAULT, 0, 0);
- kmem_free(size, sizeof (*size));
- return;
- }
-
- fd = nsc_open(size->path, NSC_CACHE | NSC_DEVICE | NSC_READ,
- NULL, NULL, &rc);
- kmem_free(size, sizeof (*size));
- size = NULL;
- if (fd == NULL) {
- ncall_reply(ncall, rc, 0, 0);
- return;
- }
-
- rc = nsc_reserve(fd, NSC_PCATCH);
- if (rc != 0) {
- (void) nsc_close(fd);
- ncall_reply(ncall, rc, 0, 0);
- return;
- }
-
- sizeh = sizel = 0;
- rc = nsc_partsize(fd, &partsize);
- sizel = (int)(partsize & 0xffffffff);
- /* CONSTCOND */
- if (sizeof (nsc_size_t) > sizeof (int)) {
- sizeh = (int)((partsize & 0xffffffff00000000) >> 32);
- }
-
- nsc_release(fd);
- (void) nsc_close(fd);
-
- ncall_reply(ncall, rc, sizeh, sizel);
-}
-
-
-static int
-nsc_rncio_copy(char *data, nsc_buf_t *bufp, const int read)
-{
- nsc_vec_t *vec;
- char *datap;
- uint64_t tocopy; /* bytes */
- int thischunk; /* bytes */
- int rc;
-
- rc = 0;
- datap = data;
- vec = bufp->sb_vec;
-
- tocopy = FBA_SIZE(bufp->sb_len);
-
- while (tocopy > 0) {
- if (vec->sv_len == 0 || vec->sv_addr == 0) {
- rc = ENOSPC;
- break;
- }
-
- thischunk = (int)min((nsc_size_t)vec->sv_len, tocopy);
-
- if (read) {
- bcopy(vec->sv_addr, datap, thischunk);
- } else {
- bcopy(datap, vec->sv_addr, thischunk);
- }
-
- tocopy -= thischunk;
- if (thischunk == vec->sv_len)
- vec++;
- }
-
- return (rc);
-}
-
-
-/* ARGSUSED */
-static void
-nsc_rncio_io(ncall_t *ncall, int *ap, const int read)
-{
- nsc_ncio_rw_t *rw;
- nsc_buf_t *bufp;
- nsc_fd_t *fd;
- nsc_size_t len;
- nsc_off_t pos;
- int ioflag;
- int rc;
-
- rw = kmem_alloc(sizeof (*rw), KM_SLEEP);
- rc = ncall_get_data(ncall, rw, sizeof (*rw));
- if (rc != 0) {
- ncall_reply(ncall, EFAULT);
- kmem_free(rw, sizeof (*rw));
- return;
- }
-
- ioflag = (read ? NSC_READ : NSC_WRITE);
- pos = (nsc_off_t)rw->rw_pos;
- len = (nsc_size_t)rw->rw_len;
-
- fd = nsc_open(rw->rw_path, NSC_CACHE | NSC_DEVICE | NSC_READ | ioflag,
- NULL, NULL, &rc);
- if (fd == NULL) {
- ncall_reply(ncall, rc);
- kmem_free(rw, sizeof (*rw));
- return;
- }
-
- rc = nsc_reserve(fd, NSC_PCATCH);
- if (rc != 0) {
- ncall_reply(ncall, rc);
- (void) nsc_close(fd);
- kmem_free(rw, sizeof (*rw));
- return;
- }
-
- bufp = NULL;
- rc = nsc_alloc_buf(fd, pos, len, NSC_NOCACHE | ioflag, &bufp);
- if (rc > 0) {
- ncall_reply(ncall, rc);
- if (bufp != NULL) {
- (void) nsc_free_buf(bufp);
- }
- nsc_release(fd);
- (void) nsc_close(fd);
- kmem_free(rw, sizeof (*rw));
- return;
- }
-
- rc = nsc_rncio_copy(&rw->rw_data[0], bufp, read);
- if (rc == 0) {
- if (read) {
- /* store reply data */
- rc = ncall_put_data(ncall, rw, sizeof (*rw));
- } else {
- /* write new data */
- rc = nsc_write(bufp, pos, len, 0);
- }
- }
-
- ncall_reply(ncall, rc);
-
- (void) nsc_free_buf(bufp);
- nsc_release(fd);
- (void) nsc_close(fd);
- kmem_free(rw, sizeof (*rw));
-}
-
-
-static void
-nsc_rncio_read(ncall_t *ncall, int *ap)
-{
- nsc_rncio_io(ncall, ap, TRUE);
-}
-
-
-static void
-nsc_rncio_write(ncall_t *ncall, int *ap)
-{
- nsc_rncio_io(ncall, ap, FALSE);
-}
-
-
-/*
- * ncall-io io provider - setup.
- */
-
-void
-_nsc_init_ncio(void)
-{
- mutex_init(&nsc_ncio_lock, NULL, MUTEX_DRIVER, NULL);
-
- ncall_register_svc(NSC_NCIO_PARTSIZE, nsc_rncio_partsize);
- ncall_register_svc(NSC_NCIO_WRITE, nsc_rncio_write);
- ncall_register_svc(NSC_NCIO_READ, nsc_rncio_read);
-
- nsc_ncio_io = nsc_register_io("ncall-io",
- NSC_NCALL_ID | NSC_REFCNT, nsc_ncio_def);
-
- if (!nsc_ncio_io)
- cmn_err(CE_WARN, "_nsc_ncio_init: register io failed - ncall");
-}
-
-
-void
-_nsc_deinit_ncio(void)
-{
- if (nsc_ncio_io)
- (void) nsc_unregister_io(nsc_ncio_io, 0);
-
- ncall_unregister_svc(NSC_NCIO_PARTSIZE);
- ncall_unregister_svc(NSC_NCIO_WRITE);
- ncall_unregister_svc(NSC_NCIO_READ);
-
- nsc_ncio_io = NULL;
- mutex_destroy(&nsc_ncio_lock);
-}
diff --git a/usr/src/uts/common/avs/ns/nsctl/nsc_ncallio.h b/usr/src/uts/common/avs/ns/nsctl/nsc_ncallio.h
deleted file mode 100644
index 4a42917d2d..0000000000
--- a/usr/src/uts/common/avs/ns/nsctl/nsc_ncallio.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _NSC_NCALLIO_H
-#define _NSC_NCALLIO_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef __NSC_GEN__
-Error: Illegal #include - private file.
-#endif
-
-#include <sys/types.h>
-#include <sys/nsctl/nsc_dev.h>
-#include <sys/nsctl/nsctl.h>
-
-/*
- * ncall-io structures
- */
-
-/*
- * local per-device info structure
- */
-typedef struct nsc_ncio_dev {
- struct nsc_ncio_dev *next; /* linkage */
- char path[NSC_MAXPATH]; /* pathname */
- uint64_t phash; /* path hash */
- uint64_t partsize; /* size (FBAs) */
- int snode; /* server node */
- int ref; /* ref count */
-} nsc_ncio_dev_t;
-
-
-/*
- * on the wire partsize request structure (reply is inline).
- */
-typedef struct nsc_ncio_size {
- char path[NSC_MAXPATH];
-} nsc_ncio_size_t;
-
-
-/*
- * buffer handle and one the wire representation.
- */
-
-#define NSC_NCIO_MAXDATA (NCALL_DATA_SZ - FBA_SIZE(1))
-
-
-typedef struct nsc_ncio_rw {
- union {
- struct {
- int snode; /* server node */
- uint64_t pos; /* offset of i/o */
- uint64_t len; /* length of i/o */
- char path[NSC_MAXPATH]; /* path of device */
- } rw;
- char pad[FBA_SIZE(1)]; /* pad to FBA */
- } rw_u;
- char rw_data[NSC_NCIO_MAXDATA]; /* data */
-} nsc_ncio_rw_t;
-
-#define rw_snode rw_u.rw.snode
-#define rw_path rw_u.rw.path
-#define rw_pos rw_u.rw.pos
-#define rw_len rw_u.rw.len
-
-
-typedef struct nsc_ncio_bufh {
- nsc_buf_t bufh;
- nsc_vec_t vec[2];
- void (*disc)();
- struct nsc_ncio_bufh *next;
- struct nsc_ncio_rw rw;
-} nsc_ncio_buf_t;
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _NSC_NCALLIO_H */
diff --git a/usr/src/uts/common/avs/ns/nsctl/nsc_power.c b/usr/src/uts/common/avs/ns/nsctl/nsc_power.c
deleted file mode 100644
index 4b7406052c..0000000000
--- a/usr/src/uts/common/avs/ns/nsctl/nsc_power.c
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/ksynch.h>
-#include <sys/kmem.h>
-#include <sys/file.h>
-#include <sys/errno.h>
-#include <sys/open.h>
-#include <sys/cred.h>
-#include <sys/conf.h>
-#include <sys/uio.h>
-#include <sys/cmn_err.h>
-
-#define __NSC_GEN__
-#include "nsc_dev.h"
-#include "nsc_ioctl.h"
-#include "nsc_power.h"
-#include "../nsctl.h"
-
-extern nsc_mem_t *_nsc_local_mem;
-static int null_power(void);
-
-
-typedef struct _nsc_power_s {
- struct _nsc_power_s *next; /* chain */
- char *name; /* module name */
- void (*pw_power_lost)(int); /* callback power lost(rideout) */
- void (*pw_power_ok)(void); /* callback power ok */
- void (*pw_power_down)(void);
- /* callback power down (shutdown imminent) */
-} _nsc_power_t;
-
-#define _P(x) (((long)(&((_nsc_power_t *)0)->x))/sizeof (long))
-
-static nsc_def_t _nsc_power_def[] = {
- "Power_Lost", (uintptr_t)null_power, _P(pw_power_lost),
- "Power_OK", (uintptr_t)null_power, _P(pw_power_ok),
- "Power_Down", (uintptr_t)null_power, _P(pw_power_down),
- 0, 0, 0,
-};
-
-static _nsc_power_t *_power_clients;
-static kmutex_t _power_mutex;
-
-
-static int null_power(void)
-/*
- * init null_power - dummy power routine for clients that choose not
- * to implement all the power hooks.
- *
- */
-{
- return (0);
-}
-
-/*
- * int
- * _nsc_power
- * Call registered clients of the generic power ioctls.
- *
- * Calling/Exit State:
- * Calls all the registered clients with a message describing the
- * current state of the power for the system.
- */
-int
-_nsc_power(blind_t argp, int *rvp)
-{
- nsc_power_ctl_t opc;
- _nsc_power_t *pp;
-
- *rvp = 0;
- if (copyin((void *) argp, &opc, sizeof (nsc_power_ctl_t)))
- return (EFAULT);
- mutex_enter(&_power_mutex);
-
- pp = _power_clients;
- while (pp) {
- switch ((nsc_power_ops_t)opc.msg) {
-
- case Power_OK:
- (*pp->pw_power_ok)();
- break;
-
- case Power_Down:
- (*pp->pw_power_down)();
- break;
-
- case Power_Lost:
- (*pp->pw_power_lost)(opc.arg1);
- break;
-
- default:
- mutex_exit(&_power_mutex);
- return (EINVAL);
- }
-
- pp = pp->next;
- }
- mutex_exit(&_power_mutex);
- return (0);
-}
-
-/*
- * int
- * _nsc_init_power (void)
- * Initialise power ioctl subsystem.
- *
- * Calling/Exit State:
- * Called at driver initialisation time to allocate necessary
- * data structures.
- */
-int
-_nsc_init_power(void)
-{
- mutex_init(&_power_mutex, NULL, MUTEX_DRIVER, NULL);
- return (0);
-}
-
-/*
- * int
- * _nsc_deinit_power (void)
- * Initialise power ioctl subsystem.
- *
- * Calling/Exit State:
- * Called at driver initialisation time to allocate necessary
- * data structures.
- */
-int
-_nsc_deinit_power(void)
-{
- _nsc_power_t *pp, *npp;
-
- mutex_enter(&_power_mutex);
- pp = _power_clients;
- while (pp) {
- npp = pp->next;
- nsc_kmem_free(pp, sizeof (_nsc_power_t));
- pp = npp;
- }
- _power_clients = NULL;
- mutex_exit(&_power_mutex);
- mutex_destroy(&_power_mutex);
- return (0);
-}
-
-/*
- * blind_t
- * nsc_register_power (char *name, nsc_def_t *def)
- * Register an power ioctl client.
- *
- * Calling/Exit State:
- * Returns a token for use in future calls to nsc_unregister_power.
- * If a client with the same name is already registered then NULL
- * is return to indicate failure.
- * If registration fails NULL is returned.
- *
- * Description:
- * Registers an power ioctl client for notifications during subsequent
- * ioctl from UPS/PCU management.
- */
-blind_t
-nsc_register_power(char *name, nsc_def_t *def)
-{
- _nsc_power_t *entry, *pp;
-
-
- entry = nsc_kmem_alloc(sizeof (_nsc_power_t), 0, _nsc_local_mem);
-
- if (entry == NULL)
- return (NULL);
- nsc_decode_param(def, _nsc_power_def, (long *)entry);
-
- mutex_enter(&_power_mutex);
-
- for (pp = _power_clients; pp; pp = pp->next) {
- if (strcmp(pp->name, name) == 0) {
- mutex_exit(&_power_mutex);
- nsc_kmem_free(entry, sizeof (_nsc_power_t));
- return (NULL);
- }
- }
- entry->name = name;
-
- entry->next = _power_clients;
- _power_clients = entry;
- mutex_exit(&_power_mutex);
- return ((blind_t)entry);
-}
-
-/*
- * int
- * nsc_unregister_power (blind_t powerp)
- * Un-register a power ioctl client.
- *
- * Calling/Exit State:
- * Returns 0 on success, otherwise returns an error code.
- *
- * Description:
- * The specified power ioctl client is un-registered if possible.
- * Zero is returned on success otherwise an error code.
- */
-int
-nsc_unregister_power(blind_t powerp)
-{
- _nsc_power_t **xpp, *entry;
-
- entry = (_nsc_power_t *)powerp;
- if (entry == NULL)
- return (EINVAL);
-
- mutex_enter(&_power_mutex);
-
- for (xpp = &_power_clients; *xpp; xpp = &(*xpp)->next)
- if (*xpp == entry)
- break;
-
- if (*xpp == NULL) {
- mutex_exit(&_power_mutex);
- return (EALREADY);
- }
- *xpp = entry->next;
- mutex_exit(&_power_mutex);
- nsc_kmem_free(entry, sizeof (_nsc_power_t));
-
- return (0);
-}
diff --git a/usr/src/uts/common/avs/ns/nsctl/nsc_power.h b/usr/src/uts/common/avs/ns/nsctl/nsc_power.h
deleted file mode 100644
index 6284818aea..0000000000
--- a/usr/src/uts/common/avs/ns/nsctl/nsc_power.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _NSC_POWER_H
-#define _NSC_POWER_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Power ioctl definitions for Storage Device.
- * This layout is common between 32 and 64 bits kernels.
- */
-
-typedef struct nsc_power_ctl_s {
- int msg; /* power ioctl sub-opcode */
- int arg1; /* argument for the sub-opcode */
-} nsc_power_ctl_t;
-
-#ifdef _KERNEL
-extern int _nsc_init_power(void);
-extern int _nsc_deinit_power(void);
-extern int _nsc_power(blind_t, int *);
-#endif /* _KERNEL */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _NSC_POWER_H */
diff --git a/usr/src/uts/common/avs/ns/nsctl/nsc_resv.c b/usr/src/uts/common/avs/ns/nsctl/nsc_resv.c
deleted file mode 100644
index 24ef8df98c..0000000000
--- a/usr/src/uts/common/avs/ns/nsctl/nsc_resv.c
+++ /dev/null
@@ -1,1014 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/ksynch.h>
-#include <sys/kmem.h>
-#include <sys/cmn_err.h>
-#include <sys/errno.h>
-#include <sys/ddi.h>
-
-#define __NSC_GEN__
-#include <sys/ncall/ncall.h>
-#include "nsc_dev.h"
-#include "../nsctl.h"
-#ifdef DS_DDICT
-#include "../contract.h"
-#endif
-
-
-static int _nsc_attach_fd(nsc_fd_t *, int);
-static int _nsc_detach_owner(nsc_fd_t *, int);
-static int _nsc_fd_fn(nsc_fd_t *, int (*)(), int, int);
-static int _nsc_attach_iodev(nsc_iodev_t *, int);
-static int _nsc_attach_dev(nsc_dev_t *, int);
-static int _nsc_call_dev(nsc_dev_t *, blindfn_t, blind_t,
- int *, int *, int, int, nsc_iodev_t *);
-
-
-/*
- * void
- * _nsc_init_resv (void)
- * Initialise reserve mechanism.
- *
- * Calling/Exit State:
- * Called at initialisation time to allocate necessary
- * data structures.
- */
-void
-_nsc_init_resv()
-{
-}
-
-
-/*
- * void
- * _nsc_deinit_resv (void)
- * De-initialise reserve mechanism.
- *
- * Calling/Exit State:
- * Called at unload time to de-allocate resources.
- */
-void
-_nsc_deinit_resv()
-{
-}
-
-
-/*
- * int
- * nsc_attach (nsc_fd_t *fd, int flag)
- * Force attach of file descriptor.
- *
- * Calling/Exit State:
- * Returns 0 if the attach succeeds, otherwise
- * returns an error code.
- *
- * Description:
- * Tries to attach the file descriptor by reserving
- * and then releasing it. This is intended purely as
- * a performance aid since there is no guarantee that
- * the file descriptor will remain attached upon
- * return.
- */
-int
-nsc_attach(fd, flag)
-nsc_fd_t *fd;
-int flag;
-{
- int rc;
-
- rc = nsc_reserve(fd, flag);
-
- if (rc == 0)
- nsc_release(fd);
-
- return (rc);
-}
-
-
-/*
- * int
- * nsc_reserve (nsc_fd_t *fd, int flag)
- * Reserve file descriptor.
- *
- * Calling/Exit State:
- * Returns 0 if the reserve succeeds, otherwise
- * returns an error code.
- *
- * Description:
- * Reserves the file descriptor for either NSC_READ or
- * NSC_WRITE access. If neither is specified the mode
- * with which the file was opened will be used. Trying
- * to reserve a read only file in write mode will cause
- * EACCES to be returned.
- *
- * If NSC_NOBLOCK is specifed and the reserve cannot be
- * completed immediately, EAGAIN will be returned.
- *
- * If NSC_NOWAIT is set and the device is busy, EAGAIN
- * will be returned.
- *
- * If NSC_TRY is set and the device is already reserved
- * EAGAIN will be returned.
- *
- * If NSC_PCATCH is specified and a signal is received,
- * the reserve will be terminated and EINTR returned.
- *
- * If NSC_MULTI is set then multiple reserves of the
- * same type are permitted for the file descriptor.
- */
-int
-nsc_reserve(fd, flag)
-nsc_fd_t *fd;
-int flag;
-{
- nsc_dev_t *dev = fd->sf_dev;
- int rc, rw;
-
- if ((flag & NSC_READ) == 0)
- flag |= (fd->sf_flag & NSC_RDWR);
-
- rw = (flag & NSC_RDWR);
- if ((fd->sf_flag & rw) != rw)
- return (EACCES);
-
- mutex_enter(&dev->nsc_lock);
-
- while ((rc = _nsc_attach_fd(fd, flag)) != 0)
- if (rc != ERESTART)
- break;
-
- if (!rc && !fd->sf_reserve++) {
- fd->sf_aio = fd->sf_iodev->si_io;
- fd->sf_mode = (flag & NSC_MULTI);
- }
-
- mutex_exit(&dev->nsc_lock);
- return (rc);
-}
-
-
-/*
- * int
- * nsc_reserve_lk (nsc_fd_t *fd)
- * Reserve locked file descriptor.
- *
- * Calling/Exit State:
- * The device lock must be held across calls to
- * this function.
- *
- * Must be preceeded by a successful call to nsc_avail.
- *
- * Description:
- * Reserves the file descriptor using the mode specified
- * when the file was opened. This is only intended for
- * use in performance critical situations.
- */
-void
-nsc_reserve_lk(fd)
-nsc_fd_t *fd;
-{
- fd->sf_reserve = 1;
- fd->sf_aio = fd->sf_iodev->si_io;
-}
-
-
-/*
- * int
- * nsc_avail (nsc_fd_t *fd)
- * Test if file descriptor is available.
- *
- * Calling/Exit State:
- * The device lock must be held across calls to
- * this function.
- *
- * Returns true if the file descriptor is available to
- * be reserved using the mode specified when the file
- * was opened.
- *
- * Description:
- * This is only intended for use in performance critical
- * situations in conjunction with nsc_reserve_lk.
- */
-int
-nsc_avail(fd)
-nsc_fd_t *fd;
-{
- int rw;
-
- if (!fd || fd->sf_pend || fd->sf_reserve || fd->sf_reopen)
- return (0);
-
- if ((fd->sf_avail & _NSC_ATTACH) == 0)
- return (0);
- if ((fd->sf_avail & _NSC_PINNED) == 0)
- return (0);
-
- rw = (fd->sf_flag & NSC_RDWR);
-
- return ((fd->sf_avail & rw) == rw);
-}
-
-
-/*
- * int
- * nsc_held (nsc_fd_t *fd)
- * Test if file descriptor is reserved.
- *
- * Calling/Exit State:
- * Returns true if the file descriptor is currently
- * reserved.
- */
-int
-nsc_held(fd)
-nsc_fd_t *fd;
-{
- return ((fd) ? fd->sf_reserve : 1);
-}
-
-
-/*
- * int
- * nsc_waiting (nsc_fd_t *fd)
- * Test if another client is waiting for this device.
- *
- * Calling/Exit State:
- * Must be called with the file descriptor reserved.
- * Returns true if another thread is waiting to reserve this device.
- *
- * Description:
- * This is only intended for use in performance critical
- * situations and inherently returns historical information.
- */
-int
-nsc_waiting(nsc_fd_t *fd)
-{
- nsc_dev_t *dev;
-
- if (!fd || !nsc_held(fd))
- return (FALSE);
-
- dev = fd->sf_dev;
-
- return (dev->nsc_wait || dev->nsc_refcnt <= 0);
-}
-
-
-/*
- * int
- * nsc_release_lk (nsc_fd_t *fd)
- * Release locked file descriptor.
- *
- * Calling/Exit State:
- * The device lock must be held across calls to
- * this function.
- *
- * Returns true if another node is waiting for the
- * device and a call to nsc_detach should be made.
- *
- * Description:
- * Releases the file descriptor. This is only intended
- * for use in performance critical situations in
- * conjunction with nsc_reserve_lk.
- */
-int
-nsc_release_lk(fd)
-nsc_fd_t *fd;
-{
- nsc_dev_t *dev = fd->sf_dev;
-
- fd->sf_reserve = 0;
- fd->sf_aio = _nsc_null_io;
-
- if (dev->nsc_wait || dev->nsc_refcnt <= 0)
- cv_broadcast(&dev->nsc_cv);
-
- return (dev->nsc_drop > 0);
-}
-
-
-/*
- * int
- * nsc_release (nsc_fd_t *fd)
- * Release file descriptor.
- *
- * Description:
- * Releases the file descriptor. If another node
- * is waiting for the device it will be completely
- * detached before returning.
- */
-void
-nsc_release(fd)
-nsc_fd_t *fd;
-{
- nsc_dev_t *dev = fd->sf_dev;
- int rc;
-
- mutex_enter(&dev->nsc_lock);
-
- if (!fd->sf_reserve || --fd->sf_reserve) {
- mutex_exit(&dev->nsc_lock);
- return;
- }
-
- fd->sf_aio = _nsc_null_io;
- fd->sf_mode = 0;
-
- if (dev->nsc_wait || dev->nsc_refcnt <= 0)
- cv_broadcast(&dev->nsc_cv);
-
- while (dev->nsc_drop > 0) {
- rc = _nsc_detach_dev(dev, NULL, NSC_RDWR);
- if (!rc || rc != ERESTART)
- break;
- }
-
- mutex_exit(&dev->nsc_lock);
-}
-
-
-/*
- * int
- * nsc_detach (nsc_fd_t *fd, int flag)
- * Detach device from node.
- *
- * Calling/Exit State:
- * Returns 0 if the reserve succeeds, otherwise
- * returns an error code.
- *
- * Description:
- * Detaches the device from the current node. If flag
- * specifies read access then flush is called in preference
- * to detach.
- *
- * If NSC_NOBLOCK is specifed and the detach cannot be
- * completed immediately, EAGAIN will be returned.
- *
- * If NSC_TRY is set and the device is reserved, EAGAIN
- * will be returned.
- *
- * If NSC_NOWAIT is set and the device is busy, EAGAIN
- * will be returned.
- *
- * If NSC_PCATCH is specified and a signal is received,
- * the reserve will be terminated and EINTR returned.
- *
- * If NSC_DEFER is set and the device is reserved, then
- * the detach will be done on release.
- */
-int
-nsc_detach(fd, flag)
-nsc_fd_t *fd;
-int flag;
-{
- nsc_dev_t *dev;
- int rc;
-
- if (!fd)
- return (0);
-
- dev = fd->sf_dev;
-
- if (flag & NSC_DEFER)
- flag |= NSC_TRY;
- if ((flag & NSC_READ) == 0)
- flag |= NSC_RDWR;
-
- mutex_enter(&dev->nsc_lock);
-
- while ((rc = _nsc_detach_dev(dev, NULL, flag)) != 0)
- if (rc != ERESTART)
- break;
-
- if (rc == EAGAIN && (flag & NSC_DEFER))
- dev->nsc_drop = 1;
-
- mutex_exit(&dev->nsc_lock);
- return (rc);
-}
-
-
-/*
- * static int
- * _nsc_attach_fd (nsc_fd_t *fd, int flag)
- * Attach file descriptor.
- *
- * Calling/Exit State:
- * The device lock must be held across calls to
- * this function.
- *
- * Returns 0 if the attach succeeds without releasing
- * the device lock, otherwise returns an error code.
- *
- * Description:
- * Attach the specified file descriptor. Other file
- * descriptors for the same I/O device will be flushed
- * or detached first as necessary.
- */
-static int
-_nsc_attach_fd(fd, flag)
-nsc_fd_t *fd;
-int flag;
-{
- nsc_dev_t *dev = fd->sf_dev;
- int rw = (flag & NSC_RDWR);
- nsc_iodev_t *iodev;
- int rc, av;
-
- if (fd->sf_pend)
- return (_nsc_wait_dev(dev, flag));
-
- if (fd->sf_reopen)
- if ((rc = _nsc_close_fd(fd, flag)) != 0)
- return (rc);
-
- if (!fd->sf_iodev)
- if ((rc = _nsc_open_fd(fd, flag)) != 0)
- return (rc);
-
- iodev = fd->sf_iodev;
-
- if ((flag & fd->sf_mode & NSC_MULTI) && fd->sf_reserve)
- if ((fd->sf_avail & rw) == rw && !iodev->si_rpend)
- if (dev->nsc_drop == 0)
- return (0);
-
- if (fd->sf_reserve) {
- if (flag & NSC_TRY)
- return (EAGAIN);
- return (_nsc_wait_dev(dev, flag));
- }
-
- if (fd->sf_avail & _NSC_ATTACH)
- if (fd->sf_avail & _NSC_PINNED)
- if ((fd->sf_avail & rw) == rw)
- return (0);
-
- if (iodev->si_rpend && !fd->sf_avail)
- return (_nsc_wait_dev(dev, flag));
-
- if ((rc = _nsc_detach_iodev(iodev, fd, flag)) != 0 ||
- (rc = _nsc_attach_iodev(iodev, flag)) != 0)
- return (rc);
-
- if (!fd->sf_avail) {
- fd->sf_avail = rw;
- return (_nsc_fd_fn(fd, fd->sf_attach, _NSC_ATTACH, flag));
- }
-
- if ((fd->sf_avail & _NSC_PINNED) == 0) {
- av = (fd->sf_avail | _NSC_PINNED);
-
- return _nsc_call_dev(dev, iodev->si_io->getpin,
- fd->sf_cd, &fd->sf_avail, &fd->sf_pend, av, flag, NULL);
- }
-
- fd->sf_avail |= rw;
- return (0);
-}
-
-
-/*
- * int
- * _nsc_detach_fd (nsc_fd_t *fd, int flag)
- * Detach file descriptor.
- *
- * Calling/Exit State:
- * The device lock must be held across calls to
- * this function.
- *
- * Returns 0 if the detach succeeds without releasing
- * the device lock, otherwise returns an error code.
- *
- * Description:
- * Detach the specified file descriptor. If flag
- * specifies read access then flush is called in
- * preference to detach.
- */
-int
-_nsc_detach_fd(fd, flag)
-nsc_fd_t *fd;
-int flag;
-{
- nsc_dev_t *dev = fd->sf_dev;
- int rc;
-
- if (fd->sf_pend == _NSC_CLOSE)
- return (0);
-
- if (fd->sf_pend)
- return (_nsc_wait_dev(dev, flag));
-
- if (fd->sf_flush == nsc_null)
- flag |= NSC_RDWR;
-
- if ((fd->sf_avail & NSC_RDWR) == 0)
- if (!fd->sf_avail || !(flag & NSC_WRITE))
- return (0);
-
- if (fd->sf_reserve && fd->sf_owner)
- if ((rc = _nsc_detach_owner(fd, flag)) != 0)
- return (rc);
-
- if (fd->sf_reserve) {
- if (flag & NSC_TRY)
- return (EAGAIN);
- return (_nsc_wait_dev(dev, flag));
- }
-
- if (flag & NSC_WRITE) {
- if (fd->sf_iodev->si_busy)
- return (_nsc_wait_dev(dev, flag));
-
- return (_nsc_fd_fn(fd, fd->sf_detach, 0, flag));
- }
-
- return (_nsc_fd_fn(fd, fd->sf_flush, (fd->sf_avail & ~NSC_RDWR), flag));
-}
-
-
-/*
- * static int
- * _nsc_detach_owner (nsc_fd_t *fd, int flag)
- * Detach owner of file descriptor.
- *
- * Calling/Exit State:
- * The device lock must be held across calls to
- * this function.
- *
- * Returns 0 if the detach succeeds without releasing
- * the device lock, otherwise returns an error code.
- *
- * Description:
- * Detach the owner of the specified file descriptor.
- * Wherever possible this is done without releasing
- * the current device lock.
- */
-static int
-_nsc_detach_owner(fd, flag)
-nsc_fd_t *fd;
-int flag;
-{
- nsc_dev_t *newdev = fd->sf_owner->si_dev;
- nsc_dev_t *dev = fd->sf_dev;
- int try;
- int rc;
-
- if (newdev == dev) {
- if ((rc = _nsc_detach_iodev(fd->sf_owner, NULL, flag)) == 0)
- fd->sf_owner = NULL;
- return (rc);
- }
-
- if ((try = mutex_tryenter(&newdev->nsc_lock)) != 0)
- if (!_nsc_detach_iodev(fd->sf_owner, NULL,
- (flag | NSC_NOBLOCK))) {
- mutex_exit(&newdev->nsc_lock);
- return (0);
- }
-
- if (flag & NSC_NOBLOCK) {
- if (try != 0)
- mutex_exit(&newdev->nsc_lock);
- return (EAGAIN);
- }
-
- fd->sf_pend = _NSC_OWNER;
- mutex_exit(&dev->nsc_lock);
-
- if (try == 0)
- mutex_enter(&newdev->nsc_lock);
-
- rc = _nsc_detach_iodev(fd->sf_owner, NULL, flag);
- fd->sf_owner = NULL;
-
- mutex_exit(&newdev->nsc_lock);
-
- mutex_enter(&dev->nsc_lock);
- fd->sf_pend = 0;
-
- if (dev->nsc_wait || dev->nsc_refcnt <= 0)
- cv_broadcast(&dev->nsc_cv);
-
- return (rc ? rc : ERESTART);
-}
-
-
-/*
- * static int
- * _nsc_fd_fn (nsc_fd_t *fd, int (*fn)(), int a, int flag)
- * Call function to attach/detach file descriptor.
- *
- * Calling/Exit State:
- * The device lock must be held across calls to
- * this function.
- *
- * Returns an error code if the operation failed,
- * otherwise returns ERESTART to indicate that the
- * device state has changed.
- *
- * Description:
- * Sets up the active I/O module and calls the
- * specified function.
- */
-static int
-_nsc_fd_fn(nsc_fd_t *fd, int (*fn)(), int a, int flag)
-{
- int rc;
-
- fd->sf_aio = fd->sf_iodev->si_io;
-
- rc = _nsc_call_dev(fd->sf_dev, fn, fd->sf_arg,
- &fd->sf_avail, &fd->sf_pend, a, flag, NULL);
-
- fd->sf_aio = _nsc_null_io;
- return (rc);
-}
-
-
-/*
- * static int
- * _nsc_attach_iodev (nsc_iodev_t *iodev, int flag)
- * Attach I/O device.
- *
- * Calling/Exit State:
- * The device lock must be held across calls to
- * this function.
- *
- * Returns 0 if the attach succeeds without releasing
- * the device lock, otherwise returns an error code.
- *
- * Description:
- * Attach the specified I/O device. Other I/O devices
- * for the same device will be flushed or detached first
- * as necessary.
- *
- * It is assumed that any valid cache descriptor for
- * this device can be used to attach the I/O device.
- */
-static int
-_nsc_attach_iodev(iodev, flag)
-nsc_iodev_t *iodev;
-int flag;
-{
- nsc_dev_t *dev = iodev->si_dev;
- nsc_io_t *io = iodev->si_io;
- int rc, rw;
-
- rw = (flag & NSC_RDWR);
-
- if (iodev->si_pend)
- return (_nsc_wait_dev(dev, flag));
-
- if (iodev->si_avail & _NSC_ATTACH)
- if ((iodev->si_avail & rw) == rw)
- return (0);
-
- if ((io->flag & NSC_FILTER) == 0) {
- if (dev->nsc_rpend && !iodev->si_avail)
- return (_nsc_wait_dev(dev, flag));
-
- if ((rc = _nsc_detach_dev(dev, iodev, flag)) != 0 ||
- (rc = _nsc_attach_dev(dev, flag)) != 0)
- return (rc);
- }
-
- if (!iodev->si_avail) {
- iodev->si_avail = rw;
-
- if (!iodev->si_open) {
- cmn_err(CE_PANIC,
- "nsctl: _nsc_attach_iodev: %p no fds",
- (void *)iodev);
- }
-
- return (_nsc_call_dev(dev, io->attach, iodev->si_open->sf_cd,
- &iodev->si_avail, &iodev->si_pend, _NSC_ATTACH,
- flag, iodev));
- }
-
- iodev->si_avail |= rw;
- return (0);
-}
-
-
-/*
- * int
- * _nsc_detach_iodev (nsc_iodev_t *iodev, nsc_fd_t *keep, int flag)
- * Detach I/O device.
- *
- * Calling/Exit State:
- * The device lock must be held across calls to
- * this function.
- *
- * Returns 0 if the detach succeeds without releasing
- * the device lock, otherwise returns an error code.
- *
- * Description:
- * Detach the specified I/O device except for file
- * descriptor keep. If flag specifies read access then
- * flush is called in preference to detach.
- *
- * It is assumed that any valid cache descriptor for
- * this device can be used to detach the I/O device.
- */
-int
-_nsc_detach_iodev(nsc_iodev_t *iodev, nsc_fd_t *keep, int flag)
-{
- nsc_dev_t *dev = iodev->si_dev;
- nsc_io_t *io = iodev->si_io;
- int (*fn)(), av, rc;
- nsc_fd_t *fd;
-
- if (iodev->si_pend == _NSC_CLOSE)
- return (0);
-
- if (iodev->si_pend)
- return (_nsc_wait_dev(dev, flag));
-
- if (!keep && io->flush == nsc_null)
- flag |= NSC_RDWR;
-
- if ((iodev->si_avail & NSC_RDWR) == 0)
- if (!iodev->si_avail || !(flag & NSC_WRITE))
- return (0);
-
- iodev->si_rpend++;
-
- for (fd = iodev->si_open; fd; fd = fd->sf_next) {
- if (fd == keep)
- continue;
-
- if ((rc = _nsc_detach_fd(fd, flag)) != 0) {
- _nsc_wake_dev(dev, &iodev->si_rpend);
- return (rc);
- }
- }
-
- _nsc_wake_dev(dev, &iodev->si_rpend);
-
- if (keep)
- return (0);
-
- if (!iodev->si_open) {
- cmn_err(CE_PANIC,
- "nsctl: _nsc_detach_iodev: %p no fds", (void *)iodev);
- }
-
- fn = (flag & NSC_WRITE) ? io->detach : io->flush;
- av = (flag & NSC_WRITE) ? 0 : (iodev->si_avail & ~NSC_RDWR);
-
- return (_nsc_call_dev(dev, fn, iodev->si_open->sf_cd,
- &iodev->si_avail, &iodev->si_pend, av, flag, iodev));
-}
-
-
-/*
- * static int
- * _nsc_attach_dev (nsc_dev_t *dev, int flag)
- * Attach device to node.
- *
- * Calling/Exit State:
- * The device lock must be held across calls to
- * this function.
- *
- * Returns 0 if the attach succeeds without releasing
- * the device lock, otherwise returns an error code.
- *
- * Description:
- * Attach the device to the current node.
- */
-static int
-_nsc_attach_dev(dev, flag)
-nsc_dev_t *dev;
-int flag;
-{
- if (dev->nsc_pend) {
- if (flag & NSC_TRY)
- return (EAGAIN);
- return (_nsc_wait_dev(dev, flag));
- }
-
- return (0);
-}
-
-
-/*
- * int
- * _nsc_detach_dev (nsc_dev_t *dev, nsc_iodev_t *keep, int flag)
- * Detach device.
- *
- * Calling/Exit State:
- * The device lock must be held across calls to
- * this function.
- *
- * Returns 0 if the detach succeeds without releasing
- * the device lock, otherwise returns an error code.
- *
- * Description:
- * Detach the device except for I/O descriptor keep.
- * If flag specifies read access then flush is called
- * in preference to detach. If appropriate the device
- * will be released for use by another node.
- *
- * All I/O devices are detached regardless of the
- * current owner as a sanity check.
- */
-int
-_nsc_detach_dev(nsc_dev_t *dev, nsc_iodev_t *keep, int flag)
-{
- nsc_iodev_t *iodev;
- int rc = 0;
-
- if (dev->nsc_pend) {
- if (flag & NSC_TRY)
- return (EAGAIN);
- return (_nsc_wait_dev(dev, flag));
- }
-
- dev->nsc_rpend++;
-
- for (iodev = dev->nsc_list; iodev; iodev = iodev->si_next) {
- if (iodev == keep)
- continue;
- if (iodev->si_io->flag & NSC_FILTER)
- continue;
-
- if ((rc = _nsc_detach_iodev(iodev, NULL, flag)) != 0)
- break;
- }
-
- _nsc_wake_dev(dev, &dev->nsc_rpend);
-
- if (keep || !(flag & NSC_WRITE))
- return (rc);
- if (rc == EAGAIN || rc == ERESTART)
- return (rc);
-
- dev->nsc_drop = 0;
-
- return (rc);
-}
-
-
-/*
- * static int
- * _nsc_call_dev (nsc_dev_t *dev, blindfn_t fn, blind_t arg,
- * *int *ap, int *pp, int a, int flag, nsc_iodev_t *iodev)
- * Call attach/detach function.
- *
- * Calling/Exit State:
- * The device lock must be held across calls to this
- * this function.
- *
- * Returns an error code if the operation failed,
- * otherwise returns ERESTART to indicate that the
- * device state has changed.
- *
- * The flags pointed to by ap are updated to reflect
- * availability based upon argument a. The pending
- * flag pointed to by pp is set whilst the operation
- * is in progress.
- *
- * Description:
- * Marks the device busy, temporarily releases the
- * device lock and calls the specified function with
- * the given argument.
- *
- * If a detach is being performed then clear _NSC_ATTACH
- * first to prevent pinned data callbacks. If the detach
- * fails then clear _NSC_PINNED and indicate that a flush
- * is required by setting NSC_READ.
- */
-static int
-_nsc_call_dev(nsc_dev_t *dev, blindfn_t fn, blind_t arg, int *ap, int *pp,
- int a, int flag, nsc_iodev_t *iodev)
-{
- int rc = 0, v = *ap;
-
- if (flag & NSC_NOBLOCK)
- if (fn != nsc_null)
- return (EAGAIN);
-
- if (!a && v)
- *ap = (v & ~_NSC_ATTACH) | NSC_READ;
-
- if (fn != nsc_null) {
- *pp = (a) ? a : _NSC_DETACH;
- mutex_exit(&dev->nsc_lock);
-
- rc = (*fn)(arg, iodev);
-
- mutex_enter(&dev->nsc_lock);
- *pp = 0;
- }
-
- if (dev->nsc_wait || dev->nsc_refcnt <= 0)
- cv_broadcast(&dev->nsc_cv);
-
- if (rc) {
- if (!a && v)
- a = (v & ~_NSC_PINNED) | NSC_READ;
- else if (v & _NSC_ATTACH)
- a = v;
- else
- a = 0;
- }
-
- *ap = a;
- return (rc ? rc : ERESTART);
-}
-
-
-/*
- * int
- * _nsc_wait_dev (nsc_dev_t *dev, int flag)
- * Wait for device state to change.
- *
- * Calling/Exit State:
- * Must be called with the device lock held.
- * Returns EAGAIN if NSC_NOBLOCK or NSC_NOWAIT is set,
- * or EINTR if the wait was interrupted, otherwise
- * returns ERESTART to indicate that the device state
- * has changed.
- *
- * Description:
- * Waits for the device state to change before resuming.
- *
- * Remarks:
- * If the reference count on the device has dropped to
- * zero then cv_broadcast is called to wakeup _nsc_free_dev.
- */
-int
-_nsc_wait_dev(dev, flag)
-nsc_dev_t *dev;
-int flag;
-{
- int rc = 1;
-
- if (flag & (NSC_NOBLOCK | NSC_NOWAIT))
- return (EAGAIN);
-
- dev->nsc_wait++;
-
- if (flag & NSC_PCATCH)
- rc = cv_wait_sig(&dev->nsc_cv, &dev->nsc_lock);
- else
- cv_wait(&dev->nsc_cv, &dev->nsc_lock);
-
- dev->nsc_wait--;
-
- if (dev->nsc_refcnt <= 0)
- cv_broadcast(&dev->nsc_cv);
-
- return ((rc == 0) ? EINTR : ERESTART);
-}
-
-
-/*
- * void
- * _nsc_wake_dev (nsc_dev_t *dev, int *valp)
- * Decrement value and wakeup device.
- *
- * Calling/Exit State:
- * The device lock must be held across calls to
- * this function.
- *
- * Description:
- * Decrements the indicated value and if appropriate
- * wakes up anybody waiting on the device.
- */
-void
-_nsc_wake_dev(dev, valp)
-nsc_dev_t *dev;
-int *valp;
-{
- if (--(*valp))
- return;
-
- if (dev->nsc_wait || dev->nsc_refcnt <= 0)
- cv_broadcast(&dev->nsc_cv);
-}
diff --git a/usr/src/uts/common/avs/ns/nsctl/nsc_rmspin.c b/usr/src/uts/common/avs/ns/nsctl/nsc_rmspin.c
deleted file mode 100644
index bae65bbcbe..0000000000
--- a/usr/src/uts/common/avs/ns/nsctl/nsc_rmspin.c
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/debug.h>
-#include <sys/ksynch.h>
-#include <sys/cmn_err.h>
-#include <sys/kmem.h>
-#include <sys/ddi.h>
-
-#define __NSC_GEN__
-#include "nsc_gen.h"
-#include "nsc_mem.h"
-#include "nsc_rmspin.h"
-#include "../nsctl.h"
-
-
-static kmutex_t _nsc_rmspin_slp;
-
-nsc_rmlock_t _nsc_lock_top;
-kmutex_t _nsc_global_lock;
-int _nsc_global_lock_init;
-
-extern nsc_mem_t *_nsc_local_mem;
-
-/*
- * void
- * _nsc_init_rmlock (void)
- * Initialise global locks.
- *
- * Calling/Exit State:
- * Called at driver initialisation time to allocate necessary
- * data structures.
- */
-void
-_nsc_init_rmlock()
-{
- mutex_init(&_nsc_rmspin_slp, NULL, MUTEX_DRIVER, NULL);
-
- _nsc_lock_top.next = _nsc_lock_top.prev = &_nsc_lock_top;
-
- mutex_init(&_nsc_global_lock, NULL, MUTEX_DRIVER, NULL);
- _nsc_global_lock_init = 1;
-}
-
-
-/*
- * void
- * _nsc_deinit_rmlock (void)
- * De-initialise global locks.
- *
- * Calling/Exit State:
- * Called at driver unload time to de-allocate
- * resources.
- */
-void
-_nsc_deinit_rmlock()
-{
- _nsc_global_lock_init = 0;
- mutex_destroy(&_nsc_global_lock);
-
- ASSERT(_nsc_lock_top.next == &_nsc_lock_top);
- ASSERT(_nsc_lock_top.prev == &_nsc_lock_top);
-
- mutex_destroy(&_nsc_rmspin_slp);
-}
-
-
-/*
- * int
- * _nsc_lock_all_rm (void)
- * Take all global locks in address order.
- *
- * Calling/Exit State:
- * Returns 0 if _nsc_unlock_all_rm() should be called, or -1.
- */
-int
-_nsc_lock_all_rm()
-{
- nsc_rmlock_t *lp;
-
- mutex_enter(&_nsc_rmspin_slp);
-
- for (lp = _nsc_lock_top.next; lp != &_nsc_lock_top; lp = lp->next) {
- (void) nsc_rm_lock(lp);
- }
-
- return (0);
-}
-
-
-/*
- * void
- * _nsc_unlock_all_rm (void)
- * Release all global locks in reverse address order.
- *
- * Calling/Exit State:
- */
-void
-_nsc_unlock_all_rm()
-{
- nsc_rmlock_t *lp;
-
- for (lp = _nsc_lock_top.prev; lp != &_nsc_lock_top; lp = lp->prev) {
- nsc_rm_unlock(lp);
- }
-
- mutex_exit(&_nsc_rmspin_slp);
-}
-
-
-/*
- * nsc_rmlock_t *
- * nsc_rm_lock_alloc(char *name, int flag, void *arg)
- * Allocate and initialise a global lock.
- *
- * Calling/Exit State:
- * The 'flag' parameter should be either KM_SLEEP or KM_NOSLEEP,
- * depending on whether the caller is willing to sleep while memory
- * is allocated or not.
- *
- * The 'arg' parameter is passed directly to the underlying
- * mutex_init(9f) function call.
- *
- * Returns NULL if lock cannot be allocated.
- */
-nsc_rmlock_t *
-nsc_rm_lock_alloc(char *name, int flag, void *arg)
-{
- nsc_rmlock_t *lp, *lk;
-
- if ((lk = (nsc_rmlock_t *)nsc_kmem_zalloc(sizeof (*lk),
- flag, _nsc_local_mem)) == NULL)
- return (NULL);
-
- mutex_init(&lk->lockp, NULL, MUTEX_DRIVER, arg);
-
- mutex_enter(&_nsc_rmspin_slp);
-
- for (lp = _nsc_lock_top.next; lp != &_nsc_lock_top; lp = lp->next)
- if (strcmp(lp->name, name) == 0)
- break;
-
- if (lp != &_nsc_lock_top) {
- mutex_exit(&_nsc_rmspin_slp);
-
- mutex_destroy(&lk->lockp);
- nsc_kmem_free(lk, sizeof (*lk));
-
- cmn_err(CE_WARN, "!nsctl: rmlock double allocation (%s)", name);
- return (NULL);
- }
-
- lk->name = name;
-
- lk->next = _nsc_lock_top.next;
- lk->prev = &_nsc_lock_top;
- _nsc_lock_top.next = lk;
- lk->next->prev = lk;
-
- mutex_exit(&_nsc_rmspin_slp);
-
- return (lk);
-}
-
-
-/*
- * void
- * nsc_rm_lock_destroy(nsc_rmlock_t *rmlockp)
- * Release the global lock.
- *
- * Remarks:
- * The specified global lock is released and made
- * available for reallocation.
- */
-void
-nsc_rm_lock_dealloc(rmlockp)
-nsc_rmlock_t *rmlockp;
-{
- if (!rmlockp)
- return;
-
- mutex_enter(&_nsc_rmspin_slp);
-
- rmlockp->next->prev = rmlockp->prev;
- rmlockp->prev->next = rmlockp->next;
-
- if (rmlockp->child) {
- cmn_err(CE_WARN, "!nsctl: rmlock destroyed when locked (%s)",
- rmlockp->name);
- nsc_do_unlock(rmlockp->child);
- rmlockp->child = NULL;
- }
-
- mutex_destroy(&rmlockp->lockp);
- mutex_exit(&_nsc_rmspin_slp);
-
- nsc_kmem_free(rmlockp, sizeof (*rmlockp));
-}
-
-
-/*
- * void
- * nsc_rm_lock(nsc_rmlock_t *rmlockp)
- * Acquire a global lock.
- *
- * Calling/Exit State:
- * rmlockp is the lock to be acquired.
- * Returns 0 (success) or errno. Lock is not acquired if rc != 0.
- */
-int
-nsc_rm_lock(nsc_rmlock_t *rmlockp)
-{
- int rc;
-
- mutex_enter(&rmlockp->lockp);
-
- ASSERT(! rmlockp->child);
-
- /* always use a write-lock */
- rc = nsc_do_lock(1, &rmlockp->child);
- if (rc) {
- rmlockp->child = NULL;
- mutex_exit(&rmlockp->lockp);
- }
-
- return (rc);
-}
-
-
-/*
- * static void
- * nsc_rm_unlock(nsc_rmlock_t *rmlockp)
- * Unlock a global lock.
- *
- * Calling/Exit State:
- * rmlockp is the lock to be released.
- */
-void
-nsc_rm_unlock(nsc_rmlock_t *rmlockp)
-{
- if (rmlockp->child) {
- ASSERT(MUTEX_HELD(&rmlockp->lockp));
- nsc_do_unlock(rmlockp->child);
- rmlockp->child = NULL;
- mutex_exit(&rmlockp->lockp);
- }
-}
diff --git a/usr/src/uts/common/avs/ns/nsctl/nsc_rmspin.h b/usr/src/uts/common/avs/ns/nsctl/nsc_rmspin.h
deleted file mode 100644
index 27051669ff..0000000000
--- a/usr/src/uts/common/avs/ns/nsctl/nsc_rmspin.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _NSC_RMSPIN_H
-#define _NSC_RMSPIN_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef __NSC_GEN__
-Error: Illegal #include - private file.
-#endif
-
-typedef struct nsc_rmlock_s {
- struct nsc_rmlock_s *next;
- struct nsc_rmlock_s *prev;
- char *name;
- void *child;
- kmutex_t lockp;
-} nsc_rmlock_t;
-
-
-extern int nsc_do_lock(int, void **);
-extern void nsc_do_unlock(void *);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _NSC_RMSPIN_H */
diff --git a/usr/src/uts/common/avs/ns/nsctl/nsc_trap.c b/usr/src/uts/common/avs/ns/nsctl/nsc_trap.c
deleted file mode 100644
index e66a04b71e..0000000000
--- a/usr/src/uts/common/avs/ns/nsctl/nsc_trap.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/ddi.h>
-#include <sys/sunddi.h>
-
-#ifdef DS_DDICT
-#include "../contract.h"
-#endif
-
-#define SVE_STE_CLASS "SVE_STE"
-#define SVE_II_CLASS "SVE_II"
-#define SVE_CACHE_CLASS "SVE_CACHE"
-
-void
-nsc_do_sysevent(char *driver_name, char *trap_messages, int errorno,
- int alertlevel, char *component, dev_info_t *info_dip)
-{
-#if !defined(DS_DDICT) && !defined(_SunOS_5_6) && \
- !defined(_SunOS_5_7) && !defined(_SunOS_5_8)
-
- nvlist_t *attr_list;
- int rc;
-
- attr_list = NULL;
- rc = nvlist_alloc(&attr_list, NV_UNIQUE_NAME_TYPE, KM_SLEEP);
- if (rc != 0) {
- goto out;
- }
- rc = nvlist_add_int32(attr_list, "alertlevel", alertlevel);
- if (rc != 0) {
- goto out;
- }
- rc = nvlist_add_string(attr_list, "messagevalue", trap_messages);
- if (rc != 0) {
- goto out;
- }
- rc = nvlist_add_int32(attr_list, "errorno", errorno);
- if (rc != 0) {
- goto out;
- }
- if (strcmp(driver_name, "sdbc") == 0)
- rc = ddi_log_sysevent(info_dip, DDI_VENDOR_SUNW,
- SVE_CACHE_CLASS, component, attr_list, NULL, DDI_SLEEP);
- else if (strcmp(driver_name, "ste") == 0)
- rc = ddi_log_sysevent(info_dip, DDI_VENDOR_SUNW,
- SVE_STE_CLASS, component, attr_list, NULL, DDI_SLEEP);
- else if (strcmp(driver_name, "ii") == 0)
- rc = ddi_log_sysevent(info_dip, DDI_VENDOR_SUNW,
- SVE_II_CLASS, component, attr_list, NULL, DDI_SLEEP);
-out:
- nvlist_free(attr_list);
-
- if (rc != 0) {
- cmn_err(CE_WARN, "!%s: unable to log sysevent %d:%s and %d",
- driver_name, errorno, trap_messages, alertlevel);
- }
-#endif /* which O/S? */
-}
diff --git a/usr/src/uts/common/avs/ns/nsctl/nsctl.c b/usr/src/uts/common/avs/ns/nsctl/nsctl.c
deleted file mode 100644
index b76e12bf33..0000000000
--- a/usr/src/uts/common/avs/ns/nsctl/nsctl.c
+++ /dev/null
@@ -1,923 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- * Copyright 2012 Milan Jurik. All rights reserved.
- */
-
-#include <sys/types.h>
-#include <sys/ksynch.h>
-#include <sys/kmem.h>
-#include <sys/file.h>
-#include <sys/errno.h>
-#include <sys/open.h>
-#include <sys/cred.h>
-#include <sys/conf.h>
-#include <sys/uio.h>
-#include <sys/cmn_err.h>
-#include <sys/modctl.h>
-#include <sys/ddi.h>
-
-#define __NSC_GEN__
-#include <sys/nsctl/nsc_dev.h>
-#include <sys/nsctl/nsc_gen.h>
-#include <sys/nsctl/nsc_ioctl.h>
-#include <sys/nsctl/nsc_power.h>
-#include <sys/nsctl/nsc_mem.h>
-#include "../nsctl.h"
-
-#include <sys/nsctl/nsvers.h>
-
-#ifdef DS_DDICT
-#include "../contract.h"
-#endif
-
-extern void nscsetup();
-extern int _nsc_init_raw(int);
-extern void _nsc_deinit_raw();
-extern void _nsc_init_start();
-extern void _nsc_init_os(), _nsc_deinit_os();
-extern void _nsc_init_dev(), _nsc_init_mem();
-extern void _nsc_init_gen(), _nsc_init_rmlock();
-extern void _nsc_init_resv(), _nsc_deinit_resv();
-extern void _nsc_init_frz(), _nsc_deinit_frz();
-extern void _nsc_init_ncio(), _nsc_deinit_ncio();
-extern void _nsc_deinit_mem(), _nsc_deinit_rmlock();
-extern void _nsc_deinit_dev();
-
-extern int _nsc_frz_start(char *, int *);
-extern int _nsc_frz_stop(char *, int *);
-extern int _nsc_frz_isfrozen(char *, int *);
-
-extern nsc_mem_t *_nsc_local_mem;
-extern nsc_rmhdr_t *_nsc_rmhdr_ptr;
-extern nsc_def_t _nsc_raw_def[];
-extern int _nsc_raw_flags;
-
-int nsc_devflag = D_MP;
-
-int _nsc_init_done = 0;
-
-kmutex_t _nsc_drv_lock;
-nsc_io_t *_nsc_file_io;
-nsc_io_t *_nsc_vchr_io;
-nsc_io_t *_nsc_raw_io;
-
-nsc_fd_t **_nsc_minor_fd;
-kmutex_t **_nsc_minor_slp;
-
-
-/* Maximum number of devices - tunable in nsctl.conf */
-static int _nsc_max_devices;
-
-/* Internal version of _nsc_max_devices */
-int _nsc_maxdev;
-
-extern void _nsc_global_setup(void);
-
-static int nsc_load(), nsc_unload();
-static void nscteardown();
-
-/*
- * Solaris specific driver module interface code.
- */
-
-extern int nscopen(dev_t *, int, int, cred_t *);
-extern int nscioctl(dev_t, int, intptr_t, int, cred_t *, int *);
-extern int nscclose(dev_t, int, int, cred_t *);
-extern int nscread(dev_t, uio_t *, cred_t *);
-extern int nscwrite(dev_t, uio_t *, cred_t *);
-
-static dev_info_t *nsctl_dip; /* Single DIP for driver */
-
-static int _nsctl_print(dev_t, char *);
-
-static struct cb_ops nsctl_cb_ops = {
- nscopen, /* open */
- nscclose, /* close */
- nodev, /* not a block driver, strategy not an entry point */
- _nsctl_print, /* no print routine */
- nodev, /* no dump routine */
- nscread, /* read */
- nscwrite, /* write */
- (int (*)()) nscioctl, /* ioctl */
- nodev, /* no devmap routine */
- nodev, /* no mmap routine */
- nodev, /* no segmap routine */
- nochpoll, /* no chpoll routine */
- ddi_prop_op,
- 0, /* not a STREAMS driver, no cb_str routine */
- D_NEW | D_MP | D_64BIT, /* safe for multi-thread/multi-processor */
- CB_REV,
- nodev, /* aread */
- nodev, /* awrite */
-};
-
-static int _nsctl_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
-static int _nsctl_attach(dev_info_t *, ddi_attach_cmd_t);
-static int _nsctl_detach(dev_info_t *, ddi_detach_cmd_t);
-
-static struct dev_ops nsctl_ops = {
- DEVO_REV, /* Driver build version */
- 0, /* device reference count */
- _nsctl_getinfo,
- nulldev, /* Identify */
- nulldev, /* Probe */
- _nsctl_attach,
- _nsctl_detach,
- nodev, /* Reset */
- &nsctl_cb_ops,
- (struct bus_ops *)0
-};
-
-static struct modldrv nsctl_ldrv = {
- &mod_driverops,
- "nws:Control:" ISS_VERSION_STR,
- &nsctl_ops
-};
-
-static struct modlinkage nsctl_modlinkage = {
- MODREV_1,
- &nsctl_ldrv,
- NULL
-};
-
-/*
- * Solaris module load time code
- */
-
-int nsc_min_nodeid;
-int nsc_max_nodeid;
-
-int
-_init(void)
-{
- int err;
-
- err = nsc_load();
-
- if (!err)
- err = mod_install(&nsctl_modlinkage);
-
- if (err) {
- (void) nsc_unload();
- cmn_err(CE_NOTE, "!nsctl_init: err %d", err);
- }
-
- return (err);
-
-}
-
-/*
- * Solaris module unload time code
- */
-
-int
-_fini(void)
-{
- int err;
-
- if ((err = mod_remove(&nsctl_modlinkage)) == 0) {
- err = nsc_unload();
- }
- return (err);
-}
-
-/*
- * Solaris module info code
- */
-int
-_info(struct modinfo *modinfop)
-{
- return (mod_info(&nsctl_modlinkage, modinfop));
-}
-
-/*
- * Attach an instance of the device. This happens before an open
- * can succeed.
- */
-static int
-_nsctl_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
-{
- int rc;
-
- if (cmd == DDI_ATTACH) {
- nsctl_dip = dip;
-
- /* Announce presence of the device */
- ddi_report_dev(dip);
-
- /*
- * Get the node parameters now that we can look up.
- */
- nsc_min_nodeid = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
- "nsc_min_nodeid", 0);
-
- nsc_max_nodeid = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
- "nsc_max_nodeid", 5);
-
- _nsc_max_devices = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
- "nsc_max_devices", 128);
-
- _nsc_maxdev = _nsc_max_devices;
- nscsetup();
-
- /*
- * Init raw requires the _nsc_max_devices value and so
- * cannot be done before the nsc_max_devices property has
- * been read which can only be done after the module is
- * attached and we have a dip.
- */
-
- if ((rc = _nsc_init_raw(_nsc_max_devices)) != 0) {
- cmn_err(CE_WARN,
- "!nsctl: unable to initialize raw io provider: %d",
- rc);
- return (DDI_FAILURE);
- }
-
- /*
- * Init rest of soft state structure
- */
-
- rc = ddi_create_minor_node(dip, "c,nsctl", S_IFCHR, 0,
- DDI_PSEUDO, 0);
- if (rc != DDI_SUCCESS) {
- /* free anything we allocated here */
- cmn_err(CE_WARN,
- "!_nsctl_attach: ddi_create_minor_node failed %d",
- rc);
- return (DDI_FAILURE);
- }
-
- /* Announce presence of the device */
- ddi_report_dev(dip);
-
- /* mark the device as attached, opens may proceed */
- return (DDI_SUCCESS);
- } else
- return (DDI_FAILURE);
-}
-
-static int
-_nsctl_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
-{
- if (cmd == DDI_DETACH) {
- nscteardown();
- _nsc_deinit_raw();
-
- ddi_remove_minor_node(dip, NULL);
- nsctl_dip = NULL;
-
- return (DDI_SUCCESS);
- }
- else
- return (DDI_FAILURE);
-}
-
-
-/* ARGSUSED */
-static int
-_nsctl_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
-{
- dev_t dev;
- int rc;
-
- switch (cmd) {
- case DDI_INFO_DEVT2INSTANCE:
- /* The "instance" number is the minor number */
- dev = (dev_t)arg;
- *result = (void *)(unsigned long)getminor(dev);
- rc = DDI_SUCCESS;
- break;
-
- case DDI_INFO_DEVT2DEVINFO:
- *result = nsctl_dip;
- rc = DDI_SUCCESS;
- break;
-
- default:
- rc = DDI_FAILURE;
- break;
- }
-
- return (rc);
-}
-
-
-/* ARGSUSED */
-static int
-_nsctl_print(dev_t dev, char *s)
-{
- cmn_err(CE_WARN, "!nsctl:%s", s);
- return (0);
-}
-
-
-void
-nsc_init()
-{
- if (_nsc_init_done)
- return;
-
- _nsc_init_start();
- _nsc_init_gen();
- _nsc_init_svc();
- _nsc_init_mem();
- _nsc_init_dev();
- _nsc_init_rmlock();
- _nsc_init_resv();
- _nsc_init_os();
- (void) _nsc_init_power();
-
- /*
- * When using mc, nscsetup is done through mc callback to global_init.
- */
- nscsetup();
-
- mutex_init(&_nsc_drv_lock, NULL, MUTEX_DRIVER, NULL);
-
- _nsc_raw_io = nsc_register_io("raw",
- NSC_RAW_ID | _nsc_raw_flags, _nsc_raw_def);
-
- if (!_nsc_raw_io)
- cmn_err(CE_WARN, "!_nsc_init: register io failed - raw");
-
- _nsc_init_ncio();
- _nsc_init_frz();
-
- _nsc_init_done = 1;
-}
-
-
-/*
- * Called after the mc refresh is complete (SEG_INIT callbacks have
- * been received) and module _attach() is done. Only does any real
- * work when all of the above conditions have been met.
- */
-void
-nscsetup()
-{
- if (nsc_max_devices() == 0 || _nsc_minor_fd != NULL)
- return;
-
- _nsc_minor_fd = nsc_kmem_zalloc(sizeof (nsc_fd_t *)*_nsc_maxdev,
- 0, _nsc_local_mem);
-
- if (!_nsc_minor_fd) {
- cmn_err(CE_WARN, "!nscsetup - alloc failed");
- return;
- }
-
- _nsc_minor_slp = nsc_kmem_zalloc(sizeof (kmutex_t *)*_nsc_maxdev,
- 0, _nsc_local_mem);
-
- if (!_nsc_minor_slp) {
- cmn_err(CE_WARN, "!nscsetup - alloc failed");
- nsc_kmem_free(_nsc_minor_fd, sizeof (nsc_fd_t *) * _nsc_maxdev);
- _nsc_minor_fd = (nsc_fd_t **)NULL;
- }
-}
-
-static void
-nscteardown()
-{
- int i;
-
- if (_nsc_minor_fd == NULL)
- return;
-
-#ifdef DEBUG
- /* Check all devices were closed. Index 0 is the prototype dev. */
- for (i = 1; i < _nsc_maxdev; i++) {
- ASSERT(_nsc_minor_slp[i] == NULL);
- ASSERT(_nsc_minor_fd[i] == NULL);
- }
-#endif /* DEBUG */
-
- nsc_kmem_free(_nsc_minor_fd, sizeof (nsc_fd_t *) * _nsc_maxdev);
- nsc_kmem_free(_nsc_minor_slp, sizeof (kmutex_t *) * _nsc_maxdev);
-
- _nsc_minor_fd = (nsc_fd_t **)NULL;
- _nsc_minor_slp = (kmutex_t **)NULL;
-}
-
-int
-nsc_load()
-{
- nsc_init();
- return (0);
-}
-
-
-int
-nsc_unload()
-{
- if (!_nsc_init_done) {
- return (0);
- }
-
- nscteardown();
-
- (void) _nsc_deinit_power();
- _nsc_deinit_resv();
- _nsc_deinit_mem();
- _nsc_deinit_rmlock();
- _nsc_deinit_svc();
- _nsc_deinit_frz();
- _nsc_deinit_ncio();
-
- if (_nsc_vchr_io)
- (void) nsc_unregister_io(_nsc_vchr_io, 0);
-
- if (_nsc_file_io)
- (void) nsc_unregister_io(_nsc_file_io, 0);
-
- _nsc_vchr_io = NULL;
- _nsc_file_io = NULL;
-
- if (_nsc_raw_io)
- (void) nsc_unregister_io(_nsc_raw_io, 0);
-
- _nsc_raw_io = NULL;
-
- _nsc_deinit_dev();
- _nsc_deinit_os();
-
- _nsc_init_done = 0;
- return (0);
-}
-
-
-/* ARGSUSED */
-
-int
-nscopen(dev_t *devp, int flag, int otyp, cred_t *crp)
-{
- kmutex_t *slp;
- int i, error;
-
- if (error = drv_priv(crp))
- return (error);
-
- if (!_nsc_minor_fd || !_nsc_minor_slp)
- return (ENXIO);
-
- if (getminor(*devp) != 0)
- return (ENXIO);
-
- slp = nsc_kmem_alloc(sizeof (kmutex_t), 0, _nsc_local_mem);
- mutex_init(slp, NULL, MUTEX_DRIVER, NULL);
-
- mutex_enter(&_nsc_drv_lock);
-
- for (i = 1; i < _nsc_maxdev; i++) {
- if (_nsc_minor_slp[i] == NULL) {
- _nsc_minor_slp[i] = slp;
- break;
- }
- }
-
- mutex_exit(&_nsc_drv_lock);
-
- if (i >= _nsc_maxdev) {
- mutex_destroy(slp);
- nsc_kmem_free(slp, sizeof (kmutex_t));
- return (EAGAIN);
- }
-
- *devp = makedevice(getmajor(*devp), i);
-
- return (0);
-}
-
-
-int
-_nscopen(dev_t dev, intptr_t arg, int mode, int *rvp)
-{
- minor_t mindev = getminor(dev);
- struct nscioc_open *op;
- nsc_fd_t *fd;
- int rc;
-
- op = nsc_kmem_alloc(sizeof (*op), KM_SLEEP, _nsc_local_mem);
- if (op == NULL) {
- return (ENOMEM);
- }
-
- if (ddi_copyin((void *)arg, op, sizeof (*op), mode) < 0) {
- nsc_kmem_free(op, sizeof (*op));
- return (EFAULT);
- }
-
- mutex_enter(_nsc_minor_slp[mindev]);
-
- if (_nsc_minor_fd[mindev]) {
- mutex_exit(_nsc_minor_slp[mindev]);
- nsc_kmem_free(op, sizeof (*op));
- return (EBUSY);
- }
-
- op->path[sizeof (op->path)-1] = 0;
-
- fd = nsc_open(op->path, (op->flag & NSC_TYPES), 0, 0, &rc);
-
- if (fd == NULL) {
- mutex_exit(_nsc_minor_slp[mindev]);
- nsc_kmem_free(op, sizeof (*op));
- return (rc);
- }
-
- mode |= (op->mode - FOPEN);
-
- if (mode & (FWRITE|FEXCL)) {
- if ((rc = nsc_reserve(fd, NSC_PCATCH)) != 0) {
- mutex_exit(_nsc_minor_slp[mindev]);
- (void) nsc_close(fd);
- nsc_kmem_free(op, sizeof (*op));
- return (rc);
- }
- }
-
- *rvp = 0;
- _nsc_minor_fd[mindev] = fd;
-
- mutex_exit(_nsc_minor_slp[mindev]);
- nsc_kmem_free(op, sizeof (*op));
- return (0);
-}
-
-
-/* ARGSUSED */
-
-int
-nscclose(dev_t dev, int flag, int otyp, cred_t *crp)
-{
- minor_t mindev = getminor(dev);
- kmutex_t *slp;
- nsc_fd_t *fd;
-
- if (!_nsc_minor_fd || !_nsc_minor_slp)
- return (0);
-
- if ((slp = _nsc_minor_slp[mindev]) == 0)
- return (0);
-
- if ((fd = _nsc_minor_fd[mindev]) != NULL)
- (void) nsc_close(fd);
-
- _nsc_minor_fd[mindev] = NULL;
- _nsc_minor_slp[mindev] = NULL;
-
- mutex_destroy(slp);
- nsc_kmem_free(slp, sizeof (kmutex_t));
- return (0);
-}
-
-
-/* ARGSUSED */
-
-int
-nscread(dev_t dev, uio_t *uiop, cred_t *crp)
-{
- minor_t mindev = getminor(dev);
- int rc, resv;
- nsc_fd_t *fd;
-
- if ((fd = _nsc_minor_fd[mindev]) == 0)
- return (EIO);
-
- mutex_enter(_nsc_minor_slp[mindev]);
-
- resv = (nsc_held(fd) == 0);
-
- if (resv && (rc = nsc_reserve(fd, NSC_PCATCH)) != 0) {
- mutex_exit(_nsc_minor_slp[mindev]);
- return (rc);
- }
-
- rc = nsc_uread(fd, uiop, crp);
-
- if (resv)
- nsc_release(fd);
-
- mutex_exit(_nsc_minor_slp[mindev]);
- return (rc);
-}
-
-
-/* ARGSUSED */
-
-int
-nscwrite(dev_t dev, uio_t *uiop, cred_t *crp)
-{
- minor_t mindev = getminor(dev);
- int rc, resv;
- nsc_fd_t *fd;
-
- if ((fd = _nsc_minor_fd[mindev]) == 0)
- return (EIO);
-
- mutex_enter(_nsc_minor_slp[mindev]);
-
- resv = (nsc_held(fd) == 0);
-
- if (resv && (rc = nsc_reserve(fd, NSC_PCATCH)) != 0) {
- mutex_exit(_nsc_minor_slp[mindev]);
- return (rc);
- }
-
- rc = nsc_uwrite(fd, uiop, crp);
-
- if (resv)
- nsc_release(fd);
-
- mutex_exit(_nsc_minor_slp[mindev]);
- return (rc);
-}
-
-
-int
-_nscreserve(dev_t dev, int *rvp)
-{
- minor_t mindev = getminor(dev);
- nsc_fd_t *fd;
- int rc;
-
- if ((fd = _nsc_minor_fd[mindev]) == 0)
- return (EIO);
-
- mutex_enter(_nsc_minor_slp[mindev]);
-
- if (nsc_held(fd)) {
- mutex_exit(_nsc_minor_slp[mindev]);
- return (EBUSY);
- }
-
- if ((rc = nsc_reserve(fd, NSC_PCATCH)) != 0) {
- mutex_exit(_nsc_minor_slp[mindev]);
- return (rc);
- }
-
- *rvp = 0;
-
- mutex_exit(_nsc_minor_slp[mindev]);
- return (0);
-}
-
-
-int
-_nscrelease(dev_t dev, int *rvp)
-{
- minor_t mindev = getminor(dev);
- nsc_fd_t *fd;
-
- if ((fd = _nsc_minor_fd[mindev]) == 0)
- return (EIO);
-
- mutex_enter(_nsc_minor_slp[mindev]);
-
- if (!nsc_held(fd)) {
- mutex_exit(_nsc_minor_slp[mindev]);
- return (EINVAL);
- }
-
- nsc_release(fd);
-
- *rvp = 0;
-
- mutex_exit(_nsc_minor_slp[mindev]);
- return (0);
-}
-
-
-int
-_nscpartsize(dev_t dev, intptr_t arg, int mode)
-{
- struct nscioc_partsize partsize;
- minor_t mindev = getminor(dev);
- nsc_size_t size;
- int rc, resv;
- nsc_fd_t *fd;
-
- if ((fd = _nsc_minor_fd[mindev]) == 0)
- return (EIO);
-
- mutex_enter(_nsc_minor_slp[mindev]);
-
- resv = (nsc_held(fd) == 0);
-
- if (resv && (rc = nsc_reserve(fd, NSC_PCATCH)) != 0) {
- mutex_exit(_nsc_minor_slp[mindev]);
- return (rc);
- }
-
- rc = nsc_partsize(fd, &size);
- partsize.partsize = (uint64_t)size;
-
- if (resv)
- nsc_release(fd);
-
- mutex_exit(_nsc_minor_slp[mindev]);
-
- if (ddi_copyout((void *)&partsize, (void *)arg,
- sizeof (partsize), mode) < 0) {
- return (EFAULT);
- }
-
- return (rc);
-}
-
-
-/* ARGSUSED */
-
-int
-nscioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *crp, int *rvp)
-{
- struct nscioc_bsize *bsize = NULL;
- char *path = NULL;
- int rc = 0;
-
- *rvp = 0;
-
- switch (cmd) {
- case NSCIOC_OPEN:
- rc = _nscopen(dev, arg, mode, rvp);
- break;
-
- case NSCIOC_RESERVE:
- rc = _nscreserve(dev, rvp);
- break;
-
- case NSCIOC_RELEASE:
- rc = _nscrelease(dev, rvp);
- break;
-
- case NSCIOC_PARTSIZE:
- rc = _nscpartsize(dev, arg, mode);
- break;
-
- case NSCIOC_FREEZE:
- path = nsc_kmem_alloc(NSC_MAXPATH, KM_SLEEP, _nsc_local_mem);
- if (path == NULL) {
- rc = ENOMEM;
- break;
- }
- if (ddi_copyin((void *)arg, path, NSC_MAXPATH, mode) < 0)
- rc = EFAULT;
- else {
- path[NSC_MAXPATH-1] = 0;
- rc = _nsc_frz_start(path, rvp);
- }
- break;
-
- case NSCIOC_UNFREEZE:
- path = nsc_kmem_alloc(NSC_MAXPATH, KM_SLEEP, _nsc_local_mem);
- if (path == NULL) {
- rc = ENOMEM;
- break;
- }
- if (ddi_copyin((void *)arg, path, NSC_MAXPATH, mode) < 0)
- rc = EFAULT;
- else {
- path[NSC_MAXPATH-1] = 0;
- rc = _nsc_frz_stop(path, rvp);
- }
- break;
-
- case NSCIOC_ISFROZEN:
- path = nsc_kmem_alloc(NSC_MAXPATH, KM_SLEEP, _nsc_local_mem);
- if (path == NULL) {
- rc = ENOMEM;
- break;
- }
- if (ddi_copyin((void *)arg, path, NSC_MAXPATH, mode) < 0)
- rc = EFAULT;
- else {
- path[NSC_MAXPATH-1] = 0;
- rc = _nsc_frz_isfrozen(path, rvp);
- }
- break;
-
-#ifdef ENABLE_POWER_MSG
- case NSCIOC_POWERMSG:
- rc = _nsc_power((void *)arg, rvp);
- break;
-#endif
-
- case NSCIOC_NSKERND:
- rc = nskernd_command(arg, mode, rvp);
- break;
-
- /* return sizes of global memory segments */
- case NSCIOC_GLOBAL_SIZES:
- if (!_nsc_init_done) {
- rc = EINVAL;
- break;
- }
-
- rc = _nsc_get_global_sizes((void *)arg, rvp);
-
- break;
-
- /* return contents of global segments */
- case NSCIOC_GLOBAL_DATA:
- if (!_nsc_init_done) {
- rc = EINVAL;
- break;
- }
-
- rc = _nsc_get_global_data((void *)arg, rvp);
- break;
-
- /*
- * nvmem systems:
- * clear the hdr dirty bit to prevent loading from nvme on reboot
- */
- case NSCIOC_NVMEM_CLEANF:
- rc = _nsc_clear_dirty(1); /* dont be nice about it */
- break;
- case NSCIOC_NVMEM_CLEAN:
- rc = _nsc_clear_dirty(0);
- break;
-
- case NSCIOC_BSIZE:
- bsize = nsc_kmem_alloc(sizeof (*bsize), KM_SLEEP,
- _nsc_local_mem);
- if (bsize == NULL) {
- rc = ENOMEM;
- break;
- }
-
- if (ddi_copyin((void *)arg, bsize, sizeof (*bsize), mode) < 0) {
- rc = EFAULT;
- break;
- }
-
- rc = nskern_bsize(bsize, rvp);
- if (rc == 0) {
- if (ddi_copyout(bsize, (void *)arg,
- sizeof (*bsize), mode) < 0) {
- rc = EFAULT;
- break;
- }
- }
-
- break;
-
- default:
- return (ENOTTY);
- }
-
- if (bsize != NULL) {
- nsc_kmem_free(bsize, sizeof (*bsize));
- bsize = NULL;
- }
- if (path != NULL) {
- nsc_kmem_free(path, NSC_MAXPATH);
- path = NULL;
- }
- return (rc);
-}
-
-
-int
-nsc_max_devices(void)
-{
- return (_nsc_max_devices);
-}
-
-
-/*
- * Used by _nsc_global_setup() in case nvram is dirty and has saved a different
- * value for nsc_max_devices. We need to use the saved value, not the new
- * one configured by the user.
- */
-void
-_nsc_set_max_devices(int maxdev)
-{
- _nsc_max_devices = maxdev;
- _nsc_maxdev = _nsc_max_devices;
-}
diff --git a/usr/src/uts/common/avs/ns/nsctl/nsctl.conf b/usr/src/uts/common/avs/ns/nsctl/nsctl.conf
deleted file mode 100644
index 1d69f34610..0000000000
--- a/usr/src/uts/common/avs/ns/nsctl/nsctl.conf
+++ /dev/null
@@ -1,41 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# NSCTL Solaris configuration properties
-#
-#
-name="nsctl" parent="pseudo" instance=0;
-
-#
-# Configurable maximum and minimum nodeids that can be used by the
-# StorageTek Data Services.
-# Usually should not be changed.
-#
-nsc_min_nodeid=0 nsc_max_nodeid=5;
-
-#
-# Configurable maximum number of devices that can be handled by the
-# StorageTek Data Services. A larger value will consume more memory.
-# BugId 4729454: increased to 4096 for SVE.
-#
-nsc_max_devices=4096;
diff --git a/usr/src/uts/common/avs/ns/nsctl/nsvers.h b/usr/src/uts/common/avs/ns/nsctl/nsvers.h
deleted file mode 100644
index ca0a21555f..0000000000
--- a/usr/src/uts/common/avs/ns/nsctl/nsvers.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _NSVERS_H
-#define _NSVERS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef _VERSION_
-#define _VERSION_ "SunOS 5.11"
-#endif
-
-#ifndef ISS_VERSION_STR
-#define ISS_VERSION_STR "SunOS 5.11"
-#endif
-
-#ifndef ISS_VERSION_NUM
-#define ISS_VERSION_NUM 61
-#endif
-
-#ifndef ISS_VERSION_MAJ
-#define ISS_VERSION_MAJ 11
-#endif
-
-#ifndef ISS_VERSION_MIN
-#define ISS_VERSION_MIN 11
-#endif
-
-#ifndef ISS_VERSION_MIC
-#define ISS_VERSION_MIC 0
-#endif
-
-#ifndef BUILD_DATE_STR
-#define BUILD_DATE_STR "None"
-#endif
-
-#ifndef SCMTEST_MAJOR_VERSION
-#define SCMTEST_MAJOR_VERSION "0"
-#endif
-
-#ifndef SCMTEST_MINOR_VERSION
-#define SCMTEST_MINOR_VERSION "0"
-#endif
-
-#ifndef SCMTEST_PATCH_VERSION
-#define SCMTEST_PATCH_VERSION "0"
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _NSVERS_H */
diff --git a/usr/src/uts/common/avs/ns/nsctl_inter.h b/usr/src/uts/common/avs/ns/nsctl_inter.h
deleted file mode 100644
index e61a1d3536..0000000000
--- a/usr/src/uts/common/avs/ns/nsctl_inter.h
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SYS_NSCTL_INTER_H
-#define _SYS_NSCTL_INTER_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define __NSC_GEN__
-#include <sys/ksynch.h>
-#include <sys/nsctl/nsc_dev.h>
-#include <sys/nsctl/nsc_gen.h>
-#include <sys/nsctl/nsc_mem.h>
-#include <sys/nsctl/nsc_rmspin.h>
-
-#ifdef _KERNEL
-
-#include <sys/nsc_ddi.h>
-
-/* prevent errors from typedefs not defined until after this is included */
-typedef int nsc_size_t;
-typedef int nsc_off_t;
-
-int nsc_inval() { }
-int nsc_ioerr() { }
-int nsc_fatal() { }
-int nsc_null() { }
-int nsc_true() { }
-void nsc_decode_param(void *, void *, void *) { }
-int nskernd_isdaemon() { }
-uchar_t nsc_ldstub(uchar_t *) { }
-void nsc_membar_stld(void) { }
-
-#ifndef _BLIND_T
-typedef void * blind_t;
-#endif
-typedef void strategy_fn_t;
-nsc_io_t *nsc_register_io(char *, int, void *) { }
-int nsc_unregister_io(nsc_io_t *, int) { }
-nsc_path_t *nsc_register_path(char *, int, nsc_io_t *) { }
-int nsc_unregister_path(nsc_path_t *, int) { }
-int nsc_cache_sizes(int *, int *) { }
-int nsc_register_down(void (*)()) { }
-int nsc_node_hints(unsigned int *) { }
-int nsc_node_hints_set(unsigned int) { }
-blind_t nsc_register_power(char *, void *) { }
-int nsc_unregister_power(blind_t) { }
-strategy_fn_t nsc_get_strategy(major_t) { }
-void *nsc_get_devops(major_t) { }
-void nsc_do_sysevent(char *, char *, int, int, char *, dev_info_t *) { }
-nsc_fd_t *nsc_open(char *, int, void *, blind_t, int *) { }
-int nsc_close(nsc_fd_t *) { }
-char *nsc_pathname(nsc_fd_t *) { }
-int nsc_shared(nsc_fd_t *) { }
-int nsc_setval(nsc_fd_t *, char *, int) { }
-int nsc_getval(nsc_fd_t *, char *, int *) { }
-int nsc_set_trksize(nsc_fd_t *, int) { }
-int nsc_discard_pinned(nsc_fd_t *, int, int) { }
-kmutex_t *nsc_lock_addr(nsc_fd_t *) { }
-int nsc_attach(nsc_fd_t *, int) { }
-int nsc_reserve(nsc_fd_t *, int) { }
-void nsc_reserve_lk(nsc_fd_t *) { }
-void nsc_release(nsc_fd_t *) { }
-int nsc_release_lk(nsc_fd_t *) { }
-int nsc_detach(nsc_fd_t *, int) { }
-int nsc_avail(nsc_fd_t *) { }
-int nsc_held(nsc_fd_t *) { }
-int nsc_waiting(nsc_fd_t *) { }
-int nsc_partsize(nsc_fd_t *, nsc_size_t *) { }
-int nsc_maxfbas(nsc_fd_t *, int, nsc_size_t *) { }
-int nsc_control(nsc_fd_t *, int, void *, int) { }
-int nsc_get_pinned(nsc_fd_t *) { }
-int nsc_max_devices(void) { }
-
-void nsc_set_owner(nsc_fd_t *, nsc_iodev_t *) { }
-void nsc_pinned_data(nsc_iodev_t *, int, int) { }
-void nsc_unpinned_data(nsc_iodev_t *, int, int) { }
-int nsc_alloc_buf(nsc_fd_t *, nsc_off_t, nsc_size_t, int, void **) { }
-int nsc_alloc_abuf(nsc_off_t, nsc_size_t, int, void **) { }
-int nsc_read(void *, nsc_off_t, nsc_size_t, int) { }
-int nsc_write(void *, nsc_off_t, nsc_size_t, int) { }
-int nsc_zero(void *, nsc_off_t, nsc_size_t, int) { }
-int nsc_copy(void *, void *, nsc_off_t, nsc_off_t, nsc_size_t) { }
-int nsc_copy_direct(void *, void *, nsc_off_t, nsc_off_t, nsc_size_t) { }
-int nsc_uncommit(void *, nsc_off_t, nsc_size_t, int) { }
-int nsc_free_buf(void *) { }
-void *nsc_alloc_handle(nsc_fd_t *,
- void (*)(), void (*)(), void (*)()) { }
-int nsc_free_handle(void *) { }
-int nsc_uread(nsc_fd_t *, void *, void *) { }
-int nsc_uwrite(nsc_fd_t *, void *, void *) { }
-
-nsc_rmlock_t *nsc_rm_lock_alloc(char *, int, void *) { }
-void nsc_rm_lock_dealloc(nsc_rmlock_t *) { }
-int nsc_rm_lock(nsc_rmlock_t *) { }
-void nsc_rm_unlock(nsc_rmlock_t *) { }
-
-void *nsc_register_mem(char *, int, int) { }
-void nsc_unregister_mem(void *) { }
-void *nsc_kmem_alloc(size_t, int, void *) { }
-void *nsc_kmem_zalloc(size_t, int, void *) { }
-void nsc_kmem_free(void *, size_t) { }
-void nsc_mem_sizes(void *, size_t *, size_t *, size_t *) { }
-size_t nsc_mem_avail(void *) { }
-
-int nsc_commit_mem(void *, void *, size_t, void) { }
-
-void nsc_cm_errhdlr(void *, void *, size_t, int) { }
-
-nsc_svc_t *nsc_register_svc(char *, void (*)(intptr_t)) { }
-int nsc_unregister_svc(nsc_svc_t *) { }
-int nsc_call_svc(nsc_svc_t *, intptr_t) { }
-
-char *nsc_strdup(char *) { }
-void nsc_strfree(char *) { }
-int nsc_strmatch(char *, char *) { }
-void nsc_sprintf(char *, char *, ...) { }
-int nsc_max_nodeid, nsc_min_nodeid;
-int nsc_nodeid_data(void) { }
-int nsc_node_id(void) { }
-int nsc_node_up(int) { }
-char *nsc_node_name(void) { }
-time_t nsc_time(void) { }
-clock_t nsc_lbolt(void) { }
-int nsc_delay_sig(clock_t) { }
-clock_t nsc_usec(void) { }
-void nsc_yield(void) { }
-int nsc_create_process(void (*)(void *), void *, boolean_t) { }
-int nsc_power_init(void) { }
-void nsc_power_deinit(void) { }
-void _nsc_global_nvmemmap_lookup(void *) { }
-void _nsc_mark_pages(void addr, void size, int dump) { }
-void _nsc_init_raw() { }
-void _nsc_deinit_raw() { }
-void _nsc_init_start() { }
-void _nsc_init_os() { }
-void _nsc_raw_flags() { }
-int _nsc_raw_def[1];
-void nskernd_command() { }
-void nskern_bsize() { }
-int nsc_do_lock() { }
-void nsc_do_unlock() { }
-int HZ;
-uint64_t nsc_strhash(char *) { }
-int nsc_fdpathcmp(void *, uint64_t, char *) { }
-char *nsc_caller() { }
-char *nsc_callee() { }
-void *nsc_threadp() { }
-
-/*
- * Misc stuff to make our life easier
- */
-#ifndef _VERSION_
-#define _VERSION_ "SunOS 5.11"
-#endif
-
-#ifndef ISS_VERSION_STR
-#define ISS_VERSION_STR "SunOS 5.11"
-#endif
-
-#ifndef ISS_VERSION_NUM
-#define ISS_VERSION_NUM 61
-#endif
-
-#ifndef ISS_VERSION_MAJ
-#define ISS_VERSION_MAJ 11
-#endif
-
-#ifndef ISS_VERSION_MIN
-#define ISS_VERSION_MIN 11
-#endif
-
-#ifndef ISS_VERSION_MIC
-#define ISS_VERSION_MIC 0
-#endif
-
-#ifndef BUILD_DATE_STR
-#define BUILD_DATE_STR "None"
-#endif
-
-#ifndef SCMTEST_MAJOR_VERSION
-#define SCMTEST_MAJOR_VERSION "0"
-#endif
-
-#ifndef SCMTEST_MINOR_VERSION
-#define SCMTEST_MINOR_VERSION "0"
-#endif
-
-#ifndef SCMTEST_PATCH_VERSION
-#define SCMTEST_PATCH_VERSION "0"
-#endif
-
-#endif /* _KERNEL */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SYS_NSCTL_INTER_H */
diff --git a/usr/src/uts/common/avs/ns/rdc/Makefile b/usr/src/uts/common/avs/ns/rdc/Makefile
deleted file mode 100644
index 91b1eb3d5b..0000000000
--- a/usr/src/uts/common/avs/ns/rdc/Makefile
+++ /dev/null
@@ -1,62 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#
-# include global definitions
-include ../../../../../Makefile.master
-
-HDRS= rdc.h \
- rdc_io.h \
- rdc_ioctl.h \
- rdc_bitmap.h \
- rdc_diskq.h
-
-DERIVED_HDRS= rdc_prot.h
-
-ROOTDIR= $(ROOT)/usr/include/sys/nsctl
-
-ROOTHDRS= $(HDRS:%=$(ROOTDIR)/%) $(DERIVED_HDRS:%=$(ROOTDIR)/%)
-
-# install rule
-$(ROOTDIR)/%: %
- $(INS.file)
-
-DERIVED_FILES= rdc_prot.h
-
-CHECKHDRS= $(HDRS:%.h=%.check)
-
-.KEEP_STATE:
-
-.PARALLEL: $(CHECKHDRS)
-
-install_h: $(ROOTDIRS) $(ROOTHDRS)
-
-clobber clean:
- $(RM) $(DERIVED_FILES)
-rdc_prot.h: rdc_prot.x
- $(RPCGEN) -h rdc_prot.x > $@
-
-$(ROOTDIR):
- $(INS.dir)
-
-check: $(CHECKHDRS)
diff --git a/usr/src/uts/common/avs/ns/rdc/rdc.c b/usr/src/uts/common/avs/ns/rdc/rdc.c
deleted file mode 100644
index 28750c6e25..0000000000
--- a/usr/src/uts/common/avs/ns/rdc/rdc.c
+++ /dev/null
@@ -1,1108 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#define _RDC_
-#include <sys/types.h>
-#include <sys/ksynch.h>
-#include <sys/kmem.h>
-#include <sys/errno.h>
-#include <sys/conf.h>
-#include <sys/cmn_err.h>
-#include <sys/modctl.h>
-#include <sys/cred.h>
-#include <sys/ddi.h>
-#include <sys/sysmacros.h>
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_k.h>
-#include <sys/unistat/spcs_errors.h>
-
-#include <sys/nsc_thread.h>
-#ifdef DS_DDICT
-#include "../contract.h"
-#endif
-#include <sys/nsctl/nsctl.h>
-#include <sys/nsctl/nsvers.h>
-
-#include <sys/sdt.h> /* dtrace is S10 or later */
-
-#include "rdc.h"
-#include "rdc_io.h"
-#include "rdc_bitmap.h"
-#include "rdc_ioctl.h"
-#include "rdcsrv.h"
-#include "rdc_diskq.h"
-
-#define DIDINIT 0x01
-#define DIDNODES 0x02
-#define DIDCONFIG 0x04
-
-static int rdcopen(dev_t *devp, int flag, int otyp, cred_t *crp);
-static int rdcclose(dev_t dev, int flag, int otyp, cred_t *crp);
-static int rdcprint(dev_t dev, char *str);
-static int rdcioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *crp,
- int *rvp);
-static int rdcattach(dev_info_t *dip, ddi_attach_cmd_t cmd);
-static int rdcdetach(dev_info_t *dip, ddi_detach_cmd_t cmd);
-static int rdcgetinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
- void **result);
-#ifdef DEBUG
-static int rdc_clrkstat(void *);
-#endif
-
-/*
- * kstat interface
- */
-static kstat_t *sndr_kstats;
-
-int sndr_info_stats_update(kstat_t *ksp, int rw);
-
-static sndr_m_stats_t sndr_info_stats = {
- {RDC_MKSTAT_MAXSETS, KSTAT_DATA_ULONG},
- {RDC_MKSTAT_MAXFBAS, KSTAT_DATA_ULONG},
- {RDC_MKSTAT_RPC_TIMEOUT, KSTAT_DATA_ULONG},
- {RDC_MKSTAT_HEALTH_THRES, KSTAT_DATA_ULONG},
- {RDC_MKSTAT_BITMAP_WRITES, KSTAT_DATA_ULONG},
- {RDC_MKSTAT_CLNT_COTS_CALLS, KSTAT_DATA_ULONG},
- {RDC_MKSTAT_CLNT_CLTS_CALLS, KSTAT_DATA_ULONG},
- {RDC_MKSTAT_SVC_COTS_CALLS, KSTAT_DATA_ULONG},
- {RDC_MKSTAT_SVC_CLTS_CALLS, KSTAT_DATA_ULONG},
- {RDC_MKSTAT_BITMAP_REF_DELAY, KSTAT_DATA_ULONG}
-};
-
-int rdc_info_stats_update(kstat_t *ksp, int rw);
-
-static rdc_info_stats_t rdc_info_stats = {
- {RDC_IKSTAT_FLAGS, KSTAT_DATA_ULONG},
- {RDC_IKSTAT_SYNCFLAGS, KSTAT_DATA_ULONG},
- {RDC_IKSTAT_BMPFLAGS, KSTAT_DATA_ULONG},
- {RDC_IKSTAT_SYNCPOS, KSTAT_DATA_ULONG},
- {RDC_IKSTAT_VOLSIZE, KSTAT_DATA_ULONG},
- {RDC_IKSTAT_BITSSET, KSTAT_DATA_ULONG},
- {RDC_IKSTAT_AUTOSYNC, KSTAT_DATA_ULONG},
- {RDC_IKSTAT_MAXQFBAS, KSTAT_DATA_ULONG},
- {RDC_IKSTAT_MAXQITEMS, KSTAT_DATA_ULONG},
- {RDC_IKSTAT_FILE, KSTAT_DATA_STRING},
- {RDC_IKSTAT_SECFILE, KSTAT_DATA_STRING},
- {RDC_IKSTAT_BITMAP, KSTAT_DATA_STRING},
- {RDC_IKSTAT_PRIMARY_HOST, KSTAT_DATA_STRING},
- {RDC_IKSTAT_SECONDARY_HOST, KSTAT_DATA_STRING},
- {RDC_IKSTAT_TYPE_FLAG, KSTAT_DATA_ULONG},
- {RDC_IKSTAT_BMP_SIZE, KSTAT_DATA_ULONG},
- {RDC_IKSTAT_DISK_STATUS, KSTAT_DATA_ULONG},
- {RDC_IKSTAT_IF_DOWN, KSTAT_DATA_ULONG},
- {RDC_IKSTAT_IF_RPC_VERSION, KSTAT_DATA_ULONG},
- {RDC_IKSTAT_ASYNC_BLOCK_HWM, KSTAT_DATA_ULONG},
- {RDC_IKSTAT_ASYNC_ITEM_HWM, KSTAT_DATA_ULONG},
- {RDC_IKSTAT_ASYNC_THROTTLE_DELAY, KSTAT_DATA_ULONG},
- {RDC_IKSTAT_ASYNC_ITEMS, KSTAT_DATA_ULONG},
- {RDC_IKSTAT_ASYNC_BLOCKS, KSTAT_DATA_ULONG},
- {RDC_IKSTAT_QUEUE_TYPE, KSTAT_DATA_CHAR}
-};
-
-static struct cb_ops rdc_cb_ops = {
- rdcopen,
- rdcclose,
- nulldev, /* no strategy */
- rdcprint,
- nodev, /* no dump */
- nodev, /* no read */
- nodev, /* no write */
- rdcioctl,
- nodev, /* no devmap */
- nodev, /* no mmap */
- nodev, /* no segmap */
- nochpoll,
- ddi_prop_op,
- NULL, /* not STREAMS */
- D_NEW | D_MP | D_64BIT,
- CB_REV,
- nodev, /* no aread */
- nodev, /* no awrite */
-};
-
-static struct dev_ops rdc_ops = {
- DEVO_REV,
- 0,
- rdcgetinfo,
- nulldev, /* identify */
- nulldev, /* probe */
- rdcattach,
- rdcdetach,
- nodev, /* no reset */
- &rdc_cb_ops,
- (struct bus_ops *)NULL
-};
-
-static struct modldrv rdc_ldrv = {
- &mod_driverops,
- "nws:Remote Mirror:" ISS_VERSION_STR,
- &rdc_ops
-};
-
-static struct modlinkage rdc_modlinkage = {
- MODREV_1,
- &rdc_ldrv,
- NULL
-};
-
-const int sndr_major_rev = ISS_VERSION_MAJ;
-const int sndr_minor_rev = ISS_VERSION_MIN;
-const int sndr_micro_rev = ISS_VERSION_MIC;
-const int sndr_baseline_rev = ISS_VERSION_NUM;
-static char sndr_version[16];
-
-static void *rdc_dip;
-
-extern int _rdc_init_dev();
-extern void _rdc_deinit_dev();
-extern void rdc_link_down_free();
-
-int rdc_bitmap_mode;
-int rdc_auto_sync;
-int rdc_max_sets;
-extern int rdc_health_thres;
-
-kmutex_t rdc_sync_mutex;
-rdc_sync_event_t rdc_sync_event;
-clock_t rdc_sync_event_timeout;
-
-static void
-rdc_sync_event_init()
-{
- mutex_init(&rdc_sync_mutex, NULL, MUTEX_DRIVER, NULL);
- mutex_init(&rdc_sync_event.mutex, NULL, MUTEX_DRIVER, NULL);
- cv_init(&rdc_sync_event.cv, NULL, CV_DRIVER, NULL);
- cv_init(&rdc_sync_event.done_cv, NULL, CV_DRIVER, NULL);
- rdc_sync_event.master[0] = 0;
- rdc_sync_event.lbolt = (clock_t)0;
- rdc_sync_event_timeout = RDC_SYNC_EVENT_TIMEOUT;
-}
-
-
-static void
-rdc_sync_event_destroy()
-{
- mutex_destroy(&rdc_sync_mutex);
- mutex_destroy(&rdc_sync_event.mutex);
- cv_destroy(&rdc_sync_event.cv);
- cv_destroy(&rdc_sync_event.done_cv);
-}
-
-
-
-int
-_init(void)
-{
- return (mod_install(&rdc_modlinkage));
-}
-
-int
-_fini(void)
-{
- return (mod_remove(&rdc_modlinkage));
-}
-
-int
-_info(struct modinfo *modinfop)
-{
- return (mod_info(&rdc_modlinkage, modinfop));
-}
-
-static int
-rdcattach(dev_info_t *dip, ddi_attach_cmd_t cmd)
-{
- intptr_t flags;
- int instance;
- int i;
-
- /*CONSTCOND*/
- ASSERT(sizeof (u_longlong_t) == 8);
-
- if (cmd != DDI_ATTACH)
- return (DDI_FAILURE);
-
- (void) strncpy(sndr_version, _VERSION_, sizeof (sndr_version));
-
- instance = ddi_get_instance(dip);
- rdc_dip = dip;
-
- flags = 0;
-
- rdc_sync_event_init();
-
- /*
- * rdc_max_sets must be set before calling _rdc_load().
- */
-
- rdc_max_sets = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "rdc_max_sets", 64);
-
- if (_rdc_init_dev()) {
- cmn_err(CE_WARN, "!rdc: _rdc_init_dev failed");
- goto out;
- }
- flags |= DIDINIT;
-
- if (_rdc_load() != 0) {
- cmn_err(CE_WARN, "!rdc: _rdc_load failed");
- goto out;
- }
-
- if (_rdc_configure()) {
- cmn_err(CE_WARN, "!rdc: _rdc_configure failed");
- goto out;
- }
- flags |= DIDCONFIG;
-
- if (ddi_create_minor_node(dip, "rdc", S_IFCHR, instance, DDI_PSEUDO, 0)
- != DDI_SUCCESS) {
- cmn_err(CE_WARN, "!rdc: could not create node.");
- goto out;
- }
- flags |= DIDNODES;
-
- rdc_bitmap_mode = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
- "rdc_bitmap_mode", 0);
-
- switch (rdc_bitmap_mode) {
- case RDC_BMP_AUTO: /* 0 */
- break;
- case RDC_BMP_ALWAYS: /* 1 */
- break;
- case RDC_BMP_NEVER: /* 2 */
- cmn_err(CE_NOTE, "!SNDR bitmap mode override");
- cmn_err(CE_CONT,
- "!SNDR: bitmaps will only be written on shutdown\n");
- break;
- default: /* unknown */
- cmn_err(CE_NOTE,
- "!SNDR: unknown bitmap mode %d - autodetecting mode",
- rdc_bitmap_mode);
- rdc_bitmap_mode = RDC_BMP_AUTO;
- break;
- }
-
- rdc_bitmap_init();
-
- rdc_auto_sync = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
- "rdc_auto_sync", 0);
-
- i = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
- "rdc_health_thres", RDC_HEALTH_THRESHOLD);
- if (i >= RDC_MIN_HEALTH_THRES)
- rdc_health_thres = i;
- else
- cmn_err(CE_WARN, "!value rdc_heath_thres from rdc.conf ignored "
- "as it is smaller than the min value of %d",
- RDC_MIN_HEALTH_THRES);
-
- ddi_set_driver_private(dip, (caddr_t)flags);
- ddi_report_dev(dip);
-
- sndr_kstats = kstat_create(RDC_KSTAT_MODULE, 0,
- RDC_KSTAT_MINFO, RDC_KSTAT_CLASS, KSTAT_TYPE_NAMED,
- sizeof (sndr_m_stats_t) / sizeof (kstat_named_t),
- KSTAT_FLAG_VIRTUAL);
-
- if (sndr_kstats) {
- sndr_kstats->ks_data = &sndr_info_stats;
- sndr_kstats->ks_update = sndr_info_stats_update;
- sndr_kstats->ks_private = &rdc_k_info[0];
- kstat_install(sndr_kstats);
- } else
- cmn_err(CE_WARN, "!SNDR: module kstats failed");
-
- return (DDI_SUCCESS);
-
-out:
- DTRACE_PROBE(rdc_attach_failed);
- ddi_set_driver_private(dip, (caddr_t)flags);
- (void) rdcdetach(dip, DDI_DETACH);
- return (DDI_FAILURE);
-}
-
-static int
-rdcdetach(dev_info_t *dip, ddi_detach_cmd_t cmd)
-{
- rdc_k_info_t *krdc;
- rdc_u_info_t *urdc;
- int rdcd;
- intptr_t flags;
-
-
- if (cmd != DDI_DETACH) {
- DTRACE_PROBE(rdc_detach_unknown_cmd);
- return (DDI_FAILURE);
- }
-
- if (rdc_k_info == NULL || rdc_u_info == NULL)
- goto cleanup;
-
- mutex_enter(&rdc_conf_lock);
-
- for (rdcd = 0; rdcd < rdc_max_sets; rdcd++) {
- krdc = &rdc_k_info[rdcd];
- urdc = &rdc_u_info[rdcd];
-
- if (IS_ENABLED(urdc) || krdc->devices) {
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!rdc: cannot detach, rdcd %d still in use", rdcd);
-#endif
- mutex_exit(&rdc_conf_lock);
- DTRACE_PROBE(rdc_detach_err_busy);
- return (DDI_FAILURE);
- }
- }
-
- mutex_exit(&rdc_conf_lock);
-
-cleanup:
- flags = (intptr_t)ddi_get_driver_private(dip);
-
- if (flags & DIDNODES)
- ddi_remove_minor_node(dip, NULL);
-
- if (sndr_kstats) {
- kstat_delete(sndr_kstats);
- }
- if (flags & DIDINIT)
- _rdc_deinit_dev();
-
- if (flags & DIDCONFIG) {
- (void) _rdc_deconfigure();
- (void) _rdc_unload();
- rdcsrv_unload();
- }
-
- rdc_sync_event_destroy();
- rdc_link_down_free();
-
- rdc_dip = NULL;
- return (DDI_SUCCESS);
-}
-
-/* ARGSUSED */
-static int
-rdcgetinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
-{
- int rc = DDI_FAILURE;
-
- switch (infocmd) {
-
- case DDI_INFO_DEVT2DEVINFO:
- *result = rdc_dip;
- rc = DDI_SUCCESS;
- break;
-
- case DDI_INFO_DEVT2INSTANCE:
- /* We only have a single instance */
- *result = 0;
- rc = DDI_SUCCESS;
- break;
-
- default:
- break;
- }
-
- return (rc);
-}
-
-
-/* ARGSUSED */
-
-static int
-rdcopen(dev_t *devp, int flag, int otyp, cred_t *crp)
-{
- return (0);
-}
-
-
-/* ARGSUSED */
-
-static int
-rdcclose(dev_t dev, int flag, int otyp, cred_t *crp)
-{
- return (0);
-}
-
-/* ARGSUSED */
-
-static int
-rdcprint(dev_t dev, char *str)
-{
- int instance = 0;
-
- cmn_err(CE_WARN, "!rdc%d: %s", instance, str);
- return (0);
-}
-
-
-static int
-convert_ioctl_args(int cmd, intptr_t arg, int mode, _rdc_ioctl_t *args)
-{
- _rdc_ioctl32_t args32;
-
- if (ddi_copyin((void *)arg, &args32, sizeof (_rdc_ioctl32_t), mode))
- return (EFAULT);
-
- bzero((void *)args, sizeof (_rdc_ioctl_t));
-
- switch (cmd) {
- case RDC_CONFIG:
- args->arg0 = (uint32_t)args32.arg0; /* _rdc_config_t * */
- args->arg1 = (uint32_t)args32.arg1; /* pointer */
- args->arg2 = (uint32_t)args32.arg2; /* size */
- args->ustatus = (spcs_s_info_t)args32.ustatus;
- break;
-
- case RDC_STATUS:
- args->arg0 = (uint32_t)args32.arg0; /* pointer */
- args->ustatus = (spcs_s_info_t)args32.ustatus;
- break;
-
- case RDC_ENABLE_SVR:
- args->arg0 = (uint32_t)args32.arg0; /* _rdc_svc_args * */
- break;
-
- case RDC_VERSION:
- args->arg0 = (uint32_t)args32.arg0; /* _rdc_version_t * */
- args->ustatus = (spcs_s_info_t)args32.ustatus;
- break;
-
- case RDC_SYNC_EVENT:
- args->arg0 = (uint32_t)args32.arg0; /* char * */
- args->arg1 = (uint32_t)args32.arg1; /* char * */
- args->ustatus = (spcs_s_info_t)args32.ustatus;
- break;
-
- case RDC_LINK_DOWN:
- args->arg0 = (uint32_t)args32.arg0; /* char * */
- args->ustatus = (spcs_s_info_t)args32.ustatus;
- break;
- case RDC_POOL_CREATE:
- args->arg0 = (uint32_t)args32.arg0; /* svcpool_args * */
- break;
- case RDC_POOL_WAIT:
- args->arg0 = (uint32_t)args32.arg0; /* int */
- break;
- case RDC_POOL_RUN:
- args->arg0 = (uint32_t)args32.arg0; /* int */
- break;
-
- default:
- return (EINVAL);
- }
-
- return (0);
-}
-
-/*
- * Build a 32bit rdc_set structure and copyout to the user level.
- */
-int
-rdc_status_copy32(const void *arg, void *usetp, size_t size, int mode)
-{
- rdc_u_info_t *urdc = (rdc_u_info_t *)arg;
- struct rdc_set32 set32;
- size_t tailsize;
-#ifdef DEBUG
- size_t tailsize32;
-#endif
-
- bzero(&set32, sizeof (set32));
-
- tailsize = sizeof (struct rdc_addr32) -
- offsetof(struct rdc_addr32, intf);
-
- /* primary address structure, avoiding netbuf */
- bcopy(&urdc->primary.intf[0], &set32.primary.intf[0], tailsize);
-
- /* secondary address structure, avoiding netbuf */
- bcopy(&urdc->secondary.intf[0], &set32.secondary.intf[0], tailsize);
-
- /*
- * the rest, avoiding netconfig
- * note: the tail must be the same size in both structures
- */
- tailsize = sizeof (struct rdc_set) - offsetof(struct rdc_set, flags);
-#ifdef DEBUG
- /*
- * ASSERT is calling for debug reason, and tailsize32 is only declared
- * for ASSERT, put them under debug to avoid lint warning.
- */
- tailsize32 = sizeof (struct rdc_set32) -
- offsetof(struct rdc_set32, flags);
- ASSERT(tailsize == tailsize32);
-#endif
-
- bcopy(&urdc->flags, &set32.flags, tailsize);
-
- /* copyout to user level */
- return (ddi_copyout(&set32, usetp, size, mode));
-}
-
-
-/*
- * Status ioctl.
- */
-static int
-rdcstatus(_rdc_ioctl_t *args, int mode)
-{
- int (*copyout)(const void *, void *, size_t, int);
- rdc_u_info_t *urdc;
- rdc_k_info_t *krdc;
- disk_queue *dqp;
- char *usetp; /* pointer to user rdc_set structure */
- size_t size; /* sizeof user rdc_set structure */
- int32_t *maxsetsp; /* address of status->maxsets; */
- int nset, max, i, j;
-
- if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
- struct rdc_status32 status32;
-
- if (ddi_copyin((void *)args->arg0, &status32,
- sizeof (status32), mode)) {
- return (EFAULT);
- }
-
- usetp = ((char *)args->arg0) +
- offsetof(struct rdc_status32, rdc_set);
- maxsetsp = (int32_t *)((char *)args->arg0 +
- offsetof(struct rdc_status32, maxsets));
- nset = status32.nset;
-
- size = sizeof (struct rdc_set32);
- copyout = rdc_status_copy32;
- } else {
- struct rdc_status status;
-
- if (ddi_copyin((void *)args->arg0, &status,
- sizeof (status), mode)) {
- return (EFAULT);
- }
-
- usetp = ((char *)args->arg0) +
- offsetof(struct rdc_status, rdc_set);
- maxsetsp = (int32_t *)((char *)args->arg0 +
- offsetof(struct rdc_status, maxsets));
- nset = status.nset;
-
- size = sizeof (struct rdc_set);
- copyout = ddi_copyout;
- }
-
- max = min(nset, rdc_max_sets);
-
- for (i = 0, j = 0; i < max; i++) {
- urdc = &rdc_u_info[i];
- krdc = &rdc_k_info[i];
-
- if (!IS_ENABLED(urdc))
- continue;
-
- /*
- * sneak out qstate in urdc->flags
- * this is harmless because it's value is not used
- * in urdc->flags. the real qstate is kept in
- * group->diskq->disk_hdr.h.state
- */
- if (RDC_IS_DISKQ(krdc->group)) {
- dqp = &krdc->group->diskq;
- if (IS_QSTATE(dqp, RDC_QNOBLOCK))
- urdc->flags |= RDC_QNOBLOCK;
- }
-
- j++;
- if ((*copyout)(urdc, usetp, size, mode) != 0)
- return (EFAULT);
-
- urdc->flags &= ~RDC_QNOBLOCK; /* clear qstate */
- usetp += size;
- }
-
- /* copyout rdc_max_sets value */
-
- if (ddi_copyout(&rdc_max_sets, maxsetsp, sizeof (*maxsetsp), mode) != 0)
- return (EFAULT);
-
- /* copyout number of sets manipulated */
-
- /*CONSTCOND*/
- ASSERT(offsetof(struct rdc_status32, nset) == 0);
- /*CONSTCOND*/
- ASSERT(offsetof(struct rdc_status, nset) == 0);
-
- return (ddi_copyout(&j, (void *)args->arg0, sizeof (int), mode));
-}
-
-
-/* ARGSUSED */
-
-static int
-rdcioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *crp, int *rvp)
-{
- spcs_s_info_t kstatus = NULL;
- _rdc_ioctl_t args;
- int error;
- int rc = 0;
-
- if (cmd != RDC_STATUS) {
- if ((error = drv_priv(crp)) != 0)
- return (error);
- }
-#ifdef DEBUG
- if (cmd == RDC_ASYNC6) {
- rc = rdc_async6((void *)arg, mode, rvp);
- return (rc);
- }
-
- if (cmd == RDC_CLRKSTAT) {
- rc = rdc_clrkstat((void *)arg);
- return (rc);
- }
-
- if (cmd == RDC_STALL0) {
- if (((int)arg > 1) || ((int)arg < 0))
- return (EINVAL);
- rdc_stallzero((int)arg);
- return (0);
- }
- if (cmd == RDC_READGEN) {
- rc = rdc_readgen((void *)arg, mode, rvp);
- return (rc);
- }
-#endif
- if (cmd == RDC_BITMAPOP) {
- rdc_bitmap_op_t bmop;
- rdc_bitmap_op32_t bmop32;
-
- if (ddi_model_convert_from(mode & FMODELS)
- == DDI_MODEL_ILP32) {
- if (ddi_copyin((void *)arg, &bmop32, sizeof (bmop32),
- mode))
- return (EFAULT);
- bmop.offset = bmop32.offset;
- bmop.op = bmop32.op;
- (void) strncpy(bmop.sechost, bmop32.sechost,
- MAX_RDC_HOST_SIZE);
- (void) strncpy(bmop.secfile, bmop32.secfile,
- NSC_MAXPATH);
- bmop.len = bmop32.len;
- bmop.addr = (unsigned long)bmop32.addr;
- } else {
- if (ddi_copyin((void *)arg, &bmop, sizeof (bmop),
- mode))
- return (EFAULT);
- }
- rc = rdc_bitmapset(bmop.op, bmop.sechost, bmop.secfile,
- (void *)bmop.addr, bmop.len, bmop.offset, mode);
- return (rc);
- }
-
- if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
- if ((rc = convert_ioctl_args(cmd, arg, mode, &args)) != 0)
- return (rc);
- } else {
- if (ddi_copyin((void *)arg, &args,
- sizeof (_rdc_ioctl_t), mode)) {
- return (EFAULT);
- }
- }
-
- kstatus = spcs_s_kcreate();
- if (!kstatus) {
- return (ENOMEM);
- }
-
-
- switch (cmd) {
-
- case RDC_POOL_CREATE: {
- struct svcpool_args p;
-
- if (ddi_copyin((void *)arg, &p, sizeof (p), mode)) {
- spcs_s_kfree(kstatus);
- return (EFAULT);
- }
- error = svc_pool_create(&p);
-
- break;
- }
- case RDC_POOL_WAIT: {
- int id;
-
- if (ddi_copyin((void *)arg, &id, sizeof (id), mode)) {
- spcs_s_kfree(kstatus);
- return (EFAULT);
- }
-
- error = svc_wait(id);
- break;
- }
- case RDC_POOL_RUN: {
- int id;
-
- if (ddi_copyin((void *)arg, &id, sizeof (id), mode)) {
- spcs_s_kfree(kstatus);
- return (EFAULT);
- }
- error = svc_do_run(id);
- break;
- }
- case RDC_ENABLE_SVR:
- {
- STRUCT_DECL(rdc_svc_args, parms);
-
- STRUCT_INIT(parms, mode);
- /* Only used by sndrd which does not use unistat */
-
- if (ddi_copyin((void *)args.arg0, STRUCT_BUF(parms),
- STRUCT_SIZE(parms), mode)) {
- spcs_s_kfree(kstatus);
- return (EFAULT);
- }
- rc = rdc_start_server(STRUCT_BUF(parms), mode);
- }
- break;
-
- case RDC_STATUS:
- rc = rdcstatus(&args, mode);
- break;
-
- case RDC_CONFIG:
- rc = _rdc_config((void *)args.arg0, mode, kstatus, rvp);
- spcs_s_copyoutf(&kstatus, args.ustatus);
- return (rc);
-
- case RDC_VERSION:
- {
- STRUCT_DECL(rdc_version, parms);
-
- STRUCT_INIT(parms, mode);
-
- STRUCT_FSET(parms, major, sndr_major_rev);
- STRUCT_FSET(parms, minor, sndr_minor_rev);
- STRUCT_FSET(parms, micro, sndr_micro_rev);
- STRUCT_FSET(parms, baseline, sndr_baseline_rev);
-
- if (ddi_copyout(STRUCT_BUF(parms), (void *)args.arg0,
- STRUCT_SIZE(parms), mode)) {
- spcs_s_kfree(kstatus);
- return (EFAULT);
- }
- break;
- }
-
- case RDC_LINK_DOWN:
- /* char *host from user */
- rc = _rdc_link_down((void *)args.arg0, mode, kstatus, rvp);
- spcs_s_copyoutf(&kstatus, args.ustatus);
-
- return (rc);
-
- case RDC_SYNC_EVENT:
- rc = _rdc_sync_event_wait((void *)args.arg0, (void *)args.arg1,
- mode, kstatus, rvp);
- spcs_s_copyoutf(&kstatus, args.ustatus);
-
- return (rc);
-
-
- default:
- rc = EINVAL;
- break;
- }
-
- spcs_s_kfree(kstatus);
- return (rc);
-}
-
-int
-sndr_info_stats_update(kstat_t *ksp, int rw)
-{
- extern int rdc_rpc_tmout;
- extern int rdc_health_thres;
- extern int rdc_bitmap_delay;
- extern long rdc_clnt_count;
- extern long rdc_svc_count;
- sndr_m_stats_t *info_stats;
- rdc_k_info_t *krdc;
-
- info_stats = (sndr_m_stats_t *)(ksp->ks_data);
- krdc = (rdc_k_info_t *)(ksp->ks_private);
-
- /* no writes currently allowed */
-
- if (rw == KSTAT_WRITE) {
- return (EACCES);
- }
-
- /* default to READ */
- info_stats->m_maxsets.value.ul = rdc_max_sets;
- info_stats->m_maxfbas.value.ul = krdc->maxfbas;
- info_stats->m_rpc_timeout.value.ul = rdc_rpc_tmout;
- info_stats->m_health_thres.value.ul = rdc_health_thres;
- info_stats->m_bitmap_writes.value.ul = krdc->bitmap_write;
- info_stats->m_bitmap_ref_delay.value.ul = rdc_bitmap_delay;
-
- /* clts counters not implemented yet */
- info_stats->m_clnt_cots_calls.value.ul = rdc_clnt_count;
- info_stats->m_clnt_clts_calls.value.ul = 0;
- info_stats->m_svc_cots_calls.value.ul = rdc_svc_count;
- info_stats->m_svc_clts_calls.value.ul = 0;
-
- return (0);
-}
-
-/*
- * copy tailsize-1 bytes of tail of s to s1.
- */
-void
-rdc_str_tail_cpy(char *s1, char *s, size_t tailsize)
-{
- /* To avoid un-terminated string, max size is 16 - 1 */
- ssize_t offset = strlen(s) - (tailsize - 1);
-
- offset = (offset > 0) ? offset : 0;
-
- /* ensure it's null terminated */
- (void) strlcpy(s1, (const char *)(s + offset), tailsize);
-}
-
-int
-rdc_info_stats_update(kstat_t *ksp, int rw)
-{
- rdc_info_stats_t *rdc_info_stats;
- rdc_k_info_t *krdc;
- rdc_u_info_t *urdc;
-
- rdc_info_stats = (rdc_info_stats_t *)(ksp->ks_data);
- krdc = (rdc_k_info_t *)(ksp->ks_private);
- urdc = &rdc_u_info[krdc->index];
-
- /* no writes currently allowed */
-
- if (rw == KSTAT_WRITE) {
- return (EACCES);
- }
-
- /* default to READ */
- rdc_info_stats->s_flags.value.ul = urdc->flags;
- rdc_info_stats->s_syncflags.value.ul =
- urdc->sync_flags;
- rdc_info_stats->s_bmpflags.value.ul =
- urdc->bmap_flags;
- rdc_info_stats->s_syncpos.value.ul =
- urdc->sync_pos;
- rdc_info_stats->s_volsize.value.ul =
- urdc->volume_size;
- rdc_info_stats->s_bits_set.value.ul =
- urdc->bits_set;
- rdc_info_stats->s_autosync.value.ul =
- urdc->autosync;
- rdc_info_stats->s_maxqfbas.value.ul =
- urdc->maxqfbas;
- rdc_info_stats->s_maxqitems.value.ul =
- urdc->maxqitems;
-
- kstat_named_setstr(&rdc_info_stats->s_primary_vol,
- urdc->primary.file);
-
- kstat_named_setstr(&rdc_info_stats->s_secondary_vol,
- urdc->secondary.file);
-
- if (rdc_get_vflags(urdc) & RDC_PRIMARY) {
- kstat_named_setstr(&rdc_info_stats->s_bitmap,
- urdc->primary.bitmap);
- } else {
- kstat_named_setstr(&rdc_info_stats->s_bitmap,
- urdc->secondary.bitmap);
- }
-
- kstat_named_setstr(&rdc_info_stats->s_primary_intf,
- urdc->primary.intf);
-
- kstat_named_setstr(&rdc_info_stats->s_secondary_intf,
- urdc->secondary.intf);
-
- rdc_info_stats->s_type_flag.value.ul = krdc->type_flag;
- rdc_info_stats->s_bitmap_size.value.ul = krdc->bitmap_size;
- rdc_info_stats->s_disk_status.value.ul = krdc->disk_status;
-
- if (krdc->intf) {
- rdc_info_stats->s_if_if_down.value.ul = krdc->intf->if_down;
- rdc_info_stats->s_if_rpc_version.value.ul =
- krdc->intf->rpc_version;
- }
-
- /* the type can change without disable/re-enable so... */
- bzero(rdc_info_stats->s_aqueue_type.value.c, KSTAT_DATA_CHAR_LEN);
- if (RDC_IS_MEMQ(krdc->group)) {
- (void) strcpy(rdc_info_stats->s_aqueue_type.value.c, "memory");
- rdc_info_stats->s_aqueue_blk_hwm.value.ul =
- krdc->group->ra_queue.blocks_hwm;
- rdc_info_stats->s_aqueue_itm_hwm.value.ul =
- krdc->group->ra_queue.nitems_hwm;
- rdc_info_stats->s_aqueue_throttle.value.ul =
- krdc->group->ra_queue.throttle_delay;
- rdc_info_stats->s_aqueue_items.value.ul =
- krdc->group->ra_queue.nitems;
- rdc_info_stats->s_aqueue_blocks.value.ul =
- krdc->group->ra_queue.blocks;
-
- } else if (RDC_IS_DISKQ(krdc->group)) {
- disk_queue *q = &krdc->group->diskq;
- rdc_info_stats->s_aqueue_blk_hwm.value.ul =
- krdc->group->diskq.blocks_hwm;
- rdc_info_stats->s_aqueue_itm_hwm.value.ul =
- krdc->group->diskq.nitems_hwm;
- rdc_info_stats->s_aqueue_throttle.value.ul =
- krdc->group->diskq.throttle_delay;
- rdc_info_stats->s_aqueue_items.value.ul = QNITEMS(q);
- rdc_info_stats->s_aqueue_blocks.value.ul = QBLOCKS(q);
- (void) strcpy(rdc_info_stats->s_aqueue_type.value.c, "disk");
- }
-
- return (0);
-}
-
-void
-rdc_kstat_create(int index)
-{
- int j = index;
- rdc_k_info_t *krdc = &rdc_k_info[index];
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- size_t varsize;
-
- if (!krdc->set_kstats) {
- krdc->set_kstats = kstat_create(RDC_KSTAT_MODULE, j,
- RDC_KSTAT_INFO, RDC_KSTAT_CLASS, KSTAT_TYPE_NAMED,
- sizeof (rdc_info_stats_t) / sizeof (kstat_named_t),
- KSTAT_FLAG_VIRTUAL);
-#ifdef DEBUG
- if (!krdc->set_kstats)
- cmn_err(CE_NOTE, "!krdc:u_kstat null");
-#endif
-
- if (krdc->set_kstats) {
- /* calculate exact size of KSTAT_DATA_STRINGs */
- varsize = strlen(urdc->primary.file) + 1
- + strlen(urdc->secondary.file) + 1
- + strlen(urdc->primary.intf) + 1
- + strlen(urdc->secondary.intf) + 1;
- if (rdc_get_vflags(urdc) & RDC_PRIMARY) {
- varsize += strlen(urdc->primary.bitmap) + 1;
- } else {
- varsize += strlen(urdc->secondary.bitmap) + 1;
- }
-
- krdc->set_kstats->ks_data_size += varsize;
- krdc->set_kstats->ks_data = &rdc_info_stats;
- krdc->set_kstats->ks_update = rdc_info_stats_update;
- krdc->set_kstats->ks_private = &rdc_k_info[j];
- kstat_install(krdc->set_kstats);
- } else
- cmn_err(CE_WARN, "!SNDR: k-kstats failed");
- }
-
- krdc->io_kstats = kstat_create(RDC_KSTAT_MODULE, j, NULL,
- "disk", KSTAT_TYPE_IO, 1, 0);
- if (krdc->io_kstats) {
- krdc->io_kstats->ks_lock = &krdc->kstat_mutex;
- kstat_install(krdc->io_kstats);
- }
- krdc->bmp_kstats = kstat_create("sndrbmp", j, NULL,
- "disk", KSTAT_TYPE_IO, 1, 0);
- if (krdc->bmp_kstats) {
- krdc->bmp_kstats->ks_lock = &krdc->bmp_kstat_mutex;
- kstat_install(krdc->bmp_kstats);
- }
-}
-
-void
-rdc_kstat_delete(int index)
-{
- rdc_k_info_t *krdc = &rdc_k_info[index];
-
- if (krdc->set_kstats) {
- kstat_delete(krdc->set_kstats);
- krdc->set_kstats = NULL;
- }
-
- if (krdc->io_kstats) {
- kstat_delete(krdc->io_kstats);
- krdc->io_kstats = NULL;
- }
- if (krdc->bmp_kstats) {
- kstat_delete(krdc->bmp_kstats);
- krdc->bmp_kstats = NULL;
- }
-}
-
-#ifdef DEBUG
-/*
- * Reset the io_kstat structure of the krdc specified
- * by the arg index.
- */
-static int
-rdc_clrkstat(void *arg)
-{
- int index;
- rdc_k_info_t *krdc;
-
- index = (int)(unsigned long)arg;
- if ((index < 0) || (index >= rdc_max_sets)) {
- return (EINVAL);
- }
- krdc = &rdc_k_info[index];
- if (krdc->io_kstats) {
- kstat_delete(krdc->io_kstats);
- krdc->io_kstats = NULL;
- } else {
- return (EINVAL);
- }
- krdc->io_kstats = kstat_create(RDC_KSTAT_MODULE, index, NULL,
- "disk", KSTAT_TYPE_IO, 1, 0);
- if (krdc->io_kstats) {
- krdc->io_kstats->ks_lock = &krdc->kstat_mutex;
- kstat_install(krdc->io_kstats);
- } else {
- return (EINVAL);
- }
- /*
- * clear the high water marks and throttle.
- */
- if (krdc->group) {
- krdc->group->ra_queue.nitems_hwm = 0;
- krdc->group->ra_queue.blocks_hwm = 0;
- krdc->group->ra_queue.throttle_delay = 0;
- }
- return (0);
-}
-#endif
diff --git a/usr/src/uts/common/avs/ns/rdc/rdc.conf b/usr/src/uts/common/avs/ns/rdc/rdc.conf
deleted file mode 100644
index 1ef5e0e420..0000000000
--- a/usr/src/uts/common/avs/ns/rdc/rdc.conf
+++ /dev/null
@@ -1,55 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#
-#
-name="rdc" parent="pseudo";
-
-#
-# rdc_bitmap_mode
-# - Sets the mode of the RDC bitmap operation, acceptable values are:
-# 0 - autodetect bitmap mode depending on the state of SDBC (default).
-# 1 - force bitmap writes for every write operation, so an update resync
-# can be performed after a crash or reboot.
-# 2 - only write the bitmap on shutdown, so a full resync is
-# required after a crash, but an update resync is required after
-# a reboot.
-#
-rdc_bitmap_mode=1;
-
-#
-# rdc_max_sets
-# - Configure the maximum number of RDC sets that can be enabled on
-# this host. The actual maximum number of sets that can be enabled
-# will be the minimum of this value and nsc_max_devices (see
-# nsctl.conf) at the time the rdc kernel module is loaded.
-#
-rdc_max_sets=64;
-
-#
-# rdc_health_thres
-# - Set the timeout (in seconds) for RDC health monitoring. If IPMP is in
-# use over the RDC link this value should be set higher than in.mpathd's
-# timeout.
-#
-#rdc_health_thres=20;
diff --git a/usr/src/uts/common/avs/ns/rdc/rdc.h b/usr/src/uts/common/avs/ns/rdc/rdc.h
deleted file mode 100644
index 8ebb22ad17..0000000000
--- a/usr/src/uts/common/avs/ns/rdc/rdc.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _RDC_H
-#define _RDC_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define RDCDEV "/dev/rdc"
-#define RDC_KSTAT_CLASS "storedge"
-#define RDC_KSTAT_MINFO "modinfo"
-#define RDC_KSTAT_INFO "setinfo"
-#define RDC_KSTAT_MODULE "sndr"
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _RDC_H */
diff --git a/usr/src/uts/common/avs/ns/rdc/rdc_bitmap.c b/usr/src/uts/common/avs/ns/rdc/rdc_bitmap.c
deleted file mode 100644
index bbea681e09..0000000000
--- a/usr/src/uts/common/avs/ns/rdc/rdc_bitmap.c
+++ /dev/null
@@ -1,2659 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/ksynch.h>
-#include <sys/cmn_err.h>
-#include <sys/kmem.h>
-#include <sys/stat.h>
-#include <sys/errno.h>
-
-#include "../solaris/nsc_thread.h"
-#ifdef DS_DDICT
-#include "../contract.h"
-#endif
-#include <sys/nsctl/nsctl.h>
-
-#include <sys/kmem.h>
-#include <sys/cmn_err.h>
-#include <sys/ddi.h>
-
-#include "rdc_io.h"
-#include "rdc_bitmap.h"
-#include "rdc_clnt.h"
-#include "rdc_diskq.h"
-
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_k.h>
-#include <sys/unistat/spcs_errors.h>
-
-#ifndef UINT8_MAX
-#define UINT8_MAX 255
-#endif
-
-#ifndef UINT_MAX
-#define UINT_MAX 0xffffffff
-#endif
-
-/*
- * RDC bitmap functions.
- */
-
-/*
- * RDC cluster integration notes.
- *
- * 1. Configuration
- *
- * 1.1. Change 'rdc_bitmap_mode' in /usr/kernel/drv/rdc.conf to '1'.
- *
- * 2. Operation
- *
- * 2.1. SunCluster ensures that only one physical host has any rdc
- * controlled device imported at any one time. Hence rdc will
- * only be active on a single node for any set at a time.
- *
- * 2.2. So operation from the kernel perspective looks just like
- * operation on a single, standalone, node.
- *
- */
-
-struct rdc_bitmap_ops *rdc_bitmap_ops; /* the bitmap ops switch */
-static int rdc_wrflag; /* write flag for io */
-int rdc_bitmap_delay = 0;
-extern nsc_io_t *_rdc_io_hc;
-
-int rdc_suspend_diskq(rdc_k_info_t *krdc);
-
-/*
- * rdc_ns_io
- * Perform read or write on an underlying ns device
- *
- * fd - nsc file descriptor
- * flag - nsc io direction and characteristics flag
- * fba_pos - offset from beginning of device in FBAs
- * io_addr - pointer to data buffer
- * io_len - length of io in bytes
- */
-
-int
-rdc_ns_io(nsc_fd_t *fd, int flag, nsc_off_t fba_pos, uchar_t *io_addr,
- nsc_size_t io_len)
-{
- nsc_buf_t *tmp;
- nsc_vec_t *vecp;
- uchar_t *vaddr;
- size_t copy_len;
- int vlen;
- int rc;
- nsc_size_t fba_req, fba_len;
- nsc_size_t maxfbas = 0;
- nsc_size_t tocopy;
- unsigned char *toaddr;
-
- rc = nsc_maxfbas(fd, 0, &maxfbas);
- if (!RDC_SUCCESS(rc)) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!rdc_ns_io: maxfbas failed (%d)", rc);
-#endif
- maxfbas = 256;
- }
- toaddr = io_addr;
- fba_req = FBA_LEN(io_len);
-loop:
- tmp = NULL;
- fba_len = min(fba_req, maxfbas);
- tocopy = min(io_len, FBA_SIZE(fba_len));
- ASSERT(tocopy < INT32_MAX);
-
- rc = nsc_alloc_buf(fd, fba_pos, fba_len, flag, &tmp);
- if (!RDC_SUCCESS(rc)) {
- if (tmp) {
- (void) nsc_free_buf(tmp);
- }
- return (EIO);
- }
-
- if ((flag & NSC_WRITE) != 0 && (flag & NSC_READ) == 0 &&
- FBA_OFF(io_len) != 0) {
- /*
- * Not overwriting all of the last FBA, so read in the
- * old contents now before we overwrite it with the new
- * data.
- */
- rc = nsc_read(tmp, fba_pos+FBA_NUM(io_len), 1, 0);
- if (!RDC_SUCCESS(rc)) {
- (void) nsc_free_buf(tmp);
- return (EIO);
- }
- }
-
- vecp = tmp->sb_vec;
- vlen = vecp->sv_len;
- vaddr = vecp->sv_addr;
-
- while (tocopy > 0) {
- if (vecp->sv_addr == 0 || vecp->sv_len == 0) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!rdc_ns_io: ran off end of handle");
-#endif
- break;
- }
-
- copy_len = (size_t)min(vlen, (int)tocopy);
-
- if (flag & NSC_WRITE)
- bcopy(toaddr, vaddr, copy_len);
- else
- bcopy(vaddr, toaddr, copy_len);
-
- toaddr += copy_len;
- io_addr += copy_len; /* adjust position in callers buffer */
- io_len -= copy_len; /* adjust total byte length remaining */
- tocopy -= copy_len; /* adjust chunk byte length remaining */
- vaddr += copy_len; /* adjust location in sv_vec_t */
- vlen -= copy_len; /* adjust length left in sv_vec_t */
-
- if (vlen <= 0) {
- vecp++;
- vaddr = vecp->sv_addr;
- vlen = vecp->sv_len;
- }
- }
-
- if (flag & NSC_WRITE) {
- rc = nsc_write(tmp, tmp->sb_pos, tmp->sb_len, 0);
- if (!RDC_SUCCESS(rc)) {
- (void) nsc_free_buf(tmp);
- return (rc);
- }
- }
-
- (void) nsc_free_buf(tmp);
-
- fba_pos += fba_len;
- fba_req -= fba_len;
- if (fba_req > 0)
- goto loop;
-
- return (0);
-}
-
-/*
- * Must be called with krdc->bmapmutex held.
- */
-static void
-rdc_fill_header(rdc_u_info_t *urdc, rdc_header_t *header)
-{
- rdc_k_info_t *krdc = &rdc_k_info[urdc->index];
-#ifdef DEBUG
- ASSERT(MUTEX_HELD(&krdc->bmapmutex));
-#endif
-
- header->magic = RDC_HDR_MAGIC;
- (void) strncpy(header->primary.file, urdc->primary.file, NSC_MAXPATH);
- (void) strncpy(header->primary.bitmap, urdc->primary.bitmap,
- NSC_MAXPATH);
- (void) strncpy(header->secondary.file, urdc->secondary.file,
- NSC_MAXPATH);
- (void) strncpy(header->secondary.bitmap, urdc->secondary.bitmap,
- NSC_MAXPATH);
- header->flags = urdc->flags | urdc->sync_flags | urdc->bmap_flags;
- header->autosync = urdc->autosync;
- header->maxqfbas = urdc->maxqfbas;
- header->maxqitems = urdc->maxqitems;
- header->asyncthr = urdc->asyncthr;
- header->syshostid = urdc->syshostid;
- header->refcntsize = rdc_refcntsize(krdc);
-#ifdef DEBUG_REFCNT
- cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
- (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
-#endif
-}
-
-/*
- * Must be called with krdc->bmapmutex held.
- */
-static int
-rdc_read_header(rdc_k_info_t *krdc, rdc_header_t *header)
-{
- int sts;
- rdc_u_info_t *urdc;
- union {
- rdc_header_t *current;
- rdc_headerv4_t *v4;
- } u_hdrp;
-
- if (krdc == NULL) {
- return (-1);
- }
-
- ASSERT(MUTEX_HELD(&krdc->bmapmutex));
-
- urdc = &rdc_u_info[krdc->index];
- if (rdc_get_vflags(urdc) & RDC_BMP_FAILED)
- return (-1);
-
- if (krdc->bitmapfd == NULL) {
- return (-1);
- }
- if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
- rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reserve failed");
- return (-1);
- }
-
- if (krdc->bmp_kstats) {
- mutex_enter(krdc->bmp_kstats->ks_lock);
- kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
- mutex_exit(krdc->bmp_kstats->ks_lock);
- }
-
- sts = rdc_ns_io(krdc->bitmapfd, NSC_RDBUF, 0, (uchar_t *)header,
- sizeof (rdc_header_t));
-
- if (krdc->bmp_kstats) {
- mutex_enter(krdc->bmp_kstats->ks_lock);
- kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
- mutex_exit(krdc->bmp_kstats->ks_lock);
- KSTAT_IO_PTR(krdc->bmp_kstats)->reads++;
- KSTAT_IO_PTR(krdc->bmp_kstats)->nread += sizeof (rdc_header_t);
- }
-
- if (!RDC_SUCCESS(sts)) {
- cmn_err(CE_WARN, "!rdc_read_header: %s read failed %d",
- urdc->primary.file, sts);
- rdc_set_flags_log(urdc, RDC_BMP_FAILED, "read header failed");
- }
-
- _rdc_rlse_devs(krdc, RDC_BMP);
-
- if (!RDC_SUCCESS(sts))
- return (-1);
- switch (header->magic) {
- case RDC_HDR_V4:
- /*
- * old header format - upgrade incore copy, disk copy will
- * be changed when state is re-written.
- */
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!sndr: old style (V4) bit map header");
-#endif
- header->magic = RDC_HDR_MAGIC;
- u_hdrp.current = header;
- /* copy down items moved by new maxq??? sizes */
- u_hdrp.current->asyncthr = u_hdrp.v4->asyncthr;
- u_hdrp.current->syshostid = u_hdrp.v4->syshostid;
- u_hdrp.current->maxqitems = u_hdrp.v4->maxqitems;
- u_hdrp.current->maxqfbas = u_hdrp.v4->maxqfbas;
- u_hdrp.current->refcntsize = 1; /* new field */
-#ifdef DEBUG_REFCNT
- cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
- (int)u_hdrp.current->refcntsize, __LINE__, __FILE__);
-#endif
- return (0);
- case RDC_HDR_MAGIC:
- /* current header type */
- return (0);
- default:
- /* not a header we currently understand */
- return (0);
- }
-}
-
-/*
- * Must be called with krdc->bmapmutex held.
- */
-static int
-rdc_write_header(rdc_k_info_t *krdc, rdc_header_t *header)
-{
- rdc_u_info_t *urdc;
- int sts;
-
- if (krdc == NULL) {
- return (-1);
- }
-
- ASSERT(MUTEX_HELD(&krdc->bmapmutex));
-
- urdc = &rdc_u_info[krdc->index];
- if (rdc_get_vflags(urdc) & RDC_BMP_FAILED)
- return (-1);
-
- if (krdc->bitmapfd == NULL) {
- return (-1);
- }
-
- if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
- rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reserve failed");
- return (-1);
- }
-
- if (krdc->bmp_kstats) {
- mutex_enter(krdc->bmp_kstats->ks_lock);
- kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
- mutex_exit(krdc->bmp_kstats->ks_lock);
- }
-
- sts = rdc_ns_io(krdc->bitmapfd, rdc_wrflag, 0, (uchar_t *)header,
- sizeof (rdc_header_t));
-
- if (krdc->bmp_kstats) {
- mutex_enter(krdc->bmp_kstats->ks_lock);
- kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
- mutex_exit(krdc->bmp_kstats->ks_lock);
- KSTAT_IO_PTR(krdc->bmp_kstats)->writes++;
- KSTAT_IO_PTR(krdc->bmp_kstats)->nwritten +=
- sizeof (rdc_header_t);
- }
-
- if (!RDC_SUCCESS(sts)) {
- cmn_err(CE_WARN, "!rdc_write_header: %s write failed %d",
- urdc->primary.file, sts);
- rdc_set_flags_log(urdc, RDC_BMP_FAILED, "write failed");
- }
-
- _rdc_rlse_devs(krdc, RDC_BMP);
-
- if (!RDC_SUCCESS(sts))
- return (-1);
- else
- return (0);
-}
-
-struct bm_ref_ops rdc_ref_byte_ops;
-struct bm_ref_ops rdc_ref_int_ops;
-
-static void
-rdc_set_refcnt_ops(rdc_k_info_t *krdc, size_t refcntsize)
-{
- switch (refcntsize) {
- default:
- /* FALLTHRU */
- case sizeof (unsigned char):
- krdc->bm_refs = &rdc_ref_byte_ops;
- break;
- case sizeof (unsigned int):
- krdc->bm_refs = &rdc_ref_int_ops;
- break;
- }
-#ifdef DEBUG_REFCNT
- cmn_err(CE_NOTE, "!sndr: set refcnt ops for refcntsize %d - %d:%s",
- (int)refcntsize, __LINE__, __FILE__);
-#endif
-}
-
-size_t
-rdc_refcntsize(rdc_k_info_t *krdc)
-{
- if (krdc->bm_refs == &rdc_ref_int_ops)
- return (sizeof (unsigned int));
- return (sizeof (unsigned char));
-}
-
-int
-rdc_read_state(rdc_k_info_t *krdc, int *statep, int *hostidp)
-{
- rdc_header_t header;
- rdc_u_info_t *urdc;
- int sts;
-
- if (krdc == NULL) {
- return (-1);
- }
-
- mutex_enter(&krdc->bmapmutex);
-
- urdc = &rdc_u_info[krdc->index];
- if (rdc_get_vflags(urdc) & RDC_BMP_FAILED) {
- mutex_exit(&krdc->bmapmutex);
- return (-1);
- }
-
- if (krdc->bitmapfd == NULL) {
- mutex_exit(&krdc->bmapmutex);
- return (-1);
- }
-
- sts = rdc_read_header(krdc, &header);
- mutex_exit(&krdc->bmapmutex);
-
- if (!RDC_SUCCESS(sts)) {
- return (-1);
- }
-
- switch (header.magic) {
- case RDC_HDR_MAGIC:
- *statep = header.flags;
- *hostidp = header.syshostid;
- rdc_set_refcnt_ops(krdc, header.refcntsize);
-#ifdef DEBUG_REFCNT
- cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
- (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
-#endif
- sts = 0;
- break;
- default:
- sts = -1;
- break;
- }
-
- return (sts);
-}
-
-int
-rdc_clear_state(rdc_k_info_t *krdc)
-{
- rdc_u_info_t *urdc;
- int sts;
- rdc_header_t header;
-
- if (krdc == NULL) {
- return (-1);
- }
-
- mutex_enter(&krdc->bmapmutex);
-
- urdc = &rdc_u_info[krdc->index];
- if (rdc_get_vflags(urdc) & RDC_BMP_FAILED) {
- mutex_exit(&krdc->bmapmutex);
- return (-1);
- }
-
- if (krdc->bitmapfd == NULL) {
- mutex_exit(&krdc->bmapmutex);
- return (-1);
- }
-
- if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
- rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reserve failed");
- mutex_exit(&krdc->bmapmutex);
- return (-1);
- }
-
- bzero(&header, sizeof (header));
-
- if (krdc->bmp_kstats) {
- mutex_enter(krdc->bmp_kstats->ks_lock);
- kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
- mutex_exit(krdc->bmp_kstats->ks_lock);
- }
-
- sts = rdc_ns_io(krdc->bitmapfd, rdc_wrflag, 0,
- (uchar_t *)&header, sizeof (header));
-
- if (krdc->bmp_kstats) {
- mutex_enter(krdc->bmp_kstats->ks_lock);
- kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
- mutex_exit(krdc->bmp_kstats->ks_lock);
- KSTAT_IO_PTR(krdc->bmp_kstats)->writes++;
- KSTAT_IO_PTR(krdc->bmp_kstats)->nwritten +=
- sizeof (rdc_header_t);
- }
-
- if (!RDC_SUCCESS(sts)) {
- cmn_err(CE_WARN, "!rdc_clear_state: %s write failed",
- urdc->primary.file);
- rdc_set_flags_log(urdc, RDC_BMP_FAILED, "write failed");
- }
-
- _rdc_rlse_devs(krdc, RDC_BMP);
- mutex_exit(&krdc->bmapmutex);
-
- if (!RDC_SUCCESS(sts))
- return (-1);
- else
- return (0);
-}
-
-void
-rdc_write_state(rdc_u_info_t *urdc)
-{
- rdc_k_info_t *krdc;
- int sts;
- rdc_header_t header;
-
- if (urdc == NULL) {
- return;
- }
-
- krdc = &rdc_k_info[urdc->index];
-
- mutex_enter(&krdc->bmapmutex);
-
- if (rdc_get_vflags(urdc) & RDC_BMP_FAILED) {
- mutex_exit(&krdc->bmapmutex);
- return;
- }
-
- if (krdc->bitmapfd == NULL) {
- mutex_exit(&krdc->bmapmutex);
- return;
- }
-
- if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
- rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reserve failed");
- mutex_exit(&krdc->bmapmutex);
- return;
- }
-
- if (krdc->bmp_kstats) {
- mutex_enter(krdc->bmp_kstats->ks_lock);
- kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
- mutex_exit(krdc->bmp_kstats->ks_lock);
- }
-
- sts = rdc_ns_io(krdc->bitmapfd, NSC_RDBUF, 0, (uchar_t *)&header,
- sizeof (header));
-
- if (krdc->bmp_kstats) {
- mutex_enter(krdc->bmp_kstats->ks_lock);
- kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
- mutex_exit(krdc->bmp_kstats->ks_lock);
- KSTAT_IO_PTR(krdc->bmp_kstats)->reads++;
- KSTAT_IO_PTR(krdc->bmp_kstats)->nread += sizeof (header);
- }
-
- if (!RDC_SUCCESS(sts)) {
- cmn_err(CE_WARN, "!rdc_write_state: %s read failed",
- urdc->primary.file);
- rdc_set_flags_log(urdc, RDC_BMP_FAILED, "read failed");
- goto done;
- }
-
- rdc_fill_header(urdc, &header);
-
- if (krdc->bmp_kstats) {
- mutex_enter(krdc->bmp_kstats->ks_lock);
- kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
- mutex_exit(krdc->bmp_kstats->ks_lock);
- }
-
- sts = rdc_ns_io(krdc->bitmapfd, rdc_wrflag, 0,
- (uchar_t *)&header, sizeof (header));
-
- if (krdc->bmp_kstats) {
- mutex_enter(krdc->bmp_kstats->ks_lock);
- kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
- mutex_exit(krdc->bmp_kstats->ks_lock);
- KSTAT_IO_PTR(krdc->bmp_kstats)->writes++;
- KSTAT_IO_PTR(krdc->bmp_kstats)->nwritten += sizeof (header);
- }
-
- if (!RDC_SUCCESS(sts)) {
- cmn_err(CE_WARN, "!rdc_write_state: %s write failed",
- urdc->primary.file);
- rdc_set_flags_log(urdc, RDC_BMP_FAILED, "write failed");
- }
-
-done:
- _rdc_rlse_devs(krdc, RDC_BMP);
- mutex_exit(&krdc->bmapmutex);
-}
-
-
-struct bitmapdata {
- uchar_t *data;
- size_t len;
-};
-
-static int
-rdc_read_bitmap(rdc_k_info_t *krdc, struct bitmapdata *data)
-{
- rdc_u_info_t *urdc;
- int sts;
-
- if (krdc == NULL) {
- return (-1);
- }
-
- if (data != NULL) {
- data->data = kmem_alloc(krdc->bitmap_size, KM_SLEEP);
- data->len = krdc->bitmap_size;
-
- if (data->data == NULL) {
- return (-1);
- }
- }
-
- mutex_enter(&krdc->bmapmutex);
-
- urdc = &rdc_u_info[krdc->index];
- if (rdc_get_vflags(urdc) & RDC_BMP_FAILED) {
- mutex_exit(&krdc->bmapmutex);
- return (-1);
- }
-
- if (krdc->bitmapfd == NULL) {
- mutex_exit(&krdc->bmapmutex);
- return (-1);
- }
-
- if (data == NULL && krdc->dcio_bitmap == NULL) {
- mutex_exit(&krdc->bmapmutex);
- return (-1);
- }
-
- if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
- cmn_err(CE_WARN, "!rdc_read_bitmap: %s reserve failed",
- urdc->primary.file);
- rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reserve failed");
- mutex_exit(&krdc->bmapmutex);
- return (-1);
- }
-
- if (krdc->bmp_kstats) {
- mutex_enter(krdc->bmp_kstats->ks_lock);
- kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
- mutex_exit(krdc->bmp_kstats->ks_lock);
- }
-
- sts = rdc_ns_io(krdc->bitmapfd, NSC_RDBUF, RDC_BITMAP_FBA,
- data ? data->data : krdc->dcio_bitmap, krdc->bitmap_size);
-
- if (krdc->bmp_kstats) {
- mutex_enter(krdc->bmp_kstats->ks_lock);
- kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
- mutex_exit(krdc->bmp_kstats->ks_lock);
- KSTAT_IO_PTR(krdc->bmp_kstats)->reads++;
- KSTAT_IO_PTR(krdc->bmp_kstats)->nread += krdc->bitmap_size;
- }
-
- _rdc_rlse_devs(krdc, RDC_BMP);
-
- if (!RDC_SUCCESS(sts)) {
- cmn_err(CE_WARN, "!rdc_read_bitmap: %s read failed",
- urdc->primary.file);
- rdc_set_flags_log(urdc, RDC_BMP_FAILED, "read failed");
- mutex_exit(&krdc->bmapmutex);
- return (-1);
- }
-
- mutex_exit(&krdc->bmapmutex);
- return (0);
-}
-
-int
-rdc_write_bitmap(rdc_k_info_t *krdc)
-{
- rdc_u_info_t *urdc;
- int sts;
-
- if (krdc == NULL) {
- return (-1);
- }
-
- mutex_enter(&krdc->bmapmutex);
-
- urdc = &rdc_u_info[krdc->index];
- if (rdc_get_vflags(urdc) & RDC_BMP_FAILED) {
- mutex_exit(&krdc->bmapmutex);
- return (-1);
- }
-
- if (krdc->bitmapfd == NULL) {
- mutex_exit(&krdc->bmapmutex);
- return (-1);
- }
-
- if (krdc->dcio_bitmap == NULL) {
- mutex_exit(&krdc->bmapmutex);
- return (-1);
- }
-
- if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
- rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reserve failed");
- mutex_exit(&krdc->bmapmutex);
- return (-1);
- }
-
- if (krdc->bmp_kstats) {
- mutex_enter(krdc->bmp_kstats->ks_lock);
- kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
- mutex_exit(krdc->bmp_kstats->ks_lock);
- }
-
- sts = rdc_ns_io(krdc->bitmapfd, rdc_wrflag, RDC_BITMAP_FBA,
- krdc->dcio_bitmap, krdc->bitmap_size);
-
- if (krdc->bmp_kstats) {
- mutex_enter(krdc->bmp_kstats->ks_lock);
- kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
- mutex_exit(krdc->bmp_kstats->ks_lock);
- KSTAT_IO_PTR(krdc->bmp_kstats)->writes++;
- KSTAT_IO_PTR(krdc->bmp_kstats)->nwritten += krdc->bitmap_size;
- }
-
- _rdc_rlse_devs(krdc, RDC_BMP);
-
- if (!RDC_SUCCESS(sts)) {
- cmn_err(CE_WARN, "!rdc_write_bitmap: %s write failed",
- urdc->primary.file);
- rdc_set_flags_log(urdc, RDC_BMP_FAILED, "write failed");
- mutex_exit(&krdc->bmapmutex);
- return (-1);
- }
-
- mutex_exit(&krdc->bmapmutex);
- return (0);
-}
-
-int
-rdc_write_bitmap_fba(rdc_k_info_t *krdc, nsc_off_t fba)
-{
- rdc_u_info_t *urdc;
- int sts;
-
- if (krdc == NULL) {
- return (-1);
- }
-
- mutex_enter(&krdc->bmapmutex);
-
- urdc = &rdc_u_info[krdc->index];
- if (rdc_get_vflags(urdc) & RDC_BMP_FAILED) {
- mutex_exit(&krdc->bmapmutex);
- return (-1);
- }
-
- if (krdc->bitmapfd == NULL) {
- mutex_exit(&krdc->bmapmutex);
- return (-1);
- }
-
- if (krdc->dcio_bitmap == NULL) {
- mutex_exit(&krdc->bmapmutex);
- return (-1);
- }
-
- if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
- cmn_err(CE_WARN, "!rdc_write_bitmap_fba: %s reserve failed",
- urdc->primary.file);
- rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reserve failed");
- mutex_exit(&krdc->bmapmutex);
- return (-1);
- }
-
- if (krdc->bmp_kstats) {
- mutex_enter(krdc->bmp_kstats->ks_lock);
- kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
- mutex_exit(krdc->bmp_kstats->ks_lock);
- }
- sts = rdc_ns_io(krdc->bitmapfd, rdc_wrflag, RDC_BITMAP_FBA + fba,
- krdc->dcio_bitmap + fba * 512, 512);
-
- if (krdc->bmp_kstats) {
- mutex_enter(krdc->bmp_kstats->ks_lock);
- kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
- mutex_exit(krdc->bmp_kstats->ks_lock);
- KSTAT_IO_PTR(krdc->bmp_kstats)->writes++;
- KSTAT_IO_PTR(krdc->bmp_kstats)->nwritten += 512;
- }
-
- _rdc_rlse_devs(krdc, RDC_BMP);
-
- if (!RDC_SUCCESS(sts)) {
- cmn_err(CE_WARN, "!rdc_write_bitmap_fba: %s write failed",
- urdc->primary.file);
- rdc_set_flags_log(urdc, RDC_BMP_FAILED, "write failed");
- mutex_exit(&krdc->bmapmutex);
- return (-1);
- }
-
- mutex_exit(&krdc->bmapmutex);
- return (0);
-}
-
-
-static int
-rdc_write_bitmap_pattern(rdc_k_info_t *krdc, const char pattern)
-{
- rdc_u_info_t *urdc;
- char *buffer;
- nsc_buf_t *h;
- nsc_vec_t *v;
- int rc;
- size_t i;
- nsc_size_t len;
- int off;
- size_t buffer_size;
- size_t iolen;
- nsc_size_t fba_req;
- nsc_off_t fba_len, fba_pos;
- nsc_size_t maxfbas = 0;
- nsc_size_t tocopy;
-
- if (krdc == NULL) {
- return (-1);
- }
-
- mutex_enter(&krdc->bmapmutex);
-
- urdc = &rdc_u_info[krdc->index];
- if (rdc_get_vflags(urdc) & RDC_BMP_FAILED) {
- mutex_exit(&krdc->bmapmutex);
- return (-1);
- }
-
- if (krdc->bitmapfd == NULL) {
- mutex_exit(&krdc->bmapmutex);
- return (-1);
- }
-
- if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
- rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reserve failed");
- mutex_exit(&krdc->bmapmutex);
- return (-1);
- }
-
- buffer_size = FBA_SIZE(1);
- ASSERT(buffer_size < INT32_MAX);
- buffer = kmem_alloc(buffer_size, KM_SLEEP);
-
- for (i = 0; i < buffer_size; i++) {
- buffer[i] = pattern;
- }
-
- rc = nsc_maxfbas(krdc->bitmapfd, 0, &maxfbas);
- if (!RDC_SUCCESS(rc)) {
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!rdc_write_bitmap_pattern: maxfbas failed (%d)", rc);
-#endif
- maxfbas = 256;
- }
-
- fba_req = FBA_LEN(krdc->bitmap_size); /* total FBAs left to copy */
- fba_pos = RDC_BITMAP_FBA; /* current FBA position */
- tocopy = krdc->bitmap_size; /* total bytes left to copy */
-loop:
- h = NULL;
- fba_len = min(fba_req, maxfbas); /* FBAs to alloc this time */
-
- rc = nsc_alloc_buf(krdc->bitmapfd, fba_pos, fba_len, rdc_wrflag, &h);
- if (!RDC_SUCCESS(rc)) {
- cmn_err(CE_WARN, "!rdc_write_bitmap_pattern: %s "
- "write failed %d", urdc->primary.file, rc);
- rdc_set_flags_log(urdc, RDC_BMP_FAILED, "nsc_alloc_buf failed");
- if (h) {
- (void) nsc_free_handle(h);
- }
-
- _rdc_rlse_devs(krdc, RDC_BMP);
- mutex_exit(&krdc->bmapmutex);
- rc = -1;
- goto finish;
- }
-
- /* bytes to copy this time */
- len = min(tocopy, FBA_SIZE(fba_len));
- v = h->sb_vec;
- off = 0;
-
- while (len) {
- if (off >= v->sv_len) {
- off = 0;
- v++;
- }
-
- if (v->sv_addr == 0 || v->sv_len == 0) {
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!rdc_write_bitmap_pattern: ran off end of handle");
-#endif
- break;
- }
-
- iolen = (size_t)min(len, buffer_size);
-
- bcopy(buffer, (char *)(v->sv_addr + off), iolen);
- off += iolen;
- len -= iolen;
- }
-
- rc = nsc_write(h, h->sb_pos, h->sb_len, 0);
- if (!RDC_SUCCESS(rc)) {
- cmn_err(CE_WARN, "!rdc_write_bitmap_pattern: "
- "%s write failed %d", urdc->primary.file, rc);
- rdc_set_flags_log(urdc, RDC_BMP_FAILED, "write failed");
- (void) nsc_free_buf(h);
- _rdc_rlse_devs(krdc, RDC_BMP);
- mutex_exit(&krdc->bmapmutex);
- rc = -1;
- goto finish;
- }
-
- (void) nsc_free_buf(h);
-
- fba_pos += fba_len;
- fba_req -= fba_len;
- tocopy -= FBA_SIZE(fba_len); /* adjust byte length remaining */
- if (fba_req > 0)
- goto loop;
-
- _rdc_rlse_devs(krdc, RDC_BMP);
- mutex_exit(&krdc->bmapmutex);
- rc = 0;
-finish:
- kmem_free(buffer, buffer_size);
- return (rc);
-}
-
-
-/*
- * rdc_write_bitmap_fill()
- *
- * Write a bitmap full of 1's out to disk without touching the
- * in-memory bitmap.
- */
-int
-rdc_write_bitmap_fill(rdc_k_info_t *krdc)
-{
- return (rdc_write_bitmap_pattern(krdc, 0xff));
-}
-
-
-void
-rdc_merge_bitmaps(rdc_k_info_t *src, rdc_k_info_t *dst)
-{
- if (src->dcio_bitmap == NULL || dst->dcio_bitmap == NULL)
- return;
-
- rdc_lor(src->dcio_bitmap, dst->dcio_bitmap,
- min(src->bitmap_size, dst->bitmap_size));
- if (dst->bitmap_write > 0)
- (void) rdc_write_bitmap(dst);
-}
-
-
-/*
- * bitmap size in bytes, vol_size fba's
- */
-
-size_t
-rdc_ref_size_possible(nsc_size_t bitmap_size, nsc_size_t vol_size)
-{
- nsc_size_t ref_size;
- nsc_size_t bitmap_end_fbas;
-
- bitmap_end_fbas = RDC_BITMAP_FBA + FBA_LEN(bitmap_size);
- ref_size = FBA_LEN(bitmap_size * BITS_IN_BYTE * sizeof (unsigned char));
- if (bitmap_end_fbas + ref_size > vol_size)
- return ((size_t)0);
-
- ref_size = FBA_LEN(bitmap_size * BITS_IN_BYTE * sizeof (unsigned int));
- if (bitmap_end_fbas + ref_size > vol_size)
- return (sizeof (unsigned char));
- return (sizeof (unsigned int));
-}
-
-int
-rdc_move_bitmap(rdc_k_info_t *krdc, char *newbitmap)
-{
- rdc_u_info_t *urdc;
- nsc_fd_t *oldfd;
- nsc_fd_t *newfd = NULL;
- rdc_header_t header;
- int sts;
- nsc_size_t vol_size;
- nsc_size_t req_size;
- size_t ref_size;
-
- if (krdc == NULL) {
- return (-1);
- }
-
- if (krdc->bitmapfd == NULL) {
- return (-1);
- }
-
- req_size = RDC_BITMAP_FBA + FBA_LEN(krdc->bitmap_size);
- if (RDC_IS_DISKQ(krdc->group)) {
- /* new volume must support at least the old refcntsize */
- req_size += FBA_LEN(krdc->bitmap_size * BITS_IN_BYTE *
- rdc_refcntsize(krdc));
-#ifdef DEBUG_REFCNT
- cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
- (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
-#endif
- }
-
- mutex_enter(&krdc->bmapmutex);
-
- if (rdc_read_header(krdc, &header) < 0) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!rdc_move_bitmap: Read old header failed");
-#endif
- mutex_exit(&krdc->bmapmutex);
- return (-1);
- }
-
- oldfd = krdc->bitmapfd;
-
- newfd = nsc_open(newbitmap, NSC_RDCHR_ID|NSC_FILE|NSC_RDWR, 0, 0, 0);
- if (newfd == NULL) {
- newfd = nsc_open(newbitmap,
- NSC_RDCHR_ID|NSC_CACHE|NSC_DEVICE|NSC_RDWR, 0, 0, 0);
- if (newfd == NULL) {
- /* Can't open new bitmap */
- cmn_err(CE_WARN,
- "!rdc_move_bitmap: Cannot open new bitmap %s",
- newbitmap);
- goto fail;
- }
- }
-
- sts = nsc_reserve(newfd, 0);
- if (!RDC_SUCCESS(sts)) {
- cmn_err(CE_WARN, "!rdc_move_bitmap: Reserve failed for %s",
- newbitmap);
- goto fail;
- }
- sts = nsc_partsize(newfd, &vol_size);
- nsc_release(newfd);
-
- if (!RDC_SUCCESS(sts)) {
- cmn_err(CE_WARN,
- "!rdc_move_bitmap: nsc_partsize failed for %s", newbitmap);
- goto fail;
- }
-
- ref_size = rdc_ref_size_possible(krdc->bitmap_size, vol_size);
-
- if (vol_size < req_size) {
- cmn_err(CE_WARN,
- "!rdc_move_bitmap: bitmap %s too small: %" NSC_SZFMT
- " vs %" NSC_SZFMT " blocks", newbitmap, vol_size, req_size);
- goto fail;
- }
-
- mutex_enter(&krdc->devices->id_rlock);
- krdc->bitmapfd = newfd; /* swap under lock */
- if (krdc->bmaprsrv > 0) {
- sts = nsc_reserve(krdc->bitmapfd, 0);
- if (!RDC_SUCCESS(sts)) {
- krdc->bitmapfd = oldfd; /* replace under lock */
- mutex_exit(&krdc->devices->id_rlock);
- cmn_err(CE_WARN,
- "!rdc_move_bitmap: Reserve failed for %s",
- newbitmap);
- goto fail;
- }
- }
- rdc_set_refcnt_ops(krdc, ref_size);
-#ifdef DEBUG_REFCNT
- cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
- (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
-#endif
- mutex_exit(&krdc->devices->id_rlock);
-
- /* Forget newfd now it is krdc->bitmapfd */
- newfd = NULL;
-
- /* Put new bitmap name into header and user-visible data structure */
- urdc = &rdc_u_info[krdc->index];
- if (rdc_get_vflags(urdc) & RDC_PRIMARY) {
- (void) strncpy(header.primary.bitmap, newbitmap, NSC_MAXPATH);
- (void) strncpy(urdc->primary.bitmap, newbitmap, NSC_MAXPATH);
- } else {
- (void) strncpy(header.secondary.bitmap, newbitmap, NSC_MAXPATH);
- (void) strncpy(urdc->secondary.bitmap, newbitmap, NSC_MAXPATH);
- }
-
- if (rdc_write_header(krdc, &header) < 0) {
- cmn_err(CE_WARN,
- "!rdc_move_bitmap: Write header %s failed", newbitmap);
- goto fail;
- }
-
- mutex_exit(&krdc->bmapmutex);
-
- if (rdc_write_bitmap(krdc) < 0) {
- mutex_enter(&krdc->bmapmutex);
- cmn_err(CE_WARN,
- "!rdc_move_bitmap: Write bitmap %s failed", newbitmap);
- goto fail;
- }
-
- /* Unintercept the old bitmap */
- if (krdc->b_tok) {
- int rc;
-
- rdc_group_exit(krdc);
- rc = nsc_unregister_path(krdc->b_tok, 0);
- if (rc)
- cmn_err(CE_WARN, "!rdc_move_bitmap: "
- "unregister bitmap failed %d", rc);
- else
- krdc->b_tok = nsc_register_path(newbitmap,
- NSC_CACHE | NSC_DEVICE, _rdc_io_hc);
- rdc_group_enter(krdc);
- }
-
- /* clear the old bitmap header */
- bzero(&header, sizeof (header));
-
- sts = nsc_held(oldfd) ? 0 : nsc_reserve(oldfd, 0);
- if (sts == 0) {
-
- if (krdc->bmp_kstats) {
- mutex_enter(krdc->bmp_kstats->ks_lock);
- kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
- mutex_exit(krdc->bmp_kstats->ks_lock);
- }
-
- sts = rdc_ns_io(oldfd, rdc_wrflag, 0,
- (uchar_t *)&header, sizeof (header));
-
- if (krdc->bmp_kstats) {
- mutex_enter(krdc->bmp_kstats->ks_lock);
- kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
- mutex_exit(krdc->bmp_kstats->ks_lock);
- KSTAT_IO_PTR(krdc->bmp_kstats)->writes++;
- KSTAT_IO_PTR(krdc->bmp_kstats)->nwritten +=
- sizeof (header);
- }
-
- }
-#ifdef DEBUG
- if (sts != 0) {
- cmn_err(CE_WARN,
- "!rdc_move_bitmap: unable to clear bitmap header on %s",
- nsc_pathname(oldfd));
- }
-#endif
-
- /* nsc_close will undo any reservation */
- if (nsc_close(oldfd) != 0) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!rdc_move_bitmap: close old bitmap failed");
-#else
- ;
- /*EMPTY*/
-#endif
- }
-
- return (0);
-
-fail:
- /* Close newfd if it was unused */
- if (newfd && newfd != krdc->bitmapfd) {
- (void) nsc_close(newfd);
- newfd = NULL;
- }
-
- mutex_exit(&krdc->bmapmutex);
- return (-1);
-}
-
-
-void
-rdc_close_bitmap(rdc_k_info_t *krdc)
-{
-
- if (krdc == NULL) {
- return;
- }
-
- mutex_enter(&krdc->bmapmutex);
-
- if (krdc->bitmapfd) {
- if (nsc_close(krdc->bitmapfd) != 0) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!nsc_close on bitmap failed");
-#else
- ;
- /*EMPTY*/
-#endif
- }
- krdc->bitmapfd = 0;
- }
-
- mutex_exit(&krdc->bmapmutex);
-}
-
-void
-rdc_free_bitmap(rdc_k_info_t *krdc, int cmd)
-{
- rdc_header_t header;
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
-
- if (krdc == NULL) {
- return;
- }
-
- mutex_enter(&krdc->bmapmutex);
-
- if (cmd != RDC_CMD_SUSPEND) {
-
- bzero((char *)&header, sizeof (rdc_header_t));
-
- if (krdc->bitmapfd)
- (void) rdc_write_header(krdc, &header);
- } else {
- mutex_exit(&krdc->bmapmutex);
- /* gotta drop mutex, in case q needs to fail */
- if (RDC_IS_DISKQ(krdc->group) && rdc_suspend_diskq(krdc) < 0) {
- cmn_err(CE_WARN,
- "!rdc_free_bitmap: diskq suspend failed");
- }
-
- mutex_enter(&krdc->bmapmutex);
- if (rdc_read_header(krdc, &header) < 0) {
- cmn_err(CE_WARN,
- "!rdc_free_bitmap: Read header failed");
- } else {
- rdc_fill_header(urdc, &header);
-
- (void) rdc_write_header(krdc, &header);
- }
- }
-
- mutex_exit(&krdc->bmapmutex);
-
- if (krdc->dcio_bitmap != NULL) {
- if (cmd == RDC_CMD_SUSPEND) {
- if (krdc->bitmapfd)
- (void) rdc_write_bitmap(krdc);
- }
-
- kmem_free(krdc->dcio_bitmap, krdc->bitmap_size);
- krdc->dcio_bitmap = NULL;
- }
- if (krdc->bitmap_ref != NULL) {
- kmem_free(krdc->bitmap_ref, (krdc->bitmap_size * BITS_IN_BYTE *
- BMAP_REF_PREF_SIZE));
- krdc->bitmap_ref = NULL;
- }
-
- krdc->bitmap_size = 0;
-}
-
-static int
-rdc_alloc_bitmap(rdc_k_info_t *krdc)
-{
- rdc_u_info_t *urdc;
- char *bitmapname;
- nsc_size_t bitmap_ref_size;
-
- if (krdc == NULL) {
- return (-1);
- }
-
- urdc = &rdc_u_info[krdc->index];
- if (rdc_get_vflags(urdc) & RDC_PRIMARY)
- bitmapname = &urdc->primary.bitmap[0];
- else
- bitmapname = &urdc->secondary.bitmap[0];
-
- if (krdc->dcio_bitmap) {
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!rdc_alloc_bitmap: bitmap %s already allocated",
- bitmapname);
-#endif
- return (0);
- }
-
- if (urdc->volume_size == 0)
- return (-1);
-
- krdc->bitmap_size = BMAP_LOG_BYTES(urdc->volume_size);
- /* Round up */
- krdc->bitmap_size = (krdc->bitmap_size + 511) / 512 * 512;
-
- krdc->dcio_bitmap = (uchar_t *)kmem_zalloc(krdc->bitmap_size,
- KM_SLEEP);
- if (krdc->dcio_bitmap == NULL) {
- cmn_err(CE_WARN, "!rdc_alloc_bitmap: alloc %" NSC_SZFMT
- " failed for %s", krdc->bitmap_size, bitmapname);
- return (-1);
- }
-
- /*
- * use largest ref count type size as we haven't opened the bitmap
- * volume yet to find out what has acutally be used.
- */
- bitmap_ref_size = krdc->bitmap_size * BITS_IN_BYTE * BMAP_REF_PREF_SIZE;
- if ((rdc_get_vflags(urdc) & RDC_PRIMARY) &&
- ((krdc->type_flag & RDC_ASYNCMODE) != 0)) {
- krdc->bitmap_ref = (uchar_t *)kmem_zalloc(bitmap_ref_size,
- KM_SLEEP);
- if (krdc->bitmap_ref == NULL) {
- cmn_err(CE_WARN,
- "!rdc_alloc_bitmap: ref alloc %" NSC_SZFMT
- " failed for %s",
- bitmap_ref_size, bitmapname);
- return (-1);
- }
- }
-
- return (0);
-}
-
-
-static int
-rdc_open_bitmap(rdc_k_info_t *krdc)
-{
- rdc_u_info_t *urdc;
- int sts;
- uint_t hints = 0;
- nsc_size_t vol_size;
- char *bitmapname;
- nsc_size_t req_size;
- nsc_size_t bit_size;
-
- urdc = &rdc_u_info[krdc->index];
- if (rdc_get_vflags(urdc) & RDC_PRIMARY)
- bitmapname = &urdc->primary.bitmap[0];
- else
- bitmapname = &urdc->secondary.bitmap[0];
-
- urdc->bits_set = 0;
-
- bit_size = req_size = RDC_BITMAP_FBA + FBA_LEN(krdc->bitmap_size);
- if (RDC_IS_DISKQ(krdc->group)) {
- req_size += FBA_LEN(krdc->bitmap_size * BITS_IN_BYTE *
- sizeof (unsigned char));
- }
-
- mutex_enter(&krdc->bmapmutex);
-
- rdc_set_refcnt_ops(krdc, sizeof (unsigned char));
-#ifdef DEBUG_REFCNT
- cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
- (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
-#endif
- if (krdc->bitmapfd == NULL)
- krdc->bitmapfd = nsc_open(bitmapname,
- NSC_RDCHR_ID|NSC_FILE|NSC_RDWR, 0, 0, 0);
- if (krdc->bitmapfd == NULL) {
- krdc->bitmapfd = nsc_open(bitmapname,
- NSC_RDCHR_ID|NSC_CACHE|NSC_DEVICE|NSC_RDWR, 0, 0, 0);
- if (krdc->bitmapfd == NULL) {
- cmn_err(CE_WARN, "!rdc_open_bitmap: Unable to open %s",
- bitmapname);
- goto fail;
- }
- }
-
- sts = _rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL);
- if (!RDC_SUCCESS(sts)) {
- cmn_err(CE_WARN, "!rdc_open_bitmap: Reserve failed for %s",
- bitmapname);
- goto fail;
- }
- sts = nsc_partsize(krdc->bitmapfd, &vol_size);
- _rdc_rlse_devs(krdc, RDC_BMP);
-
- if (!RDC_SUCCESS(sts)) {
- cmn_err(CE_WARN,
- "!rdc_open_bitmap: nsc_partsize failed for %s", bitmapname);
- goto fail;
- }
-
- if (vol_size < req_size) {
- /* minimum size supports unsigned char reference counts */
- cmn_err(CE_WARN,
- "!rdc_open_bitmap: bitmap %s too small: %" NSC_SZFMT " vs %"
- NSC_SZFMT "blocks",
- bitmapname, vol_size, req_size);
- goto fail;
- }
-
- if (rdc_bitmap_mode == RDC_BMP_NEVER) {
- krdc->bitmap_write = 0; /* forced off */
- } else if (rdc_bitmap_mode == RDC_BMP_ALWAYS ||
- (nsc_node_hints(&hints) == 0 && (hints & NSC_FORCED_WRTHRU) == 0)) {
- krdc->bitmap_write = 1; /* forced or autodetect on */
- } else {
- /* autodetect off */
- krdc->bitmap_write = 0;
- }
-
- mutex_exit(&krdc->bmapmutex);
- if (RDC_IS_DISKQ(krdc->group) && (rdc_refcntsize(krdc) <
- BMAP_REF_PREF_SIZE)) {
- /* test for larger ref counts */
-#ifdef DEBUG_REFCNT
- cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
- (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
-#endif
- req_size = bit_size;
- req_size += FBA_LEN(krdc->bitmap_size * BITS_IN_BYTE *
- sizeof (unsigned int));
- if (vol_size >= req_size)
- rdc_set_refcnt_ops(krdc, sizeof (unsigned int));
- }
-#ifdef DEBUG_REFCNT
- cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
- (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
-#endif
- return (0);
-
-fail:
- mutex_exit(&krdc->bmapmutex);
- return (-1);
-}
-
-int
-rdc_enable_bitmap(rdc_k_info_t *krdc, int set)
-{
- rdc_header_t header;
- rdc_u_info_t *urdc;
- char *bitmapname;
-
- urdc = &rdc_u_info[krdc->index];
-
- if (rdc_alloc_bitmap(krdc) < 0)
- goto fail;
-
- if (rdc_open_bitmap(krdc) < 0)
- goto fail;
-
- if (rdc_get_vflags(urdc) & RDC_PRIMARY)
- bitmapname = &urdc->primary.bitmap[0];
- else
- bitmapname = &urdc->secondary.bitmap[0];
-
- mutex_enter(&krdc->bmapmutex);
-
- rdc_clr_flags(urdc, RDC_BMP_FAILED);
- if (rdc_read_header(krdc, &header) < 0) {
- cmn_err(CE_WARN,
- "!rdc_enable_bitmap: Read header %s failed", bitmapname);
- mutex_exit(&krdc->bmapmutex);
- goto fail;
- }
-
- rdc_fill_header(urdc, &header);
- rdc_set_refcnt_ops(krdc, (size_t)header.refcntsize);
-
- if (set)
- (void) RDC_FILL_BITMAP(krdc, FALSE);
-
- if (rdc_write_header(krdc, &header) < 0) {
- cmn_err(CE_WARN,
- "!rdc_enable_bitmap: Write header %s failed",
- bitmapname);
- mutex_exit(&krdc->bmapmutex);
- goto fail;
- }
- mutex_exit(&krdc->bmapmutex);
-
- if (rdc_write_bitmap(krdc) < 0) {
- cmn_err(CE_WARN,
- "!rdc_enable_bitmap: Write bitmap %s failed",
- bitmapname);
- goto fail;
- }
-
- return (0);
-
-fail:
- rdc_free_bitmap(krdc, RDC_CMD_ENABLE);
- rdc_close_bitmap(krdc);
-
- mutex_enter(&krdc->bmapmutex);
- rdc_set_flags_log(urdc, RDC_BMP_FAILED, "I/O failed");
- mutex_exit(&krdc->bmapmutex);
- return (-1);
-}
-
-static int
-_rdc_rdwr_refcnt(rdc_k_info_t *krdc, int rwflg)
-{
- rdc_u_info_t *urdc;
- int rc;
- nsc_off_t offset;
- nsc_size_t len;
-
- urdc = &rdc_u_info[krdc->index];
-
-#ifdef DEBUG_REFCNT
- cmn_err(CE_NOTE, "!rdc_rdwr_refcnt: %s refcount for %s",
- (rwflg == NSC_READ) ? "resuming" : "writing",
- urdc->primary.bitmap);
-#endif
- ASSERT(MUTEX_HELD(QLOCK((&krdc->group->diskq))));
- mutex_enter(&krdc->bmapmutex);
-
- if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
- cmn_err(CE_WARN, "!rdc_rdwr_refcnt: reserve failed");
- goto fail;
- }
-
- if (krdc->bitmap_size == 0) {
- cmn_err(CE_WARN, "!rdc_rdwr_refcnt: NULL bitmap!");
- goto fail;
- }
-
- offset = RDC_BITREF_FBA(krdc);
- len = krdc->bitmap_size * BITS_IN_BYTE * rdc_refcntsize(krdc);
-
- rc = rdc_ns_io(krdc->bitmapfd, rwflg, offset,
- (uchar_t *)krdc->bitmap_ref, len);
-
- if (!RDC_SUCCESS(rc)) {
- cmn_err(CE_WARN, "!unable to %s refcount from bitmap %s",
- (rwflg == NSC_READ) ? "retrieve" : "write",
- urdc->primary.bitmap);
- rdc_set_flags_log(urdc, RDC_BMP_FAILED, "refcount I/O failed");
- goto fail;
- }
-
- _rdc_rlse_devs(krdc, RDC_BMP);
-
- mutex_exit(&krdc->bmapmutex);
-
-#ifdef DEBUG_REFCNT
- cmn_err(CE_NOTE, "!rdc_rdwr_refcnt: %s refcount for %s",
- (rwflg == NSC_READ) ? "resumed" : "wrote",
- urdc->primary.bitmap);
-#endif
- return (0);
-
- fail:
- _rdc_rlse_devs(krdc, RDC_BMP);
-
- mutex_exit(&krdc->bmapmutex);
-
- return (-1);
-
-}
-
-/*
- * rdc_read_refcount
- * read the stored refcount from disk
- * queue lock is held
- */
-int
-rdc_read_refcount(rdc_k_info_t *krdc)
-{
- int rc;
-
- rc = _rdc_rdwr_refcnt(krdc, NSC_READ);
-
- return (rc);
-}
-
-/*
- * rdc_write_refcount
- * writes krdc->bitmap_ref to the diskq
- * called with qlock held
- */
-int
-rdc_write_refcount(rdc_k_info_t *krdc)
-{
- int rc;
-
- rc = _rdc_rdwr_refcnt(krdc, NSC_WRBUF);
-
- return (rc);
-}
-
-static int
-rdc_resume_state(rdc_k_info_t *krdc, const rdc_header_t *header)
-{
- rdc_u_info_t *urdc;
- char *bitmapname;
-
- urdc = &rdc_u_info[krdc->index];
- if (rdc_get_vflags(urdc) & RDC_PRIMARY)
- bitmapname = &urdc->primary.bitmap[0];
- else
- bitmapname = &urdc->secondary.bitmap[0];
-
- if (header->magic != RDC_HDR_MAGIC) {
- cmn_err(CE_WARN, "!rdc_resume_state: Bad magic in %s",
- bitmapname);
- return (-1);
- }
-
- if (strncmp(urdc->primary.file, header->primary.file,
- NSC_MAXPATH) != 0) {
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!rdc_resume_state: Found %s Expected %s",
- header->primary.file, urdc->primary.file);
-#endif /* DEBUG */
- return (-1);
- }
-
- if (strncmp(urdc->secondary.file, header->secondary.file,
- NSC_MAXPATH) != 0) {
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!rdc_resume_state: Found %s Expected %s",
- header->secondary.file, urdc->secondary.file);
-#endif /* DEBUG */
- return (-1);
- }
-
- if (strncmp(urdc->primary.bitmap, header->primary.bitmap,
- NSC_MAXPATH) != 0) {
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!rdc_resume_state: Found %s Expected %s",
- header->primary.bitmap, urdc->primary.bitmap);
-#endif /* DEBUG */
- return (-1);
- }
-
- if (strncmp(urdc->secondary.bitmap, header->secondary.bitmap,
- NSC_MAXPATH) != 0) {
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!rdc_resume_state: Found %s Expected %s",
- header->secondary.bitmap, urdc->secondary.bitmap);
-#endif /* DEBUG */
- return (-1);
- }
-
- if (header->maxqfbas)
- urdc->maxqfbas = header->maxqfbas;
-
- if (header->maxqitems)
- urdc->maxqitems = header->maxqitems;
-
- if (header->autosync >= 0)
- urdc->autosync = header->autosync;
-
- if (header->asyncthr)
- urdc->asyncthr = header->asyncthr;
-
- rdc_many_enter(krdc);
- rdc_set_refcnt_ops(krdc, header->refcntsize);
-#ifdef DEBUG_REFCNT
- cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
- (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
-#endif
- if (header->flags & RDC_VOL_FAILED)
- rdc_set_flags(urdc, RDC_VOL_FAILED);
- if (header->flags & RDC_QUEUING)
- rdc_set_flags(urdc, RDC_QUEUING);
-
- rdc_clr_flags(urdc, RDC_SYNC_NEEDED | RDC_RSYNC_NEEDED);
- rdc_set_mflags(urdc, (header->flags & RDC_RSYNC_NEEDED));
- rdc_set_flags(urdc, (header->flags & RDC_SYNC_NEEDED));
- rdc_many_exit(krdc);
-
- if (urdc->flags & RDC_VOL_FAILED) {
-
- /* Our disk was failed so set all the bits in the bitmap */
-
- if (RDC_FILL_BITMAP(krdc, TRUE) != 0) {
- cmn_err(CE_WARN,
- "!rdc_resume_state: Fill bitmap %s failed",
- bitmapname);
- return (-1);
- }
- rdc_many_enter(krdc);
- if (IS_STATE(urdc, RDC_QUEUING))
- rdc_clr_flags(urdc, RDC_QUEUING);
- rdc_many_exit(krdc);
- } else {
- /* Header was good, so read in the bitmap */
-
- if (rdc_read_bitmap(krdc, NULL) < 0) {
- cmn_err(CE_WARN,
- "!rdc_resume_state: Read bitmap %s failed",
- bitmapname);
- return (-1);
- }
-
- urdc->bits_set = RDC_COUNT_BITMAP(krdc);
-
- /*
- * Check if another node went down with bits set, but
- * without setting logging mode.
- */
- if (urdc->bits_set != 0 &&
- (rdc_get_vflags(urdc) & RDC_ENABLED) &&
- !(rdc_get_vflags(urdc) & RDC_LOGGING)) {
- rdc_group_log(krdc, RDC_NOFLUSH | RDC_NOREMOTE, NULL);
- }
- }
-
- /* if we are using a disk queue, read in the reference count bits */
- if (RDC_IS_DISKQ(krdc->group)) {
- disk_queue *q = &krdc->group->diskq;
- mutex_enter(QLOCK(q));
- if ((rdc_read_refcount(krdc) < 0)) {
- cmn_err(CE_WARN,
- "!rdc_resume_state: Resume bitmap %s's refcount"
- "failed",
- urdc->primary.bitmap);
- mutex_exit(QLOCK(q));
- rdc_many_enter(krdc);
- if (IS_STATE(urdc, RDC_QUEUING))
- rdc_clr_flags(urdc, RDC_QUEUING);
- rdc_many_exit(krdc);
- return (-1);
- }
- mutex_exit(QLOCK(q));
- }
-
- return (0);
-}
-
-
-int
-rdc_resume_bitmap(rdc_k_info_t *krdc)
-{
- rdc_header_t header;
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- char *bitmapname;
-
- if (rdc_alloc_bitmap(krdc) < 0)
- goto allocfail;
-
- if (rdc_open_bitmap(krdc) < 0)
- goto fail;
-
- if (rdc_get_vflags(urdc) & RDC_PRIMARY)
- bitmapname = &urdc->primary.bitmap[0];
- else
- bitmapname = &urdc->secondary.bitmap[0];
-
- mutex_enter(&krdc->bmapmutex);
-
- rdc_clr_flags(urdc, RDC_BMP_FAILED);
- if (rdc_read_header(krdc, &header) < 0) {
- cmn_err(CE_WARN,
- "!rdc_resume_bitmap: Read header %s failed", bitmapname);
- mutex_exit(&krdc->bmapmutex);
- goto fail;
- }
-
- mutex_exit(&krdc->bmapmutex);
-
- /* Resuming from the bitmap, so do some checking */
-
- /*CONSTCOND*/
- ASSERT(FBA_LEN(sizeof (rdc_header_t)) <= RDC_BITMAP_FBA);
- /*CONSTCOND*/
- ASSERT(sizeof (rdc_header_t) >= sizeof (rdc_headerv2_t));
-
- if (header.magic == RDC_HDR_V2) {
- rdc_headerv2_t *hdr_v2 = (rdc_headerv2_t *)&header;
- rdc_header_t new_header;
-
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!rdc_resume_bitmap: Converting v2 header for bitmap %s",
- bitmapname);
-#endif
- bzero((char *)&new_header, sizeof (rdc_header_t));
-
- new_header.autosync = -1;
- new_header.magic = RDC_HDR_MAGIC;
- new_header.syshostid = urdc->syshostid;
-
- if (hdr_v2->volume_failed)
- new_header.flags |= RDC_VOL_FAILED;
- if (hdr_v2->sync_needed == RDC_SYNC)
- new_header.flags |= RDC_SYNC_NEEDED;
- if (hdr_v2->sync_needed == RDC_FULL_SYNC)
- new_header.flags |= RDC_SYNC_NEEDED;
- if (hdr_v2->sync_needed == RDC_REV_SYNC)
- new_header.flags |= RDC_RSYNC_NEEDED;
- if (rdc_get_vflags(urdc) & RDC_PRIMARY) {
- (void) strncpy(new_header.primary.file,
- hdr_v2->filename, NSC_MAXPATH);
- (void) strncpy(new_header.primary.bitmap,
- hdr_v2->bitmapname, NSC_MAXPATH);
- (void) strncpy(new_header.secondary.file,
- urdc->secondary.file, NSC_MAXPATH);
- (void) strncpy(new_header.secondary.bitmap,
- urdc->secondary.bitmap, NSC_MAXPATH);
- } else {
- (void) strncpy(new_header.secondary.file,
- hdr_v2->filename, NSC_MAXPATH);
- (void) strncpy(new_header.secondary.bitmap,
- hdr_v2->bitmapname, NSC_MAXPATH);
- (void) strncpy(new_header.primary.file,
- urdc->primary.file, NSC_MAXPATH);
- (void) strncpy(new_header.primary.bitmap,
- urdc->primary.bitmap, NSC_MAXPATH);
- }
-
- bcopy(&new_header, &header, sizeof (rdc_header_t));
-
- mutex_enter(&krdc->bmapmutex);
- if (rdc_write_header(krdc, &header) < 0) {
- mutex_exit(&krdc->bmapmutex);
- cmn_err(CE_WARN,
- "!rdc_resume_bitmap: Write header %s failed",
- bitmapname);
- goto fail;
- }
- mutex_exit(&krdc->bmapmutex);
-
- } else if (header.magic == RDC_HDR_V3) {
- /*
- * just update asyncthr and magic, and then we're done
- */
- header.magic = RDC_HDR_MAGIC;
- header.asyncthr = RDC_ASYNCTHR;
- mutex_enter(&krdc->bmapmutex);
- if (rdc_write_header(krdc, &header) < 0) {
- mutex_exit(&krdc->bmapmutex);
- cmn_err(CE_WARN,
- "!rdc_resume_bitmap: Write header %s failed",
- bitmapname);
- goto fail;
- }
- mutex_exit(&krdc->bmapmutex);
- }
-
- if (rdc_resume_state(krdc, &header) == 0)
- return (0);
-
- rdc_close_bitmap(krdc);
-
-fail:
- (void) RDC_FILL_BITMAP(krdc, FALSE);
- rdc_clr_flags(urdc, RDC_QUEUING);
- if (krdc->bitmap_ref)
- bzero(krdc->bitmap_ref, krdc->bitmap_size * BITS_IN_BYTE *
- rdc_refcntsize(krdc));
-
-allocfail:
- mutex_enter(&krdc->bmapmutex);
- rdc_set_flags_log(urdc, RDC_BMP_FAILED, "resume bitmap failed");
- mutex_exit(&krdc->bmapmutex);
-
- return (-1);
-}
-
-void
-rdc_std_zero_bitref(rdc_k_info_t *krdc)
-{
- nsc_size_t vol_size;
- int sts;
- size_t newrefcntsize;
-
- if (krdc->bitmap_ref) {
- mutex_enter(&krdc->bmapmutex);
- bzero(krdc->bitmap_ref, krdc->bitmap_size * BITS_IN_BYTE *
- BMAP_REF_PREF_SIZE);
- if (RDC_IS_DISKQ(krdc->group) && rdc_refcntsize(krdc) !=
- BMAP_REF_PREF_SIZE) {
- /* see if we can upgrade the size of the ref counters */
- sts = _rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL);
- if (!RDC_SUCCESS(sts)) {
- goto nochange;
- }
- sts = nsc_partsize(krdc->bitmapfd, &vol_size);
-
- newrefcntsize = rdc_ref_size_possible(krdc->bitmap_size,
- vol_size);
- if (newrefcntsize > rdc_refcntsize(krdc)) {
- rdc_set_refcnt_ops(krdc, newrefcntsize);
-#ifdef DEBUG_REFCNT
- cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
- (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
-#endif
- }
-nochange:
- _rdc_rlse_devs(krdc, RDC_BMP);
- }
- mutex_exit(&krdc->bmapmutex);
- }
-}
-
-int
-rdc_reset_bitmap(rdc_k_info_t *krdc)
-{
- rdc_u_info_t *urdc;
- rdc_header_t header;
- char *bitmapname;
-
- urdc = &rdc_u_info[krdc->index];
- if (rdc_get_vflags(urdc) & RDC_PRIMARY)
- bitmapname = &urdc->primary.bitmap[0];
- else
- bitmapname = &urdc->secondary.bitmap[0];
-
- mutex_enter(&krdc->bmapmutex);
-
- rdc_clr_flags(urdc, RDC_BMP_FAILED);
- if (rdc_read_header(krdc, &header) < 0) {
- cmn_err(CE_WARN,
- "!rdc_reset_bitmap: Read header %s failed", bitmapname);
- goto fail_with_mutex;
- }
-
- rdc_fill_header(urdc, &header);
-
- if (rdc_write_header(krdc, &header) < 0) {
- cmn_err(CE_WARN,
- "!rdc_reset_bitmap: Write header %s failed",
- bitmapname);
- goto fail_with_mutex;
- }
- mutex_exit(&krdc->bmapmutex);
-
- if (krdc->bitmap_write == -1)
- krdc->bitmap_write = 0;
-
- if (krdc->bitmap_write == 0) {
- if (rdc_write_bitmap_fill(krdc) < 0) {
- cmn_err(CE_WARN,
- "!rdc_reset_bitmap: Write bitmap %s failed",
- bitmapname);
- goto fail;
- }
- krdc->bitmap_write = -1;
- } else if (rdc_write_bitmap(krdc) < 0) {
- cmn_err(CE_WARN,
- "!rdc_reset_bitmap: Write bitmap %s failed",
- bitmapname);
- goto fail;
- }
-
- return (0);
-
-fail:
- mutex_enter(&krdc->bmapmutex);
-fail_with_mutex:
- rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reset failed");
- mutex_exit(&krdc->bmapmutex);
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!SNDR: unable to reset bitmap for %s:%s",
- urdc->secondary.intf, urdc->secondary.file);
-#endif
- return (-1);
-}
-
-
-/*
- * General bitmap operations
- */
-
-/*
- * rdc_set_bitmap_many()
- *
- * Used during reverse syncs to a 1-to-many primary to keep the 'many'
- * bitmaps up to date.
- */
-void
-rdc_set_bitmap_many(rdc_k_info_t *krdc, nsc_off_t pos, nsc_size_t len)
-{
- uint_t dummy;
-
-#ifdef DEBUG
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- if (!(rdc_get_vflags(urdc) & RDC_PRIMARY)) {
- cmn_err(CE_PANIC, "rdc_set_bitmap_many: not primary, urdc %p",
- (void *) urdc);
- }
-#endif
-
- if (IS_MANY(krdc)) {
- rdc_k_info_t *krd;
- rdc_u_info_t *urd;
-
- rdc_many_enter(krdc);
-
- for (krd = krdc->many_next; krd != krdc; krd = krd->many_next) {
- urd = &rdc_u_info[krd->index];
- if (!IS_ENABLED(urd))
- continue;
- ASSERT(urd->flags & RDC_PRIMARY);
- (void) RDC_SET_BITMAP(krd, pos, len, &dummy);
- }
-
- rdc_many_exit(krdc);
- }
-}
-
-
-static int
-_rdc_net_bmap(const struct bmap6 *b6, net_bdata6 *bd6)
-{
- rdc_k_info_t *krdc = &rdc_k_info[b6->cd];
- struct timeval t;
- int e, ret;
- uint64_t left;
- uint64_t bmap_blksize;
-
- bmap_blksize = krdc->rpc_version < RDC_VERSION7 ?
- BMAP_BLKSIZE : BMAP_BLKSIZEV7;
-
- t.tv_sec = rdc_rpc_tmout;
- t.tv_usec = 0;
-
- if (bd6->data.data_val == NULL) {
- return (EINVAL);
- }
-
- left = b6->size;
- bd6->endoblk = 0;
- while (left) {
- if (left >= bmap_blksize)
- bd6->size = (int)bmap_blksize;
- else
- bd6->size = (int)left;
-
- bd6->data.data_len = bd6->size;
-
- if ((uint64_t)bd6->size > left) {
- left = 0;
- } else {
- left -= bd6->size;
- }
- /*
- * mark the last block sent.
- */
- if (left == 0) {
- bd6->endoblk = 1;
- }
- ASSERT(krdc->rpc_version);
- if (krdc->rpc_version <= RDC_VERSION5) {
- struct net_bdata bd;
- bd.cd = bd6->cd;
- bd.offset = bd6->offset;
- bd.size = bd6->size;
- bd.data.data_len = bd6->data.data_len;
- bd.data.data_val = bd6->data.data_val;
- e = rdc_clnt_call(krdc->lsrv, RDCPROC_BDATA,
- krdc->rpc_version, xdr_net_bdata, (char *)&bd,
- xdr_int, (char *)&ret, &t);
- } else {
- e = rdc_clnt_call(krdc->lsrv, RDCPROC_BDATA6,
- krdc->rpc_version, xdr_net_bdata6, (char *)bd6,
- xdr_int, (char *)&ret, &t);
- }
- if (e || ret) {
- if (e)
- ret = e;
- return (ret);
- }
- bd6->offset += bmap_blksize;
- bd6->data.data_val += bmap_blksize;
- }
- return (0);
-}
-
-
-/*
- * Standard bitmap operations (combined kmem/disk bitmaps).
- */
-
-/*
- * rdc_std_set_bitmask(pos, len, &bitmask)
- * set a bitmask for this range. used to clear the correct
- * bits after flushing
- */
-static void
-rdc_std_set_bitmask(const nsc_off_t fba_pos, const nsc_size_t fba_len,
- uint_t *bitmask)
-{
- int first, st, en;
- if (bitmask)
- *bitmask = 0;
- else
- return;
-
- first = st = FBA_TO_LOG_NUM(fba_pos);
- en = FBA_TO_LOG_NUM(fba_pos + fba_len - 1);
- while (st <= en) {
- BMAP_BIT_SET((uchar_t *)bitmask, st - first);
- st++;
- }
-
-}
-/*
- * rdc_std_set_bitmap(krdc, fba_pos, fba_len, &bitmask)
- *
- * Mark modified segments in the dual copy file bitmap
- * to provide fast recovery
- * Note that bitmask allows for 32 segments, which at 32k per segment equals
- * 1 megabyte. If we ever allow more than this to be transferred in one
- * operation, or decrease the segment size, then this code will have to be
- * changed accordingly.
- */
-
-static int
-rdc_std_set_bitmap(rdc_k_info_t *krdc, const nsc_off_t fba_pos,
- const nsc_size_t fba_len, uint_t *bitmask)
-{
- int first, st, en;
- int fbaset = 0;
- nsc_off_t fba = 0;
- int printerr = 10;
- int tries = RDC_FUTILE_ATTEMPTS;
- int queuing = RDC_QUEUING;
- rdc_u_info_t *urdc;
-
- if (bitmask)
- *bitmask = 0;
- else
- return (-1);
-
- urdc = &rdc_u_info[krdc->index];
- if (rdc_get_vflags(urdc) & RDC_BMP_FAILED)
- return (-1);
-
- if (krdc->bitmap_write == 0) {
- if (rdc_write_bitmap_fill(krdc) < 0)
- return (-1);
- krdc->bitmap_write = -1;
- }
- first = st = FBA_TO_LOG_NUM(fba_pos);
- en = FBA_TO_LOG_NUM(fba_pos + fba_len - 1);
- ASSERT(st <= en);
- while (st <= en) {
- int use_ref;
-again:
- mutex_enter(&krdc->bmapmutex);
-
- if (krdc->dcio_bitmap == NULL) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!rdc_std_set_bitmap: "
- "recovery bitmaps not allocated");
-#endif
- mutex_exit(&krdc->bmapmutex);
- return (-1);
- }
-
- use_ref = IS_PRIMARY(urdc) && IS_ASYNC(urdc) &&
- ((rdc_get_vflags(urdc) & RDC_QUEUING) ||
- !(rdc_get_vflags(urdc) & RDC_LOGGING));
-
-
- if (!BMAP_BIT_ISSET(krdc->dcio_bitmap, st)) {
- BMAP_BIT_SET(krdc->dcio_bitmap, st);
- if (use_ref) {
- ASSERT(BMAP_REF_ISSET(krdc, st) ==
- 0);
- BMAP_REF_FORCE(krdc, st, 1);
- }
- BMAP_BIT_SET((uchar_t *)bitmask, st - first);
- urdc->bits_set++;
- if ((!fbaset) || fba != BIT_TO_FBA(st)) {
- if (fbaset && krdc->bitmap_write > 0) {
- mutex_exit(&krdc->bmapmutex);
- if (rdc_write_bitmap_fba(krdc, fba) < 0)
- return (-1);
- mutex_enter(&krdc->bmapmutex);
- }
- fba = BIT_TO_FBA(st);
- fbaset = 1;
- }
- } else {
- /*
- * Just bump reference count
- * For logging or syncing we do not care what the reference
- * is as it will be forced back on the state transition.
- */
- if (use_ref) {
- if (BMAP_REF_ISSET(krdc, st) ==
- BMAP_REF_MAXVAL(krdc)) {
- /*
- * Rollover of reference count.
- */
-
- if (!(rdc_get_vflags(urdc) &
- RDC_VOL_FAILED)) {
- /*
- * Impose throttle to help dump
- * queue
- */
- mutex_exit(&krdc->bmapmutex);
- delay(4);
- rdc_bitmap_delay++;
- if (printerr--) {
- cmn_err(CE_WARN, "!SNDR: bitmap reference count maxed out for %s:%s",
- urdc->secondary.intf, urdc->secondary.file);
-
- }
-
- if ((tries-- <= 0) &&
- IS_STATE(urdc, queuing)) {
- cmn_err(CE_WARN, "!SNDR: giving up on reference count, logging set"
- " %s:%s", urdc->secondary.intf, urdc->secondary.file);
- rdc_group_enter(krdc);
- rdc_group_log(krdc,
- RDC_NOFLUSH |
- RDC_NOREMOTE|
- RDC_FORCE_GROUP,
- "ref count retry limit exceeded");
- rdc_group_exit(krdc);
- }
- goto again;
- }
- } else {
- BMAP_REF_SET(krdc, st);
- }
- }
- }
- mutex_exit(&krdc->bmapmutex);
- st++;
- }
- if (fbaset && krdc->bitmap_write > 0) {
- if (rdc_write_bitmap_fba(krdc, fba) < 0)
- return (-1);
- }
- return (0);
-}
-
-static void
-rdc_std_clr_bitmap(rdc_k_info_t *krdc, const nsc_off_t fba_pos,
- const nsc_size_t fba_len, const uint_t bitmask, const int force)
-{
- int first, st, en;
- nsc_off_t fba = 0;
- int fbaset = 0;
- uint_t bm = bitmask;
- uchar_t *ptr = (uchar_t *)&bm;
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
-
- if (rdc_get_vflags(urdc) & RDC_BMP_FAILED)
- return;
-
- first = st = FBA_TO_LOG_NUM(fba_pos);
- en = FBA_TO_LOG_NUM(fba_pos + fba_len - 1);
- ASSERT(st <= en);
- while (st <= en) {
- mutex_enter(&krdc->bmapmutex);
-
- if (krdc->dcio_bitmap == NULL) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!rdc_std_clr_bitmap: "
- "recovery bitmaps not allocated");
-#endif
- mutex_exit(&krdc->bmapmutex);
- return;
- }
-
- if (((bitmask == 0xffffffff) ||
- (BMAP_BIT_ISSET(ptr, st - first))) &&
- BMAP_BIT_ISSET(krdc->dcio_bitmap, st)) {
-
- int use_ref = IS_PRIMARY(urdc) && IS_ASYNC(urdc) &&
- ((rdc_get_vflags(urdc) & RDC_QUEUING) ||
- !(rdc_get_vflags(urdc) & RDC_LOGGING));
-
- if (force || (use_ref == 0)) {
- if (krdc->bitmap_ref)
- BMAP_REF_FORCE(krdc, st, 0);
- } else if (use_ref) {
- if (BMAP_REF_ISSET(krdc, st) != 0)
- BMAP_REF_CLR(krdc, st);
-
- }
-
- if ((use_ref == 0) || (use_ref &&
- !BMAP_REF_ISSET(krdc, st))) {
- BMAP_BIT_CLR(krdc->dcio_bitmap, st);
-
- urdc->bits_set--;
- if (!fbaset || fba != BIT_TO_FBA(st)) {
- if (fbaset &&
- krdc->bitmap_write > 0) {
- mutex_exit(&krdc->bmapmutex);
- if (rdc_write_bitmap_fba(krdc,
- fba) < 0)
- return;
- mutex_enter(&krdc->bmapmutex);
- }
- fba = BIT_TO_FBA(st);
- fbaset = 1;
- }
- }
- }
- mutex_exit(&krdc->bmapmutex);
- st++;
- }
- if (fbaset && krdc->bitmap_write > 0) {
- if (rdc_write_bitmap_fba(krdc, fba) < 0)
- return;
- }
-}
-
-/*
- * make sure that this bit is set. if it isn't, set it
- * used when transitioning from async to sync while going
- * from rep to log. an overlapping sync write may unconditionally
- * clear the bit that has not been replicated. when the queue
- * is being dumped or this is called just to make sure pending stuff
- * is in the bitmap
- */
-void
-rdc_std_check_bit(rdc_k_info_t *krdc, nsc_off_t pos, nsc_size_t len)
-{
- int st;
- int en;
- nsc_off_t fba;
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- st = FBA_TO_LOG_NUM(pos);
- en = FBA_TO_LOG_NUM(pos + len - 1);
-
- if (rdc_get_vflags(urdc) & RDC_BMP_FAILED)
- return;
-
- while (st <= en) {
- mutex_enter(&krdc->bmapmutex);
-
- if (krdc->dcio_bitmap == NULL) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!rdc_std_check_bit: "
- "recovery bitmaps not allocated");
-#endif
- mutex_exit(&krdc->bmapmutex);
- return;
- }
-
- if (!BMAP_BIT_ISSET(krdc->dcio_bitmap, st)) {
- BMAP_BIT_SET(krdc->dcio_bitmap, st);
- if (krdc->bitmap_write > 0) {
- fba = BIT_TO_FBA(st);
- mutex_exit(&krdc->bmapmutex);
- (void) rdc_write_bitmap_fba(krdc, fba);
- mutex_enter(&krdc->bmapmutex);
- }
- urdc->bits_set++;
-
- }
- mutex_exit(&krdc->bmapmutex);
- st++;
- }
-
-}
-
-/*
- * rdc_std_count_dirty(krdc):
- *
- * Determine the number of segments that need to be flushed, This should
- * agree with the number of segments logged, but since we don't lock when
- * we increment, we force these values to agree
- */
-static int
-rdc_std_count_dirty(rdc_k_info_t *krdc)
-{
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- int i, count, size;
-
- if (krdc->dcio_bitmap == NULL) {
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!rdc_std_count_dirty: no bitmap configured for %s",
- urdc->primary.file);
-#endif
- return (0);
- }
-
- count = 0;
- ASSERT(urdc->volume_size != 0);
- size = FBA_TO_LOG_LEN(urdc->volume_size);
- for (i = 0; i < size; i++)
- if (BMAP_BIT_ISSET(krdc->dcio_bitmap, i))
- count++;
-
- if (count > size)
- count = size;
-
- return (count);
-}
-
-
-static int
-rdc_std_bit_isset(rdc_k_info_t *krdc, const int bit)
-{
- return (BMAP_BIT_ISSET(krdc->dcio_bitmap, bit));
-}
-
-
-/*
- * rdc_std_fill_bitmap(krdc, write)
- *
- * Called to force bitmaps to a fully dirty state
- */
-static int
-rdc_std_fill_bitmap(rdc_k_info_t *krdc, const int write)
-{
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- int i, size;
-
- if (krdc->dcio_bitmap == NULL) {
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!rdc_std_fill_bitmap: no bitmap configured for %s",
- urdc->primary.file);
-#endif
- return (-1);
- }
-
- ASSERT(urdc->volume_size != 0);
- size = FBA_TO_LOG_LEN(urdc->volume_size);
- for (i = 0; i < size; i++)
- BMAP_BIT_SET(krdc->dcio_bitmap, i);
-
- urdc->bits_set = size;
-
- if (write)
- return (rdc_write_bitmap(krdc));
-
- return (0);
-}
-
-
-/*
- * rdc_std_zero_bitmap(krdc)
- *
- * Called on the secondary after a sync has completed to force bitmaps
- * to a fully clean state
- */
-static void
-rdc_std_zero_bitmap(rdc_k_info_t *krdc)
-{
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- int i, size;
-
- if (krdc->dcio_bitmap == NULL) {
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!rdc_std_zero_bitmap: no bitmap configured for %s",
- urdc->primary.file);
-#endif
- return;
- }
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!Clearing bitmap for %s", urdc->secondary.file);
-#endif
-
- ASSERT(urdc->volume_size != 0);
- size = FBA_TO_LOG_LEN(urdc->volume_size);
- for (i = 0; i < size; i++)
- BMAP_BIT_CLR(krdc->dcio_bitmap, i);
- if (krdc->bitmap_write > 0)
- (void) rdc_write_bitmap(krdc);
-
- urdc->bits_set = 0;
-}
-
-
-/*
- * rdc_std_net_bmap()
- *
- * WARNING acts as both client and server
- */
-static int
-rdc_std_net_bmap(const struct bmap6 *b)
-{
- rdc_k_info_t *krdc = &rdc_k_info[b->cd];
- struct net_bdata6 bd;
-
- bd.data.data_val = (char *)krdc->dcio_bitmap;
- bd.cd = b->dual;
- bd.offset = 0;
-
- return (_rdc_net_bmap(b, &bd));
-}
-
-
-/*
- * rdc_std_net_bdata
- */
-static int
-rdc_std_net_bdata(const struct net_bdata6 *bd)
-{
- rdc_k_info_t *krdc = &rdc_k_info[bd->cd];
-
- rdc_lor((uchar_t *)bd->data.data_val,
- (uchar_t *)(((char *)krdc->dcio_bitmap) + bd->offset), bd->size);
-
- return (0);
-}
-
-
-static struct rdc_bitmap_ops rdc_std_bitmap_ops = {
- rdc_std_set_bitmap,
- rdc_std_clr_bitmap,
- rdc_std_count_dirty,
- rdc_std_bit_isset,
- rdc_std_fill_bitmap,
- rdc_std_zero_bitmap,
- rdc_std_net_bmap,
- rdc_std_net_bdata,
- rdc_std_zero_bitref,
- rdc_std_set_bitmask,
- rdc_std_check_bit
-};
-
-
-void
-rdc_bitmap_init()
-{
- rdc_bitmap_ops = &rdc_std_bitmap_ops;
- rdc_wrflag = NSC_WRITE;
-}
-
-static void
-rdc_bmap_ref_byte_set(rdc_k_info_t *krdc, int ind)
-{
- unsigned char *bmap = (unsigned char *)krdc->bitmap_ref;
-
- ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned char));
- bmap[ind]++;
-}
-
-static void
-rdc_bmap_ref_byte_clr(rdc_k_info_t *krdc, int ind)
-{
- unsigned char *bmap = (unsigned char *)krdc->bitmap_ref;
-
- ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned char));
- bmap[ind]--;
-}
-
-static unsigned int
-rdc_bmap_ref_byte_isset(rdc_k_info_t *krdc, int ind)
-{
- unsigned char *bmap = (unsigned char *)krdc->bitmap_ref;
-
- ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned char));
- return ((unsigned int)(bmap[ind]));
-}
-
-static void
-rdc_bmap_ref_byte_force(rdc_k_info_t *krdc, int ind, unsigned int val)
-{
- unsigned char *bmap = (unsigned char *)krdc->bitmap_ref;
-
- ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned char));
- bmap[ind] = (unsigned char) val;
-}
-
-/* ARGSUSED */
-static unsigned int
-rdc_bmap_ref_byte_maxval(rdc_k_info_t *krdc)
-{
- ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned char));
- return ((unsigned int)(UINT8_MAX));
-}
-
-struct bm_ref_ops rdc_ref_byte_ops = {
- rdc_bmap_ref_byte_set,
- rdc_bmap_ref_byte_clr,
- rdc_bmap_ref_byte_isset,
- rdc_bmap_ref_byte_force,
- rdc_bmap_ref_byte_maxval,
- sizeof (unsigned char)
-};
-
-static void
-rdc_bmap_ref_int_set(rdc_k_info_t *krdc, int ind)
-{
- unsigned int *bmap = (unsigned int *)krdc->bitmap_ref;
-
- ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned int));
- bmap[ind]++;
-}
-
-static void
-rdc_bmap_ref_int_clr(rdc_k_info_t *krdc, int ind)
-{
- unsigned int *bmap = (unsigned int *)krdc->bitmap_ref;
-
- ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned int));
- bmap[ind]--;
-}
-
-static unsigned int
-rdc_bmap_ref_int_isset(rdc_k_info_t *krdc, int ind)
-{
- unsigned int *bmap = (unsigned int *)krdc->bitmap_ref;
-
- ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned int));
- return ((bmap[ind]));
-}
-
-static void
-rdc_bmap_ref_int_force(rdc_k_info_t *krdc, int ind, unsigned int val)
-{
- unsigned int *bmap = (unsigned int *)krdc->bitmap_ref;
-
- ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned int));
- bmap[ind] = val;
-}
-
-/* ARGSUSED */
-static unsigned int
-rdc_bmap_ref_int_maxval(rdc_k_info_t *krdc)
-{
- ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned int));
- return ((unsigned int)(UINT_MAX));
-}
-
-struct bm_ref_ops rdc_ref_int_ops = {
- rdc_bmap_ref_int_set,
- rdc_bmap_ref_int_clr,
- rdc_bmap_ref_int_isset,
- rdc_bmap_ref_int_force,
- rdc_bmap_ref_int_maxval,
- sizeof (unsigned int)
-};
diff --git a/usr/src/uts/common/avs/ns/rdc/rdc_bitmap.h b/usr/src/uts/common/avs/ns/rdc/rdc_bitmap.h
deleted file mode 100644
index 72ee2b791a..0000000000
--- a/usr/src/uts/common/avs/ns/rdc/rdc_bitmap.h
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _RDC_BITMAP_H
-#define _RDC_BITMAP_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef _KERNEL
-
-extern int rdc_bitmap_mode; /* property from rdc.conf */
-
-/*
- * Possible values of rdc_bitmap_mode - integer flag.
- */
-#define RDC_BMP_AUTO 0x0 /* auto detect bitmap mode */
-#define RDC_BMP_ALWAYS 0x1 /* always write the bitmap */
-#define RDC_BMP_NEVER 0x2 /* never write the bitmap */
-
-#endif /* _KERNEL */
-
-/*
- * Public bitmap interface
- * The bitmaps are maintained on 32 Kbyte segments
- */
-
-#define LOG_SHFT 15
-#define IND_BYTE(ind) ((ind) >> 3)
-#define IND_BIT(ind) (1 << ((ind) & 0x7))
-
-#define FBA_LOG_SHFT (LOG_SHFT - FBA_SHFT)
-#define FBA_TO_LOG_NUM(x) ((x) >> FBA_LOG_SHFT)
-#define LOG_TO_FBA_NUM(x) ((x) << FBA_LOG_SHFT)
-#define FBA_TO_LOG_LEN(x) (FBA_TO_LOG_NUM((x)-1) + 1)
-
-#define BMAP_LOG_BYTES(fbas) (IND_BYTE(FBA_TO_LOG_NUM((fbas)-1))+1)
-
-#define BITS_IN_BYTE 8
-
-/*
- * Private macros for bitmap manipulation
- */
-
-#define BMAP_BIT_SET(bmap, ind) ((bmap)[IND_BYTE(ind)] |= IND_BIT(ind))
-#define BMAP_BIT_CLR(bmap, ind) ((bmap)[IND_BYTE(ind)] &= ~IND_BIT(ind))
-#define BMAP_BIT_ISSET(bmap, ind) \
- ((bmap)[IND_BYTE(ind)] & IND_BIT(ind))
-
-#define BIT_TO_FBA(b) (FBA_NUM(b) >> 3)
-
-#define BMAP_REF_SET(krdc, ind) (((krdc)->bm_refs->bmap_ref_set)(krdc, ind))
-#define BMAP_REF_CLR(krdc, ind) (((krdc)->bm_refs->bmap_ref_clr)(krdc, ind))
-#define BMAP_REF_ISSET(krdc, ind) (((krdc)->bm_refs->bmap_ref_isset)(krdc, ind))
-#define BMAP_REF_FORCE(krdc, ind, val) \
- (((krdc)->bm_refs->bmap_ref_force)(krdc, ind, val))
-#define BMAP_REF_MAXVAL(krdc) (((krdc)->bm_refs->bmap_ref_maxval)(krdc))
-#define BMAP_REF_SIZE(krdc) ((krdc)->bm_refs->bmap_ref_size)
-#define BMAP_REF_PREF_SIZE (sizeof (unsigned int))
-
-#ifndef _KERNEL
-
-struct bm_ref_ops {
- void (*bmap_ref_set)(void *, int);
- void (*bmap_ref_clr)(void *, int);
- unsigned int (*bmap_ref_isset)(void *, int);
- void (*bmap_ref_force)(void *, int, unsigned int);
- unsigned int (*bmap_ref_maxval)(void *);
- size_t bmap_ref_size;
-};
-
-#else
-
-struct bm_ref_ops {
- void (*bmap_ref_set)(rdc_k_info_t *, int);
- void (*bmap_ref_clr)(rdc_k_info_t *, int);
- unsigned int (*bmap_ref_isset)(rdc_k_info_t *, int);
- void (*bmap_ref_force)(rdc_k_info_t *, int, unsigned int);
- unsigned int (*bmap_ref_maxval)(rdc_k_info_t *);
- size_t bmap_ref_size;
-};
-
-
-/* convert fba to block number */
-#define _BNUM(x) (FBA_TO_LOG_NUM(x))
-
-/* force reference clear during sync */
-#define RDC_BIT_BUMP 0x0
-#define RDC_BIT_FORCE 0x1
-#define RDC_BIT_FLUSHER 0x2
-
-/* check for overlap, taking account of blocking factor */
-#define RDC_OVERLAP(p1, l1, p2, l2) \
- ((_BNUM(((p1) + (l1) - 1)) >= _BNUM((p2))) && \
- (_BNUM((p1)) <= _BNUM(((p2) + (l2) - 1))))
-
-struct rdc_bitmap_ops {
- int (*set_bitmap)(rdc_k_info_t *, const nsc_off_t, const nsc_size_t,
- uint_t *);
- void (*clr_bitmap)(rdc_k_info_t *, const nsc_off_t, const nsc_size_t,
- const uint_t, const int);
- int (*count_dirty)(rdc_k_info_t *);
- int (*bit_isset)(rdc_k_info_t *, const int);
- int (*fill_bitmap)(rdc_k_info_t *, const int);
- void (*zero_bitmap)(rdc_k_info_t *);
- int (*net_bmap)(const struct bmap6 *);
- int (*net_b_data)(const struct net_bdata6 *);
- void (*zero_bitref)(rdc_k_info_t *);
- void (*set_bitmask)(const nsc_off_t, const nsc_size_t, uint_t *);
- void (*check_bit)(rdc_k_info_t *, nsc_off_t, nsc_size_t);
-};
-
-extern struct rdc_bitmap_ops *rdc_bitmap_ops;
-
-#define RDC_SET_BITMAP(krdc, pos, len, bitmaskp) \
- (*rdc_bitmap_ops->set_bitmap)(krdc, pos, len, bitmaskp)
-#define RDC_CLR_BITMAP(krdc, pos, len, bitmask, flag) \
- (*rdc_bitmap_ops->clr_bitmap)(krdc, pos, len, bitmask, flag)
-#define RDC_COUNT_BITMAP(krdc) \
- (*rdc_bitmap_ops->count_dirty)(krdc)
-#define RDC_BIT_ISSET(krdc, bit) \
- (*rdc_bitmap_ops->bit_isset)(krdc, bit)
-#define RDC_FILL_BITMAP(krdc, write) \
- (*rdc_bitmap_ops->fill_bitmap)(krdc, write)
-#define RDC_ZERO_BITMAP(krdc) \
- (*rdc_bitmap_ops->zero_bitmap)(krdc)
-#define RDC_SEND_BITMAP(argp) \
- (*rdc_bitmap_ops->net_bmap)(argp)
-#define RDC_OR_BITMAP(argp) \
- (*rdc_bitmap_ops->net_b_data)(argp)
-#define RDC_ZERO_BITREF(krdc) \
- (*rdc_bitmap_ops->zero_bitref)(krdc)
-#define RDC_SET_BITMASK(off, len, maskp) \
- (*rdc_bitmap_ops->set_bitmask)(off, len, maskp)
-#define RDC_CHECK_BIT(krdc, pos, len) \
- (*rdc_bitmap_ops->check_bit)(krdc, pos, len)
-
-/*
- * Functions
- */
-
-extern void rdc_bitmap_init(void);
-extern int rdc_move_bitmap(rdc_k_info_t *, char *);
-extern int rdc_enable_bitmap(rdc_k_info_t *, int);
-extern int rdc_resume_bitmap(rdc_k_info_t *);
-extern int rdc_reset_bitmap(rdc_k_info_t *);
-extern void rdc_free_bitmap(rdc_k_info_t *, int);
-extern void rdc_close_bitmap(rdc_k_info_t *);
-extern int rdc_write_bitmap(rdc_k_info_t *);
-extern int rdc_write_bitmap_fill(rdc_k_info_t *);
-extern void rdc_set_bitmap_many(rdc_k_info_t *, nsc_off_t, nsc_size_t);
-extern void rdc_merge_bitmaps(rdc_k_info_t *, rdc_k_info_t *);
-
-extern int rdc_read_state(rdc_k_info_t *, int *, int *);
-extern int rdc_clear_state(rdc_k_info_t *);
-extern void rdc_write_state(rdc_u_info_t *);
-extern int rdc_ns_io(nsc_fd_t *, int, nsc_off_t, uchar_t *, nsc_size_t);
-extern int rdc_read_refcount(rdc_k_info_t *);
-extern int rdc_write_refcount(rdc_k_info_t *);
-extern size_t rdc_refcntsize(rdc_k_info_t *);
-
-#endif /* _KERNEL */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _RDC_BITMAP_H */
diff --git a/usr/src/uts/common/avs/ns/rdc/rdc_clnt.c b/usr/src/uts/common/avs/ns/rdc/rdc_clnt.c
deleted file mode 100644
index 971cb09ec0..0000000000
--- a/usr/src/uts/common/avs/ns/rdc/rdc_clnt.c
+++ /dev/null
@@ -1,3381 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/* Network data replicator Client side */
-
-
-#include <sys/types.h>
-#include <sys/debug.h>
-#include <sys/ksynch.h>
-#include <sys/cmn_err.h>
-#include <sys/kmem.h>
-#include <sys/cred.h>
-#include <sys/byteorder.h>
-#include <sys/errno.h>
-
-#ifdef _SunOS_2_6
-/*
- * on 2.6 both dki_lock.h and rpc/types.h define bool_t so we
- * define enum_t here as it is all we need from rpc/types.h
- * anyway and make it look like we included it. Yuck.
- */
-#define _RPC_TYPES_H
-typedef int enum_t;
-#else
-#ifndef DS_DDICT
-#include <rpc/types.h>
-#endif
-#endif /* _SunOS_2_6 */
-
-#ifndef DS_DDICT
-#include <rpc/auth.h>
-#include <rpc/svc.h>
-#include <rpc/xdr.h>
-#endif
-#include <sys/ddi.h>
-
-#include <sys/nsc_thread.h>
-#ifdef DS_DDICT
-#include <sys/nsctl/contract.h>
-#endif
-#include <sys/nsctl/nsctl.h>
-
-#include <sys/sdt.h> /* dtrace is S10 or later */
-
-#include "rdc_io.h"
-#include "rdc_clnt.h"
-#include "rdc_bitmap.h"
-#include "rdc_diskq.h"
-
-
-kmutex_t rdc_clnt_lock;
-
-#ifdef DEBUG
-int noflush = 0;
-#endif
-
-int rdc_rpc_tmout = RDC_CLNT_TMOUT;
-static void rdc_clnt_free(struct chtab *, CLIENT *);
-static void _rdc_remote_flush(rdc_aio_t *);
-
-void rdc_flush_memq(int index);
-void rdc_flush_diskq(int index);
-int rdc_drain_net_queue(int index);
-void rdc_flusher_thread(int index);
-int rdc_diskq_enqueue(rdc_k_info_t *krdc, rdc_aio_t *);
-void rdc_init_diskq_header(rdc_group_t *grp, dqheader *hd);
-void rdc_dump_iohdrs(disk_queue *dq);
-rdc_aio_t *rdc_dequeue(rdc_k_info_t *krdc, int *rc);
-void rdc_clr_iohdr(rdc_k_info_t *krdc, nsc_off_t qpos);
-void rdc_close_diskq(rdc_group_t *krdc);
-
-int rdc_writer(int index);
-
-static struct chtab *rdc_chtable = NULL;
-static int rdc_clnt_toomany;
-#ifdef DEBUG
-static int rdc_ooreply;
-#endif
-
-extern void rdc_fail_diskq(rdc_k_info_t *krdc, int wait, int flag);
-extern int _rdc_rsrv_diskq(rdc_group_t *group);
-extern void _rdc_rlse_diskq(rdc_group_t *group);
-
-static enum clnt_stat
-cl_call_sig(struct __client *rh, rpcproc_t proc,
- xdrproc_t xargs, caddr_t argsp, xdrproc_t xres,
- caddr_t resp, struct timeval secs)
-{
- enum clnt_stat stat;
- k_sigset_t smask;
- sigintr(&smask, 0);
- rh->cl_nosignal = TRUE;
- stat = ((*(rh)->cl_ops->cl_call)\
- (rh, proc, xargs, argsp, xres, resp, secs));
- rh->cl_nosignal = FALSE;
- sigunintr(&smask);
- return (stat);
-}
-
-int
-rdc_net_getsize(int index, uint64_t *sizeptr)
-{
- struct timeval t;
- int err, size;
- rdc_k_info_t *krdc = &rdc_k_info[index];
- int remote_index = krdc->remote_index;
-
- *sizeptr = 0;
- if (krdc->remote_index < 0)
- return (EINVAL);
-
- t.tv_sec = rdc_rpc_tmout;
- t.tv_usec = 0;
-
-#ifdef DEBUG
- if (krdc->intf == NULL)
- cmn_err(CE_WARN,
- "!rdc_net_getsize: null intf for index %d", index);
-#endif
- if (krdc->rpc_version <= RDC_VERSION5) {
- err = rdc_clnt_call(krdc->lsrv, RDCPROC_GETSIZE,
- krdc->rpc_version, xdr_int, (char *)&remote_index,
- xdr_int, (char *)&size, &t);
- if (err == 0)
- *sizeptr = size;
- } else {
- err = rdc_clnt_call(krdc->lsrv, RDCPROC_GETSIZE6,
- krdc->rpc_version, xdr_int, (char *)&remote_index,
- xdr_u_longlong_t, (char *)sizeptr, &t);
- }
- return (err);
-}
-
-
-int
-rdc_net_state(int index, int options)
-{
- struct timeval t;
- int err;
- int remote_index = -1;
- rdc_u_info_t *urdc = &rdc_u_info[index];
- rdc_k_info_t *krdc = &rdc_k_info[index];
- struct set_state s;
- struct set_state4 s4;
- char neta[32], rneta[32];
- unsigned short *sp;
-
- t.tv_sec = rdc_rpc_tmout;
- t.tv_usec = 0;
-
- if (krdc->rpc_version < RDC_VERSION7) {
- s4.netaddrlen = urdc->primary.addr.len;
- s4.rnetaddrlen = urdc->secondary.addr.len;
- bcopy(urdc->primary.addr.buf, s4.netaddr, s4.netaddrlen);
- bcopy(urdc->secondary.addr.buf, s4.rnetaddr, s4.rnetaddrlen);
- (void) strncpy(s4.pfile, urdc->primary.file, RDC_MAXNAMLEN);
- (void) strncpy(s4.sfile, urdc->secondary.file, RDC_MAXNAMLEN);
- s4.flag = options;
-
- err = rdc_clnt_call(krdc->lsrv, RDCPROC_STATE,
- krdc->rpc_version, xdr_set_state4, (char *)&s4, xdr_int,
- (char *)&remote_index, &t);
- } else {
- s.netaddrlen = urdc->primary.addr.len;
- s.rnetaddrlen = urdc->secondary.addr.len;
- s.netaddr.buf = neta;
- s.rnetaddr.buf = rneta;
- bcopy(urdc->primary.addr.buf, s.netaddr.buf, s.netaddrlen);
- bcopy(urdc->secondary.addr.buf, s.rnetaddr.buf, s.rnetaddrlen);
- s.netaddr.len = urdc->primary.addr.len;
- s.rnetaddr.len = urdc->secondary.addr.len;
- s.netaddr.maxlen = urdc->primary.addr.len;
- s.rnetaddr.maxlen = urdc->secondary.addr.len;
- sp = (unsigned short *)s.netaddr.buf;
- *sp = htons(*sp);
- sp = (unsigned short *)s.rnetaddr.buf;
- *sp = htons(*sp);
- s.pfile = urdc->primary.file;
- s.sfile = urdc->secondary.file;
- s.flag = options;
-
- err = rdc_clnt_call(krdc->lsrv, RDCPROC_STATE,
- krdc->rpc_version, xdr_set_state, (char *)&s, xdr_int,
- (char *)&remote_index, &t);
- }
-
- if (err)
- return (-1);
- else
- return (remote_index);
-}
-
-
-/*
- * rdc_net_getbmap
- * gets the bitmaps from remote side and or's them with remote bitmap
- */
-int
-rdc_net_getbmap(int index, int size)
-{
- struct timeval t;
- int err;
- struct bmap b;
- struct bmap6 b6;
- rdc_k_info_t *krdc;
-
- krdc = &rdc_k_info[index];
-
- if (krdc->remote_index < 0)
- return (EINVAL);
-
- t.tv_sec = rdc_rpc_tmout;
- t.tv_usec = 0;
-#ifdef DEBUG
- if (krdc->intf == NULL)
- cmn_err(CE_WARN,
- "!rdc_net_getbmap: null intf for index %d", index);
-#endif
-
- if (krdc->rpc_version <= RDC_VERSION5) {
- b.cd = krdc->remote_index;
- b.dual = index;
- b.size = size;
- err = rdc_clnt_call(krdc->lsrv, RDCPROC_BMAP,
- krdc->rpc_version, xdr_bmap, (char *)&b, xdr_int,
- (char *)&err, &t);
-
- } else {
- b6.cd = krdc->remote_index;
- b6.dual = index;
- b6.size = size;
- err = rdc_clnt_call(krdc->lsrv, RDCPROC_BMAP6,
- krdc->rpc_version, xdr_bmap6, (char *)&b6, xdr_int,
- (char *)&err, &t);
- }
- return (err);
-}
-
-int sndr_proto = 0;
-
-/*
- * return state corresponding to rdc_host
- */
-int
-rdc_net_getstate(rdc_k_info_t *krdc, int *serial_mode, int *use_mirror,
- int *mirror_down, int network)
-{
- int err;
- struct timeval t;
- int state;
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- struct set_state s;
-#ifdef sparc
- struct set_state4 s4;
-#endif
- char neta[32];
- char rneta[32];
- unsigned short *sp;
- char *setp = (char *)&s;
- xdrproc_t xdr_proc = xdr_set_state;
-
- if (krdc->lsrv && (krdc->intf == NULL || krdc->intf->if_down) &&
- network) /* fail fast */
- return (-1);
-
- s.netaddrlen = urdc->primary.addr.len;
- s.rnetaddrlen = urdc->secondary.addr.len;
- s.pfile = urdc->primary.file;
- s.sfile = urdc->secondary.file;
- s.netaddr.buf = neta;
- s.rnetaddr.buf = rneta;
- bcopy(urdc->primary.addr.buf, s.netaddr.buf, s.netaddrlen);
- bcopy(urdc->secondary.addr.buf, s.rnetaddr.buf, s.rnetaddrlen);
- sp = (unsigned short *) s.netaddr.buf;
- *sp = htons(*sp);
- sp = (unsigned short *) s.rnetaddr.buf;
- *sp = htons(*sp);
- s.netaddr.len = urdc->primary.addr.len;
- s.rnetaddr.len = urdc->secondary.addr.len;
- s.netaddr.maxlen = urdc->primary.addr.maxlen;
- s.rnetaddr.maxlen = urdc->secondary.addr.maxlen;
- s.flag = 0;
-
- t.tv_sec = rdc_rpc_tmout;
- t.tv_usec = 0;
-
- if (sndr_proto)
- krdc->rpc_version = sndr_proto;
- else
- krdc->rpc_version = RDC_VERS_MAX;
-
-again:
- err = rdc_clnt_call(krdc->lsrv, RDCPROC_GETSTATE4, krdc->rpc_version,
- xdr_proc, setp, xdr_int, (char *)&state, &t);
-
- if (err == RPC_PROGVERSMISMATCH && (krdc->rpc_version !=
- RDC_VERS_MIN)) {
- if (krdc->rpc_version-- == RDC_VERSION7) {
- /* set_state struct changed with v7 of protocol */
-#ifdef sparc
- s4.netaddrlen = urdc->primary.addr.len;
- s4.rnetaddrlen = urdc->secondary.addr.len;
- bcopy(urdc->primary.addr.buf, s4.netaddr,
- s4.netaddrlen);
- bcopy(urdc->secondary.addr.buf, s4.rnetaddr,
- s4.rnetaddrlen);
- (void) strncpy(s4.pfile, urdc->primary.file,
- RDC_MAXNAMLEN);
- (void) strncpy(s4.sfile, urdc->secondary.file,
- RDC_MAXNAMLEN);
- s4.flag = 0;
- xdr_proc = xdr_set_state4;
- setp = (char *)&s4;
-#else
- /* x64 can not use protocols < 7 */
- return (-1);
-#endif
- }
- goto again;
- }
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!sndr get_state: Protocol ver %d", krdc->rpc_version);
-#endif
-
- if (err) {
- return (-1);
- }
-
- if (state == -1)
- return (-1);
-
- if (serial_mode)
- *serial_mode = (state >> 2) & 1;
- if (use_mirror)
- *use_mirror = (state >> 1) & 1;
- if (mirror_down)
- *mirror_down = state & 1;
-
- return (0);
-}
-
-
-static struct xdr_discrim rdres_discrim[2] = {
- { (int)RDC_OK, xdr_readok },
- { __dontcare__, NULL_xdrproc_t }
-};
-
-
-/*
- * Reply from remote read (client side)
- */
-static bool_t
-xdr_rdresult(XDR *xdrs, readres *rr)
-{
-
- return (xdr_union(xdrs, (enum_t *)&(rr->rr_status),
- (caddr_t)&(rr->rr_ok), rdres_discrim, xdr_void));
-}
-
-static int
-rdc_rrstatus_decode(int status)
-{
- int ret = 0;
-
- if (status != RDC_OK) {
- switch (status) {
- case RDCERR_NOENT:
- ret = ENOENT;
- break;
- case RDCERR_NOMEM:
- ret = ENOMEM;
- break;
- default:
- ret = EIO;
- break;
- }
- }
-
- return (ret);
-}
-
-
-int
-rdc_net_read(int local_index, int remote_index, nsc_buf_t *handle,
- nsc_off_t fba_pos, nsc_size_t fba_len)
-{
- struct rdcrdresult rr;
- rdc_k_info_t *krdc;
- rdc_u_info_t *urdc;
- struct rread list;
- struct rread6 list6;
- struct timeval t;
- uchar_t *sv_addr;
- nsc_vec_t *vec;
- int rpc_flag;
- nsc_size_t sv_len;
- int err;
- int ret;
- nsc_size_t len;
- nsc_size_t maxfbas;
- int transflag;
-
- if (handle == NULL)
- return (EINVAL);
-
- if (!RDC_HANDLE_LIMITS(handle, fba_pos, fba_len)) {
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!rdc_net_read: handle bounds");
-#endif
- return (EINVAL);
- }
-
- krdc = &rdc_k_info[local_index];
- urdc = &rdc_u_info[local_index];
-
- maxfbas = MAX_RDC_FBAS;
-
- if (krdc->remote_fd && !(rdc_get_vflags(urdc) & RDC_FCAL_FAILED)) {
- nsc_buf_t *remote_h = NULL;
- int reserved = 0;
-
- ret = nsc_reserve(krdc->remote_fd, NSC_MULTI);
- if (RDC_SUCCESS(ret)) {
- reserved = 1;
- ret = nsc_alloc_buf(krdc->remote_fd, fba_pos, fba_len,
- NSC_RDBUF, &remote_h);
- }
- if (RDC_SUCCESS(ret)) {
- ret = nsc_copy(remote_h, handle, fba_pos, fba_pos,
- fba_len);
- if (RDC_SUCCESS(ret)) {
- (void) nsc_free_buf(remote_h);
- nsc_release(krdc->remote_fd);
- return (0);
- }
- }
- rdc_group_enter(krdc);
- rdc_set_flags(urdc, RDC_FCAL_FAILED);
- rdc_group_exit(krdc);
- if (remote_h)
- (void) nsc_free_buf(remote_h);
- if (reserved)
- nsc_release(krdc->remote_fd);
- }
-
- t.tv_sec = rdc_rpc_tmout;
- t.tv_usec = 0;
-
- if (rdc_get_vflags(urdc) & RDC_VOL_FAILED)
- rpc_flag = RDC_RREAD_FAIL;
- else
- rpc_flag = 0;
-
-#ifdef DEBUG
- if (krdc->intf == NULL)
- cmn_err(CE_WARN,
- "!rdc_net_read: null intf for index %d", local_index);
-#endif
- /*
- * switch on proto version.
- */
- len = fba_len; /* length (FBAs) still to xfer */
- rr.rr_bufsize = 0; /* rpc data buffer length (bytes) */
- rr.rr_data = NULL; /* rpc data buffer */
- transflag = rpc_flag | RDC_RREAD_START; /* setup rpc */
- if (krdc->rpc_version <= RDC_VERSION5) {
- ASSERT(fba_pos <= INT32_MAX);
- list.pos = (int)fba_pos; /* fba position of start of chunk */
- list.cd = remote_index; /* remote end cd */
- /* send setup rpc */
- list.flag = transflag;
- ASSERT(len <= INT32_MAX);
- list.len = (int)len; /* total fba length */
- err = rdc_clnt_call(krdc->lsrv, RDCPROC_READ5,
- krdc->rpc_version, xdr_rread, (char *)&list, xdr_int,
- (char *)&ret, &t);
-
- } else {
- list6.pos = fba_pos; /* fba position of start of chunk */
- list6.cd = remote_index; /* remote end cd */
- /* send setup rpc */
- list6.flag = transflag; /* setup rpc */
- ASSERT(len <= INT32_MAX);
- list6.len = (int)len; /* total fba length */
- err = rdc_clnt_call(krdc->lsrv, RDCPROC_READ6,
- krdc->rpc_version, xdr_rread6, (char *)&list6, xdr_int,
- (char *)&ret, &t);
- }
-
- if (err) {
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!rdc_net_read: setup err %d", err);
-#endif
- if (err == RPC_INTR)
- ret = EINTR;
- else
- ret = ENOLINK;
-
- goto remote_rerror;
- }
-
- if (ret == 0) { /* No valid index from r_net_read */
-#ifdef DEBUG
- cmn_err(CE_NOTE,
- "!rdc_net_read: no valid index from r_net_read");
-#endif
- return (ENOBUFS);
- }
- transflag = rpc_flag | RDC_RREAD_DATA;
- if (krdc->rpc_version <= RDC_VERSION5) {
- list.idx = ret; /* save idx to return to server */
- list.flag = transflag;
- /* move onto to data xfer rpcs */
- } else {
- list6.idx = ret; /* save idx to return to server */
- list6.flag = transflag;
- }
-
- /* find starting position in handle */
-
- vec = handle->sb_vec;
-
- fba_pos -= handle->sb_pos;
-
- for (; fba_pos >= FBA_NUM(vec->sv_len); vec++)
- fba_pos -= FBA_NUM(vec->sv_len);
-
- sv_addr = vec->sv_addr + FBA_SIZE(fba_pos); /* data in vector */
- sv_len = vec->sv_len - FBA_SIZE(fba_pos); /* bytes in vector */
-
- while (len) {
- nsc_size_t translen;
- if (len > maxfbas) {
- translen = maxfbas;
- } else {
- translen = len;
- }
-
- if (FBA_SIZE(translen) > sv_len) {
- translen = FBA_NUM(sv_len);
- }
-
- len -= translen;
- if (len == 0) {
- /* last data xfer rpc - tell server to cleanup */
- transflag |= RDC_RREAD_END;
- }
-
- if (!rr.rr_data || (nsc_size_t)rr.rr_bufsize !=
- FBA_SIZE(translen)) {
- if (rr.rr_data)
- kmem_free(rr.rr_data, rr.rr_bufsize);
-
- ASSERT(FBA_SIZE(translen) <= INT32_MAX);
- rr.rr_bufsize = FBA_SIZE(translen);
- rr.rr_data = kmem_alloc(rr.rr_bufsize, KM_NOSLEEP);
- }
-
- if (!rr.rr_data) {
- /* error */
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!rdc_net_read: kmem_alloc failed");
-#endif
- return (ENOMEM);
- }
-
- /* get data from remote end */
-
-#ifdef DEBUG
- if (krdc->intf == NULL)
- cmn_err(CE_WARN,
- "!rdc_net_read: null intf for index %d",
- local_index);
-#endif
- if (krdc->io_kstats) {
- mutex_enter(krdc->io_kstats->ks_lock);
- kstat_runq_enter(KSTAT_IO_PTR(krdc->io_kstats));
- mutex_exit(krdc->io_kstats->ks_lock);
- }
- /*CONSTCOND*/
- ASSERT(RDC_MAXDATA <= INT32_MAX);
- ASSERT(translen <= RDC_MAXDATA);
- if (krdc->rpc_version <= RDC_VERSION5) {
- list.len = (int)translen;
- list.flag = transflag;
- err = rdc_clnt_call(krdc->lsrv, RDCPROC_READ5,
- krdc->rpc_version, xdr_rread, (char *)&list,
- xdr_rdresult, (char *)&rr, &t);
- } else {
- list6.len = (int)translen;
- list6.flag = transflag;
- err = rdc_clnt_call(krdc->lsrv, RDCPROC_READ6,
- krdc->rpc_version, xdr_rread6, (char *)&list6,
- xdr_rdresult, (char *)&rr, &t);
- }
-
- if (krdc->io_kstats) {
- mutex_enter(krdc->io_kstats->ks_lock);
- kstat_runq_exit(KSTAT_IO_PTR(krdc->io_kstats));
- mutex_exit(krdc->io_kstats->ks_lock);
- }
-
- if (err) {
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!rdc_net_read: rpc err %d", err);
-#endif
- if (err == RPC_INTR) {
- ret = EINTR;
- } else {
- ret = ENOLINK;
- }
-
- goto remote_rerror;
- }
-
- if (rr.rr_status != RDC_OK) {
- ret = rdc_rrstatus_decode(rr.rr_status);
- if (!ret)
- ret = EIO;
-
- goto remote_rerror;
- }
-
- /* copy into handle */
-
- bcopy(rr.rr_data, sv_addr, (size_t)rr.rr_bufsize);
-
- /* update counters */
-
- sv_addr += rr.rr_bufsize;
- if (krdc->rpc_version <= RDC_VERSION5) {
- list.pos += translen;
- } else {
- list6.pos += translen;
- }
- if (krdc->io_kstats) {
- KSTAT_IO_PTR(krdc->io_kstats)->reads++;
- KSTAT_IO_PTR(krdc->io_kstats)->nread += rr.rr_bufsize;
- }
- ASSERT(sv_len <= INT32_MAX);
- ASSERT(sv_len >= (nsc_size_t)rr.rr_bufsize);
- sv_len -= rr.rr_bufsize;
-
- if (sv_len == 0) {
- /* goto next vector */
- vec++;
- sv_addr = vec->sv_addr;
- sv_len = vec->sv_len;
- }
- }
-
- if (rr.rr_data)
- kmem_free(rr.rr_data, rr.rr_bufsize);
-
- return (0);
-
-remote_rerror:
- if (rr.rr_data)
- kmem_free(rr.rr_data, rr.rr_bufsize);
-
- return (ret ? ret : ENOLINK);
-}
-
-/*
- * rdc_net_write
- * Main remote write client side
- * Handles protocol selection as well as requests for remote allocation
- * and data transfer
- * Does local IO for FCAL
- * caller must clear bitmap on success
- */
-
-int
-rdc_net_write(int local_index, int remote_index, nsc_buf_t *handle,
- nsc_off_t fba_pos, nsc_size_t fba_len, uint_t aseq, int qpos,
- netwriteres *netres)
-{
- rdc_k_info_t *krdc;
- rdc_u_info_t *urdc;
- struct timeval t;
- nsc_vec_t *vec;
- int sv_len;
- nsc_off_t fpos;
- int err;
- struct netwriteres netret;
- struct netwriteres *netresptr;
- struct net_data5 dlist5;
- struct net_data6 dlist6;
- int ret;
- nsc_size_t maxfbas;
- int transflag;
- int translen;
- int transendoblk;
- char *transptr;
- int vflags;
-
- if (handle == NULL)
- return (EINVAL);
-
- /* if not a diskq buffer */
- if ((qpos == -1) && (!RDC_HANDLE_LIMITS(handle, fba_pos, fba_len))) {
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!rdc_net_write: handle bounds");
-#endif
- return (EINVAL);
- }
-
-
- t.tv_sec = rdc_rpc_tmout;
- t.tv_usec = 0;
-
- krdc = &rdc_k_info[local_index];
- urdc = &rdc_u_info[local_index];
-
- maxfbas = MAX_RDC_FBAS;
-
- /* FCAL IO */
- if (krdc->remote_fd && !(rdc_get_vflags(urdc) & RDC_FCAL_FAILED)) {
- nsc_buf_t *remote_h = NULL;
- int reserved = 0;
-
- ret = nsc_reserve(krdc->remote_fd, NSC_MULTI);
- if (RDC_SUCCESS(ret)) {
- reserved = 1;
- ret = nsc_alloc_buf(krdc->remote_fd, fba_pos, fba_len,
- NSC_WRBUF, &remote_h);
- }
- if (RDC_SUCCESS(ret)) {
- ret = nsc_copy(handle, remote_h, fba_pos, fba_pos,
- fba_len);
- if (RDC_SUCCESS(ret))
- ret = nsc_write(remote_h, fba_pos, fba_len, 0);
- if (RDC_SUCCESS(ret)) {
- (void) nsc_free_buf(remote_h);
- nsc_release(krdc->remote_fd);
- return (0);
- }
- }
- rdc_group_enter(krdc);
- rdc_set_flags(urdc, RDC_FCAL_FAILED);
- rdc_group_exit(krdc);
- if (remote_h)
- (void) nsc_free_buf(remote_h);
- if (reserved)
- nsc_release(krdc->remote_fd);
- }
-
- /*
- * At this point we must decide which protocol we are using and
- * do the right thing
- */
- netret.vecdata.vecdata_val = NULL;
- netret.vecdata.vecdata_len = 0;
- if (netres) {
- netresptr = netres;
- } else {
- netresptr = &netret;
- }
-
- vflags = rdc_get_vflags(urdc);
-
- if (vflags & (RDC_VOL_FAILED|RDC_BMP_FAILED))
- transflag = RDC_RWRITE_FAIL;
- else
- transflag = 0;
-
-
-#ifdef DEBUG
- if (krdc->intf == NULL)
- cmn_err(CE_WARN, "!rdc_net_write: null intf for index %d",
- local_index);
-#endif
-
- vec = handle->sb_vec;
-
- /*
- * find starting position in vector
- */
- if ((qpos == -1) || (handle->sb_user == RDC_NULLBUFREAD))
- fpos = fba_pos - handle->sb_pos;
- else
- fpos = (qpos + 1) - handle->sb_pos;
-
- for (; fpos >= FBA_NUM(vec->sv_len); vec++)
- fpos -= FBA_NUM(vec->sv_len);
- sv_len = vec->sv_len - FBA_SIZE(fpos); /* bytes in vector */
- transptr = (char *)vec->sv_addr + FBA_SIZE(fpos);
-
- if (krdc->rpc_version <= RDC_VERSION5) {
- dlist5.local_cd = local_index;
- dlist5.cd = remote_index;
- ASSERT(fba_len <= INT32_MAX);
- ASSERT(fba_pos <= INT32_MAX);
- dlist5.len = (int)fba_len;
- dlist5.pos = (int)fba_pos;
- dlist5.idx = -1; /* Starting index */
- dlist5.flag = transflag;
- dlist5.seq = aseq; /* sequence number */
- dlist5.sfba = (int)fba_pos; /* starting fba for this xfer */
- } else {
- dlist6.local_cd = local_index;
- dlist6.cd = remote_index;
- ASSERT(fba_len <= INT32_MAX);
- dlist6.len = (int)fba_len;
- dlist6.qpos = qpos;
- dlist6.pos = fba_pos;
- dlist6.idx = -1; /* Starting index */
- dlist6.flag = transflag;
- dlist6.seq = aseq; /* sequence number */
- dlist6.sfba = fba_pos; /* starting fba for this xfer */
- }
-
- transendoblk = 0;
- while (fba_len) {
- if (!transptr) {
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!rdc_net_write: walked off end of handle!");
-#endif
- ret = EINVAL;
- goto remote_error;
- }
-
- if (fba_len > maxfbas) {
- ASSERT(maxfbas <= INT32_MAX);
- translen = (int)maxfbas;
- } else {
- ASSERT(fba_len <= INT32_MAX);
- translen = (int)fba_len;
- }
-
- if (FBA_SIZE(translen) > sv_len) {
- translen = FBA_NUM(sv_len);
- }
-
- fba_len -= translen;
- if (fba_len == 0) {
- /* last data xfer - tell server to commit */
- transendoblk = 1;
- }
-
-
-#ifdef DEBUG
- if (krdc->intf == NULL)
- cmn_err(CE_WARN,
- "!rdc_net_write: null intf for index %d",
- local_index);
-#endif
- DTRACE_PROBE(rdc_netwrite_clntcall_start);
-
- if (krdc->io_kstats) {
- mutex_enter(krdc->io_kstats->ks_lock);
- kstat_runq_enter(KSTAT_IO_PTR(krdc->io_kstats));
- mutex_exit(krdc->io_kstats->ks_lock);
- }
- if (krdc->rpc_version <= RDC_VERSION5) {
- ret = 0;
- dlist5.nfba = translen;
- dlist5.endoblk = transendoblk;
- dlist5.data.data_len = FBA_SIZE(translen);
- dlist5.data.data_val = transptr;
- err = rdc_clnt_call(krdc->lsrv, RDCPROC_WRITE5,
- krdc->rpc_version, xdr_net_data5,
- (char *)&dlist5, xdr_int,
- (char *)&ret, &t);
- if (ret >= 0) {
- netresptr->result = 0;
- netresptr->index = ret;
- } else {
- netresptr->result = ret;
- }
- } else {
- netresptr->result = 0;
- dlist6.nfba = translen;
- dlist6.endoblk = transendoblk;
- dlist6.data.data_len = FBA_SIZE(translen);
- dlist6.data.data_val = transptr;
- err = rdc_clnt_call(krdc->lsrv, RDCPROC_WRITE6,
- krdc->rpc_version, xdr_net_data6,
- (char *)&dlist6, xdr_netwriteres,
- (char *)netresptr, &t);
- }
-
- if (krdc->io_kstats) {
- mutex_enter(krdc->io_kstats->ks_lock);
- kstat_runq_exit(KSTAT_IO_PTR(krdc->io_kstats));
- mutex_exit(krdc->io_kstats->ks_lock);
- }
-
- DTRACE_PROBE(rdc_netwrite_clntcall_end);
- ret = netresptr->result;
- if (err) {
- if (err == RPC_INTR)
- ret = EINTR;
- else if (err && ret != EPROTO)
- ret = ENOLINK;
-#ifdef DEBUG
- cmn_err(CE_NOTE,
- "!rdc_net_write(5): cd %d err %d ret %d",
- remote_index, err, ret);
-#endif
- goto remote_error;
- }
- /* Error from r_net_write5 */
- if (netresptr->result < 0) {
-#ifdef DEBUG
- cmn_err(CE_NOTE,
- "!rdc_net_write: r_net_write(5) "
- "returned: %d",
- -netresptr->result);
-#endif
- ret = -netresptr->result;
- if (netret.vecdata.vecdata_val)
- kmem_free(netret.vecdata.vecdata_val,
- netret.vecdata.vecdata_len *
- sizeof (net_pendvec_t));
- goto remote_error;
- } else if (netresptr->index == 0) {
-#ifdef DEBUG
- cmn_err(CE_NOTE,
- "!rdc_net_write: no valid index from "
- "r_net_write(5)");
-#endif
- ret = ENOBUFS;
- if (netret.vecdata.vecdata_val)
- kmem_free(netret.vecdata.vecdata_val,
- netret.vecdata.vecdata_len *
- sizeof (net_pendvec_t));
- goto remote_error;
- }
- if (krdc->rpc_version <= RDC_VERSION5) {
- dlist5.idx = netresptr->index;
- dlist5.sfba += dlist5.nfba;
- } else {
- dlist6.idx = netresptr->index;
- dlist6.sfba += dlist6.nfba;
- }
- /* update counters */
- if (krdc->io_kstats) {
- KSTAT_IO_PTR(krdc->io_kstats)->writes++;
- KSTAT_IO_PTR(krdc->io_kstats)->nwritten +=
- FBA_SIZE(translen);
- }
- transptr += FBA_SIZE(translen);
- sv_len -= FBA_SIZE(translen);
-
- if (sv_len <= 0) {
- /* goto next vector */
- vec++;
- transptr = (char *)vec->sv_addr;
- sv_len = vec->sv_len;
- }
- }
- /*
- * this can't happen.....
- */
- if (netret.vecdata.vecdata_val)
- kmem_free(netret.vecdata.vecdata_val,
- netret.vecdata.vecdata_len *
- sizeof (net_pendvec_t));
-
- return (0);
-
-remote_error:
- return (ret ? ret : ENOLINK);
-}
-
-void
-rdc_fixlen(rdc_aio_t *aio)
-{
- nsc_vec_t *vecp = aio->qhandle->sb_vec;
- nsc_size_t len = 0;
-
- while (vecp->sv_addr) {
- len += FBA_NUM(vecp->sv_len);
- vecp++;
- }
- aio->qhandle->sb_len = len;
-}
-
-/*
- * rdc_dump_alloc_bufs_cd
- * Dump allocated buffers (rdc_net_hnd's) for the specified cd.
- * this could be the flusher failing, if so, don't do the delay forever
- * Returns: 0 (success), EAGAIN (caller needs to try again).
- */
-int
-rdc_dump_alloc_bufs_cd(int index)
-{
- rdc_k_info_t *krdc;
- rdc_aio_t *aio;
- net_queue *q;
- disk_queue *dq;
- kmutex_t *qlock;
-
- krdc = &rdc_k_info[index];
-
-
- if (!krdc->c_fd) {
- /* cannot do anything! */
-#ifdef DEBUG
- cmn_err(CE_WARN, "!rdc_dump_alloc_bufs_cd(%d): c_fd NULL",
- index);
-#endif
- return (0);
- }
- rdc_dump_dsets(index);
-
- dq = &krdc->group->diskq;
-
- if (RDC_IS_DISKQ(krdc->group)) {
- qlock = QLOCK(dq);
- (void) _rdc_rsrv_diskq(krdc->group);
- } else {
- qlock = &krdc->group->ra_queue.net_qlock;
- }
-
- /*
- * Now dump the async queue anonymous buffers
- * if we are a diskq, the we are using the diskq mutex.
- * However, we are flushing from diskq to memory queue
- * so we now need to grab the memory lock also
- */
-
- q = &krdc->group->ra_queue;
-
- if (RDC_IS_DISKQ(krdc->group)) {
- mutex_enter(&q->net_qlock);
- if (q->qfill_sleeping == RDC_QFILL_AWAKE) {
- int tries = 5;
-#ifdef DEBUG_DISKQ
- cmn_err(CE_NOTE,
- "!dumpalloccd sending diskq->memq flush to sleep");
-#endif
- q->qfflags |= RDC_QFILLSLEEP;
- mutex_exit(&q->net_qlock);
-
- while (q->qfill_sleeping == RDC_QFILL_AWAKE && tries--)
- delay(5);
- mutex_enter(&q->net_qlock);
- }
- }
-
- mutex_enter(qlock);
-
- while ((q->net_qhead != NULL)) {
- rdc_k_info_t *tmpkrdc;
- aio = q->net_qhead;
- tmpkrdc = &rdc_k_info[aio->index];
-
- if (RDC_IS_DISKQ(krdc->group)) {
- aio->qhandle->sb_user--;
- if (aio->qhandle->sb_user == 0) {
- rdc_fixlen(aio);
- (void) nsc_free_buf(aio->qhandle);
- aio->qhandle = NULL;
- aio->handle = NULL;
- }
- } else {
- if (aio->handle) {
- (void) nsc_free_buf(aio->handle);
- aio->handle = NULL;
- }
- }
-
- if (tmpkrdc->io_kstats && !RDC_IS_DISKQ(krdc->group)) {
- mutex_enter(tmpkrdc->io_kstats->ks_lock);
- kstat_waitq_exit(KSTAT_IO_PTR(tmpkrdc->io_kstats));
- mutex_exit(tmpkrdc->io_kstats->ks_lock);
- }
- q->net_qhead = q->net_qhead->next;
- q->blocks -= aio->len;
- q->nitems--;
-
- RDC_CHECK_BIT(tmpkrdc, aio->pos, aio->len);
-
- kmem_free(aio, sizeof (*aio));
- }
- q->net_qtail = NULL;
-
- if (krdc->group->asyncstall) {
- krdc->group->asyncdis = 1;
- cv_broadcast(&krdc->group->asyncqcv);
- }
- if (krdc->group->sleepq) {
- rdc_sleepqdiscard(krdc->group);
- }
-
- krdc->group->seq = RDC_NEWSEQ;
- krdc->group->seqack = RDC_NEWSEQ;
- if (RDC_IS_DISKQ(krdc->group)) {
- rdc_dump_iohdrs(dq);
- SET_QNXTIO(dq, QHEAD(dq));
- SET_QCOALBOUNDS(dq, QHEAD(dq));
- }
- mutex_exit(qlock);
-
- if (RDC_IS_DISKQ(krdc->group)) {
- mutex_exit(&q->net_qlock);
- _rdc_rlse_diskq(krdc->group);
- }
-
- return (0);
-}
-
-
-/*
- * rdc_dump_alloc_bufs
- * We have an error on the link
- * Try to dump all of the allocated bufs so we can cleanly recover
- * and not hang
- */
-void
-rdc_dump_alloc_bufs(rdc_if_t *ip)
-{
- rdc_k_info_t *krdc;
- int repeat;
- int index;
-
- for (index = 0; index < rdc_max_sets; index++) {
- do {
- krdc = &rdc_k_info[index];
- repeat = 0;
- if (krdc->intf == ip) {
- if (rdc_dump_alloc_bufs_cd(index) == EAGAIN) {
- repeat = 1;
- delay(2);
- }
- }
- } while (repeat);
- }
-}
-
-/*
- * returns 1 if the the throttle should throttle, 0 if not.
- */
-int
-_rdc_diskq_isfull(disk_queue *q, long len)
-{
- /* ---T----H----N--- */
- mutex_enter(QLOCK(q));
-
- if (FITSONQ(q, len + 1)) {
- mutex_exit(QLOCK(q));
- return (0);
- }
- mutex_exit(QLOCK(q));
- return (1);
-}
-
-void
-_rdc_async_throttle(rdc_k_info_t *this, long len)
-{
- rdc_k_info_t *krdc;
- rdc_u_info_t *urdc;
- int print_msg = 1;
- int tries = RDC_FUTILE_ATTEMPTS;
-
- /*
- * Throttle entries on queue
- */
-
- /* Need to take the 1-many case into account, checking all sets */
-
- /* ADD HANDY HUERISTIC HERE TO SLOW DOWN IO */
- for (krdc = this; /* CSTYLED */; krdc = krdc->many_next) {
- urdc = &rdc_u_info[krdc->index];
-
- /*
- * this may be the last set standing in a one to many setup.
- * we may also be stuck in unintercept, after marking
- * the volume as not enabled, but have not removed it
- * from the many list resulting in an endless loop if
- * we just continue here. Lets jump over this stuff
- * and check to see if we are the only dude here.
- */
- if (!IS_ENABLED(urdc))
- goto thischeck;
-
- if (IS_ASYNC(urdc) && RDC_IS_MEMQ(krdc->group)) {
- net_queue *q = &krdc->group->ra_queue;
- while ((q->blocks + q->inflbls) > urdc->maxqfbas ||
- (q->nitems + q->inflitems) > urdc->maxqitems) {
-
- if (!IS_ENABLED(urdc)) /* disable race */
- goto thischeck;
-
- if (!krdc->group->rdc_writer)
- (void) rdc_writer(krdc->index);
- delay(2);
- q->throttle_delay++;
- }
- }
-
- /* do a much more aggressive delay, get disk flush going */
- if (IS_ASYNC(urdc) && RDC_IS_DISKQ(krdc->group)) {
- disk_queue *q = &krdc->group->diskq;
- while ((!IS_QSTATE(q, RDC_QNOBLOCK)) &&
- (_rdc_diskq_isfull(q, len)) &&
- (!IS_STATE(urdc, RDC_DISKQ_FAILED))) {
- if (print_msg) {
- cmn_err(CE_WARN, "!rdc async throttle:"
- " disk queue %s full",
- &urdc->disk_queue[0]);
-
- print_msg = 0;
- }
- if (!IS_ENABLED(urdc)) /* disable race */
- goto thischeck;
-
- if (!krdc->group->rdc_writer)
- (void) rdc_writer(krdc->index);
- delay(10);
- q->throttle_delay += 10;
-
- if (!(tries--) && IS_STATE(urdc, RDC_QUEUING)) {
- cmn_err(CE_WARN, "!SNDR: disk queue "
- "%s full & not flushing. giving up",
- &urdc->disk_queue[0]);
- cmn_err(CE_WARN, "!SNDR: %s:%s entering"
- " logging mode",
- urdc->secondary.intf,
- urdc->secondary.file);
- rdc_fail_diskq(krdc, RDC_WAIT,
- RDC_DOLOG | RDC_NOFAIL);
- mutex_enter(QLOCK(q));
- cv_broadcast(&q->qfullcv);
- mutex_exit(QLOCK(q));
- }
-
- }
- if ((IS_QSTATE(q, RDC_QNOBLOCK)) &&
- _rdc_diskq_isfull(q, len) &&
- !IS_STATE(urdc, RDC_DISKQ_FAILED)) {
- if (print_msg) {
- cmn_err(CE_WARN, "!disk queue %s full",
- &urdc->disk_queue[0]);
- print_msg = 0;
- }
- rdc_fail_diskq(krdc, RDC_WAIT,
- RDC_DOLOG | RDC_NOFAIL);
- mutex_enter(QLOCK(q));
- cv_broadcast(&q->qfullcv);
- mutex_exit(QLOCK(q));
- }
- }
-
-thischeck:
- if (krdc->many_next == this)
- break;
- }
-}
-
-int rdc_coalesce = 1;
-static int rdc_joins = 0;
-
-int
-rdc_aio_coalesce(rdc_aio_t *queued, rdc_aio_t *new)
-{
- nsc_buf_t *h = NULL;
- int rc;
- rdc_k_info_t *krdc;
- uint_t bitmask;
-
- if (rdc_coalesce == 0)
- return (0); /* don't even try */
-
- if ((queued == NULL) ||
- (queued->handle == NULL) ||
- (new->handle == NULL)) {
- return (0); /* existing queue is empty */
- }
- if (queued->index != new->index || queued->len + new->len >
- MAX_RDC_FBAS) {
- return (0); /* I/O to big */
- }
- if ((queued->pos + queued->len == new->pos) ||
- (new->pos + new->len == queued->pos)) {
- rc = nsc_alloc_abuf(queued->pos, queued->len + new->len, 0,
- &h);
- if (!RDC_SUCCESS(rc)) {
- if (h != NULL)
- (void) nsc_free_buf(h);
- return (0); /* couldn't do coalesce */
- }
- rc = nsc_copy(queued->handle, h, queued->pos, queued->pos,
- queued->len);
- if (!RDC_SUCCESS(rc)) {
- (void) nsc_free_buf(h);
- return (0); /* couldn't do coalesce */
- }
- rc = nsc_copy(new->handle, h, new->pos, new->pos,
- new->len);
- if (!RDC_SUCCESS(rc)) {
- (void) nsc_free_buf(h);
- return (0); /* couldn't do coalesce */
- }
-
- krdc = &rdc_k_info[queued->index];
-
- RDC_SET_BITMASK(queued->pos, queued->len, &bitmask);
- RDC_CLR_BITMAP(krdc, queued->pos, queued->len, \
- bitmask, RDC_BIT_BUMP);
-
- RDC_SET_BITMASK(new->pos, new->len, &bitmask);
- RDC_CLR_BITMAP(krdc, new->pos, new->len, \
- bitmask, RDC_BIT_BUMP);
-
- (void) nsc_free_buf(queued->handle);
- (void) nsc_free_buf(new->handle);
- queued->handle = h;
- queued->len += new->len;
- bitmask = 0;
- /*
- * bump the ref count back up
- */
-
- RDC_SET_BITMAP(krdc, queued->pos, queued->len, &bitmask);
- return (1); /* new I/O succeeds last I/O queued */
- }
- return (0);
-}
-
-int
-rdc_memq_enqueue(rdc_k_info_t *krdc, rdc_aio_t *aio)
-{
- net_queue *q;
- rdc_group_t *group;
-
- group = krdc->group;
- q = &group->ra_queue;
-
- mutex_enter(&q->net_qlock);
-
- if (rdc_aio_coalesce(q->net_qtail, aio)) {
- rdc_joins++;
- q->blocks += aio->len;
- kmem_free(aio, sizeof (*aio));
- goto out;
- }
- aio->seq = group->seq++;
- if (group->seq < aio->seq)
- group->seq = RDC_NEWSEQ + 1; /* skip magics */
-
- if (q->net_qhead == NULL) {
- /* adding to empty q */
- q->net_qhead = q->net_qtail = aio;
-
-#ifdef DEBUG
- if (q->blocks != 0 || q->nitems != 0) {
- cmn_err(CE_PANIC,
- "rdc enqueue: q %p, qhead 0, q blocks %" NSC_SZFMT
- ", nitems %" NSC_SZFMT,
- (void *) q, q->blocks, q->nitems);
- }
-#endif
-
- } else {
- /* discontiguous, add aio to q tail */
- q->net_qtail->next = aio;
- q->net_qtail = aio;
- }
-
- q->blocks += aio->len;
- q->nitems++;
-
- if (krdc->io_kstats) {
- mutex_enter(krdc->io_kstats->ks_lock);
- kstat_waitq_enter(KSTAT_IO_PTR(krdc->io_kstats));
- mutex_exit(krdc->io_kstats->ks_lock);
- }
-out:
-#ifdef DEBUG
- /* sum the q and check for sanity */
- {
- nsc_size_t qblocks = 0;
- uint64_t nitems = 0;
- rdc_aio_t *a;
-
- for (a = q->net_qhead; a != NULL; a = a->next) {
- qblocks += a->len;
- nitems++;
- }
-
- if (qblocks != q->blocks || nitems != q->nitems) {
- cmn_err(CE_PANIC,
- "rdc enqueue: q %p, q blocks %" NSC_SZFMT " (%"
- NSC_SZFMT "), nitems %" NSC_SZFMT " (%"
- NSC_SZFMT ")", (void *) q, q->blocks, qblocks,
- q->nitems, nitems);
- }
- }
-#endif
-
- mutex_exit(&q->net_qlock);
-
- if (q->nitems > q->nitems_hwm) {
- q->nitems_hwm = q->nitems;
- }
-
- if (q->blocks > q->blocks_hwm) {
- q->blocks_hwm = q->blocks;
- }
-
- if (!krdc->group->rdc_writer)
- (void) rdc_writer(krdc->index);
-
- return (0);
-}
-
-int
-_rdc_enqueue_write(rdc_k_info_t *krdc, nsc_off_t pos, nsc_size_t len, int flag,
- nsc_buf_t *h)
-{
- rdc_aio_t *aio;
- rdc_group_t *group;
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- int rc;
-
- aio = kmem_zalloc(sizeof (*aio), KM_NOSLEEP);
- if (!aio) {
- return (ENOMEM);
- }
-
- group = krdc->group;
-
- aio->pos = pos;
- aio->qpos = -1;
- aio->len = len;
- aio->flag = flag;
- aio->index = krdc->index;
- aio->handle = h;
-
- if (group->flags & RDC_MEMQUE) {
- return (rdc_memq_enqueue(krdc, aio));
- } else if ((group->flags & RDC_DISKQUE) &&
- !IS_STATE(urdc, RDC_DISKQ_FAILED)) {
- rc = rdc_diskq_enqueue(krdc, aio);
- kmem_free(aio, sizeof (*aio));
- return (rc);
- }
- return (-1); /* keep lint quiet */
-}
-
-
-
-
-/*
- * Async Network RDC flusher
- */
-
-/*
- * don't allow any new writer threads to start if a member of the set
- * is disable pending
- */
-int
-is_disable_pending(rdc_k_info_t *krdc)
-{
- rdc_k_info_t *this = krdc;
- int rc = 0;
-
- do {
- if (krdc->type_flag & RDC_DISABLEPEND) {
- krdc = this;
- rc = 1;
- break;
- }
- krdc = krdc->group_next;
-
- } while (krdc != this);
-
- return (rc);
-}
-
-/*
- * rdc_writer -- spawn new writer if not running already
- * called after enqueing the dirty blocks
- */
-int
-rdc_writer(int index)
-{
- rdc_k_info_t *krdc = &rdc_k_info[index];
- nsthread_t *t;
- rdc_group_t *group;
- kmutex_t *qlock;
- int tries;
- const int MAX_TRIES = 16;
-
- group = krdc->group;
-
- if (RDC_IS_DISKQ(group))
- qlock = &group->diskq.disk_qlock;
- else
- qlock = &group->ra_queue.net_qlock;
-
- mutex_enter(qlock);
-
-#ifdef DEBUG
- if (noflush) {
- mutex_exit(qlock);
- return (0);
- }
-#endif
-
- if ((group->rdc_writer) || is_disable_pending(krdc)) {
- mutex_exit(qlock);
- return (0);
- }
-
- if ((group->rdc_thrnum >= 1) && (group->seqack == RDC_NEWSEQ)) {
- /*
- * We also need to check if we are starting a new
- * sequence, and if so don't create a new thread,
- * as we must ensure that the start of new sequence
- * requests arrives first to re-init the server.
- */
- mutex_exit(qlock);
- return (0);
- }
- /*
- * For version 6,
- * see if we can fit in another thread.
- */
- group->rdc_thrnum++;
-
- if (krdc->intf && (krdc->intf->rpc_version >= RDC_VERSION6)) {
- rdc_u_info_t *urdc = &rdc_u_info[index];
- if (group->rdc_thrnum >= urdc->asyncthr)
- group->rdc_writer = 1;
- } else {
- group->rdc_writer = 1;
- }
-
- mutex_exit(qlock);
-
-
- /*
- * If we got here, we know that we have not exceeded the allowed
- * number of async threads for our group. If we run out of threads
- * in _rdc_flset, we add a new thread to the set.
- */
- tries = 0;
- do {
- /* first try to grab a thread from the free list */
- if (t = nst_create(_rdc_flset, rdc_flusher_thread,
- (blind_t)(unsigned long)index, 0)) {
- break;
- }
-
- /* that failed; add a thread to the set and try again */
- if (nst_add_thread(_rdc_flset, 1) != 1) {
- cmn_err(CE_WARN, "!rdc_writer index %d nst_add_thread "
- "error, tries: %d", index, tries);
- break;
- }
- } while (++tries < MAX_TRIES);
-
- if (tries) {
- mutex_enter(&group->addthrnumlk);
- group->rdc_addthrnum += tries;
- mutex_exit(&group->addthrnumlk);
- }
-
- if (t) {
- return (1);
- }
-
- cmn_err(CE_WARN, "!rdc_writer: index %d nst_create error", index);
- rdc_many_enter(krdc);
- mutex_enter(qlock);
- group->rdc_thrnum--;
- group->rdc_writer = 0;
- if ((group->count == 0) && (group->rdc_thrnum == 0)) {
- mutex_exit(qlock);
- /*
- * Race with remove_from_group while write thread was
- * failing to be created.
- */
-#ifdef DEBUG
- cmn_err(CE_WARN, "!rdc_writer: group being destroyed");
-#endif
- rdc_delgroup(group);
- krdc->group = NULL;
- rdc_many_exit(krdc);
- return (-1);
- }
- mutex_exit(qlock);
- rdc_many_exit(krdc);
- return (-1);
-}
-
-/*
- * Either we need to flush the
- * kmem (net_queue) queue or the disk (disk_queue)
- * determine which, and do it.
- */
-void
-rdc_flusher_thread(int index)
-{
- rdc_k_info_t *krdc = &rdc_k_info[index];
-
- if (krdc->group->flags & RDC_MEMQUE) {
- rdc_flush_memq(index);
- return;
- } else if (krdc->group->flags & RDC_DISKQUE) {
- rdc_flush_diskq(index);
- return;
- } else { /* uh-oh, big time */
- cmn_err(CE_PANIC, "flusher trying to flush unknown queue type");
- }
-
-}
-
-void
-rdc_flush_memq(int index)
-{
- rdc_k_info_t *krdc = &rdc_k_info[index];
- rdc_aio_t *aio;
- net_queue *q;
- int dowork;
- rdc_group_t *group = krdc->group;
- if (!group || group->count == 0) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!rdc_flush_memq: no group left!");
-#endif
- return;
- }
-
- if (!krdc->c_fd) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!rdc_flush_memq: no c_fd!");
-#endif
- goto thread_death;
- }
-
-#ifdef DEBUG_DISABLE
- if (index < 0 || (krdc->type_flag & RDC_DISABLEPEND)) {
- cmn_err(CE_WARN, "!rdc_flush_memq: DISABLE PENDING!");
- /*
- * Need to continue as we may be trying to flush IO
- * while trying to disable or suspend
- */
- }
-#endif
-
- q = &group->ra_queue;
-
- dowork = 1;
- /* CONSTCOND */
- while (dowork) {
- if (net_exit == ATM_EXIT)
- break;
-
- group = krdc->group;
- if (!group || group->count == 0) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!rdc_flush_memq: no group left!");
-#endif
- break;
- }
-
- mutex_enter(&q->net_qlock);
- aio = q->net_qhead;
-
- if (aio == NULL) {
-#ifdef DEBUG
- if (q->nitems != 0 ||
- q->blocks != 0 ||
- q->net_qtail != 0) {
- cmn_err(CE_PANIC,
- "rdc_flush_memq(1): q %p, q blocks %"
- NSC_SZFMT ", nitems %" NSC_SZFMT
- ", qhead %p qtail %p",
- (void *) q, q->blocks, q->nitems,
- (void *) aio, (void *) q->net_qtail);
- }
-#endif
- mutex_exit(&q->net_qlock);
- break;
- }
-
- /* aio remove from q */
-
- q->net_qhead = aio->next;
- aio->next = NULL;
-
- if (q->net_qtail == aio)
- q->net_qtail = q->net_qhead;
-
- q->blocks -= aio->len;
- q->nitems--;
-
- /*
- * in flight numbers.
- */
- q->inflbls += aio->len;
- q->inflitems++;
-
-#ifdef DEBUG
- if (q->net_qhead == NULL) {
- if (q->nitems != 0 ||
- q->blocks != 0 ||
- q->net_qtail != 0) {
- cmn_err(CE_PANIC,
- "rdc_flush_memq(2): q %p, q blocks %"
- NSC_SZFMT ", nitems %" NSC_SZFMT
- ", qhead %p qtail %p",
- (void *) q, q->blocks, q->nitems,
- (void *) q->net_qhead,
- (void *) q->net_qtail);
- }
- }
-
-#ifndef NSC_MULTI_TERABYTE
- if (q->blocks < 0) {
- cmn_err(CE_PANIC,
- "rdc_flush_memq(3): q %p, q blocks %" NSC_SZFMT
- ", nitems %d, qhead %p, qtail %p",
- (void *) q, q->blocks, q->nitems,
- (void *) q->net_qhead, (void *) q->net_qtail);
- }
-#else
- /* blocks and nitems are unsigned for NSC_MULTI_TERABYTE */
-#endif
-#endif
-
- mutex_exit(&q->net_qlock);
-
- aio->iostatus = RDC_IO_INIT;
-
- _rdc_remote_flush(aio);
-
- mutex_enter(&q->net_qlock);
- q->inflbls -= aio->len;
- q->inflitems--;
- if ((group->seqack == RDC_NEWSEQ) &&
- (group->seq != RDC_NEWSEQ + 1)) {
- if ((q->net_qhead == NULL) ||
- (q->net_qhead->seq != RDC_NEWSEQ + 1)) {
- /*
- * We are an old thread, and the
- * queue sequence has been reset
- * during the network write above.
- * As such we mustn't pull another
- * job from the queue until the
- * first sequence message has been ack'ed.
- * Just die instead. Unless this thread
- * is the first sequence that has just
- * been ack'ed
- */
- dowork = 0;
- }
- }
- mutex_exit(&q->net_qlock);
-
- if ((aio->iostatus != RDC_IO_DONE) && (group->count)) {
- rdc_k_info_t *krdctmp = &rdc_k_info[aio->index];
- if (krdctmp->type_flag & RDC_DISABLEPEND) {
- kmem_free(aio, sizeof (*aio));
- goto thread_death;
- }
- rdc_group_enter(krdc);
- ASSERT(krdc->group);
- rdc_group_log(krdc, RDC_NOFLUSH | RDC_ALLREMOTE,
- "memq flush aio status not RDC_IO_DONE");
- rdc_group_exit(krdc);
- rdc_dump_queue(aio->index);
- }
- kmem_free(aio, sizeof (*aio));
-
- if (krdc->remote_index < 0 || !krdc->lsrv || !krdc->intf)
- break;
- }
-
-thread_death:
- rdc_many_enter(krdc);
- mutex_enter(&group->ra_queue.net_qlock);
- group->rdc_thrnum--;
- group->rdc_writer = 0;
- /*
- * all threads must be dead.
- */
- if ((group->count == 0) && (group->rdc_thrnum == 0)) {
- mutex_exit(&group->ra_queue.net_qlock);
- /*
- * Group now empty, so destroy
- * Race with remove_from_group while write thread was running
- */
-#ifdef DEBUG
- cmn_err(CE_WARN, "!rdc_flush_memq: group being destroyed");
-#endif
- rdc_delgroup(group);
- krdc->group = NULL;
- rdc_many_exit(krdc);
- return;
- }
- mutex_exit(&group->ra_queue.net_qlock);
- rdc_many_exit(krdc);
-}
-
-/*
- * rdc_flush_diskq
- * disk queue flusher
- */
-void
-rdc_flush_diskq(int index)
-{
- rdc_k_info_t *krdc = &rdc_k_info[index];
- rdc_u_info_t *urdc = &rdc_u_info[index];
- rdc_aio_t *aio = NULL;
- disk_queue *q;
- net_queue *nq;
- int dowork;
- int rc;
- rdc_group_t *group = krdc->group;
-
- if (!group || group->count == 0) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!rdc_flush_diskq: no group left!");
-#endif
- return;
- }
-
- if (!krdc->c_fd) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!rdc_flush_diskq: no c_fd!");
-#endif
- return;
- }
-
-#ifdef DEBUG_DISABLE
- if (index < 0 || (krdc->type_flag & RDC_DISABLEPEND)) {
- cmn_err(CE_WARN, "!rdc_flush_diskq: DISABLE PENDING!");
- /*
- * Need to continue as we may be trying to flush IO
- * while trying to disable or suspend
- */
- }
-#endif
- q = &group->diskq;
- nq = &group->ra_queue;
-
- if (IS_QSTATE(q, RDC_QDISABLEPEND) || IS_STATE(urdc, RDC_LOGGING)) {
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!flusher thread death 1 %x", QSTATE(q));
-#endif
- goto thread_death;
- }
-
- dowork = 1;
- /* CONSTCOND */
- while (dowork) {
- if (net_exit == ATM_EXIT)
- break;
-
- group = krdc->group;
- if (!group || group->count == 0) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!rdc_flush_diskq: no group left!");
-#endif
- break;
- }
-
- do {
- rc = 0;
- if ((IS_STATE(urdc, RDC_LOGGING)) ||
- (IS_STATE(urdc, RDC_SYNCING)) ||
- (nq->qfflags & RDC_QFILLSLEEP))
- goto thread_death;
-
- aio = rdc_dequeue(krdc, &rc);
-
- if ((IS_STATE(urdc, RDC_LOGGING)) ||
- (IS_STATE(urdc, RDC_SYNCING)) ||
- (nq->qfflags & RDC_QFILLSLEEP)) {
- goto thread_death;
- }
- if (rc == EAGAIN) {
- delay(40);
- }
-
- } while (rc == EAGAIN);
-
- if (aio == NULL) {
- break;
- }
-
- aio->iostatus = RDC_IO_INIT;
-
- mutex_enter(QLOCK(q));
- q->inflbls += aio->len;
- q->inflitems++;
- mutex_exit(QLOCK(q));
-
- _rdc_remote_flush(aio);
-
- mutex_enter(QLOCK(q));
- q->inflbls -= aio->len;
- q->inflitems--;
-
- if ((group->seqack == RDC_NEWSEQ) &&
- (group->seq != RDC_NEWSEQ + 1)) {
- if ((nq->net_qhead == NULL) ||
- (nq->net_qhead->seq != RDC_NEWSEQ + 1)) {
- /*
- * We are an old thread, and the
- * queue sequence has been reset
- * during the network write above.
- * As such we mustn't pull another
- * job from the queue until the
- * first sequence message has been ack'ed.
- * Just die instead. Unless of course,
- * this thread is the first sequence that
- * has just been ack'ed.
- */
- dowork = 0;
- }
- }
- mutex_exit(QLOCK(q));
-
- if (aio->iostatus == RDC_IO_CANCELLED) {
- rdc_dump_queue(aio->index);
- kmem_free(aio, sizeof (*aio));
- aio = NULL;
- if (group) { /* seq gets bumped on dequeue */
- mutex_enter(QLOCK(q));
- rdc_dump_iohdrs(q);
- SET_QNXTIO(q, QHEAD(q));
- SET_QCOALBOUNDS(q, QHEAD(q));
- group->seq = RDC_NEWSEQ;
- group->seqack = RDC_NEWSEQ;
- mutex_exit(QLOCK(q));
- }
- break;
- }
-
- if ((aio->iostatus != RDC_IO_DONE) && (group->count)) {
- rdc_k_info_t *krdctmp = &rdc_k_info[aio->index];
- if (krdctmp->type_flag & RDC_DISABLEPEND) {
- kmem_free(aio, sizeof (*aio));
- aio = NULL;
- goto thread_death;
- }
- rdc_group_enter(krdc);
- rdc_group_log(krdc,
- RDC_NOFLUSH | RDC_ALLREMOTE | RDC_QUEUING,
- "diskq flush aio status not RDC_IO_DONE");
- rdc_group_exit(krdc);
- rdc_dump_queue(aio->index);
- }
-
- kmem_free(aio, sizeof (*aio));
- aio = NULL;
-
-#ifdef DEBUG_DISABLE
- if (krdc->type_flag & RDC_DISABLEPEND) {
- cmn_err(CE_WARN,
- "!rdc_flush_diskq: DISABLE PENDING after IO!");
- }
-#endif
- if (krdc->remote_index < 0 || !krdc->lsrv || !krdc->intf)
- break;
-
- if (IS_QSTATE(q, RDC_QDISABLEPEND)) {
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!flusher thread death 2");
-#endif
- break;
- }
- }
-thread_death:
- rdc_many_enter(krdc);
- mutex_enter(QLOCK(q));
- group->rdc_thrnum--;
- group->rdc_writer = 0;
-
- if (aio && aio->qhandle) {
- aio->qhandle->sb_user--;
- if (aio->qhandle->sb_user == 0) {
- (void) _rdc_rsrv_diskq(krdc->group);
- rdc_fixlen(aio);
- (void) nsc_free_buf(aio->qhandle);
- aio->qhandle = NULL;
- aio->handle = NULL;
- _rdc_rlse_diskq(krdc->group);
- }
- }
- if ((group->count == 0) && (group->rdc_thrnum == 0)) {
- mutex_exit(QLOCK(q));
- /*
- * Group now empty, so destroy
- * Race with remove_from_group while write thread was running
- */
-#ifdef DEBUG
- cmn_err(CE_WARN, "!rdc_flush_diskq: group being destroyed");
-#endif
- mutex_enter(&group->diskqmutex);
- rdc_close_diskq(group);
- mutex_exit(&group->diskqmutex);
- rdc_delgroup(group);
- krdc->group = NULL;
- rdc_many_exit(krdc);
- return;
- }
- mutex_exit(QLOCK(q));
- rdc_many_exit(krdc);
-}
-
-/*
- * _rdc_remote_flush
- * Flush a single block ANON block
- * this function will flush from either the disk queue
- * or the memory queue. The appropriate locks must be
- * taken out etc, etc ...
- */
-static void
-_rdc_remote_flush(rdc_aio_t *aio)
-{
- rdc_k_info_t *krdc = &rdc_k_info[aio->index];
- rdc_u_info_t *urdc = &rdc_u_info[aio->index];
- disk_queue *q = &krdc->group->diskq;
- kmutex_t *qlock;
- rdc_group_t *group;
- nsc_buf_t *h = NULL;
- int reserved = 0;
- int rtype = RDC_RAW;
- int rc;
- uint_t maxseq;
- struct netwriteres netret;
- int waitq = 1;
- int vflags;
-
- group = krdc->group;
- netret.vecdata.vecdata_val = NULL;
- netret.vecdata.vecdata_len = 0;
-
- /* Where did we get this aio from anyway? */
- if (RDC_IS_DISKQ(group)) {
- qlock = &group->diskq.disk_qlock;
- } else {
- qlock = &group->ra_queue.net_qlock;
- }
-
- /*
- * quench transmission if we are too far ahead of the
- * server Q, or it will overflow.
- * Must fail all requests while asyncdis is set.
- * It will be cleared when the last thread to be discarded
- * sets the asyncstall counter to zero.
- * Note the thread within rdc_net_write
- * also bumps the asyncstall counter.
- */
-
- mutex_enter(qlock);
- if (group->asyncdis) {
- aio->iostatus = RDC_IO_CANCELLED;
- mutex_exit(qlock);
- goto failed;
- }
- /* don't go to sleep if we have gone logging! */
- vflags = rdc_get_vflags(urdc);
- if ((vflags & (RDC_BMP_FAILED|RDC_VOL_FAILED|RDC_LOGGING))) {
- if ((vflags & RDC_LOGGING) && RDC_IS_DISKQ(group))
- aio->iostatus = RDC_IO_CANCELLED;
-
- mutex_exit(qlock);
- goto failed;
- }
-
- while (maxseq = group->seqack + RDC_MAXPENDQ + 1,
- maxseq = (maxseq < group->seqack) ? maxseq + RDC_NEWSEQ + 1
- : maxseq, !RDC_INFRONT(aio->seq, maxseq)) {
- group->asyncstall++;
- ASSERT(!IS_STATE(urdc, RDC_LOGGING));
- cv_wait(&group->asyncqcv, qlock);
- group->asyncstall--;
- ASSERT(group->asyncstall >= 0);
- if (group->asyncdis) {
- if (group->asyncstall == 0) {
- group->asyncdis = 0;
- }
- aio->iostatus = RDC_IO_CANCELLED;
- mutex_exit(qlock);
- goto failed;
- }
- /*
- * See if we have gone into logging mode
- * since sleeping.
- */
- vflags = rdc_get_vflags(urdc);
- if (vflags & (RDC_BMP_FAILED|RDC_VOL_FAILED|RDC_LOGGING)) {
- if ((vflags & RDC_LOGGING) && RDC_IS_DISKQ(group))
- aio->iostatus = RDC_IO_CANCELLED;
-
- mutex_exit(qlock);
- goto failed;
- }
- }
- mutex_exit(qlock);
-
- if ((krdc->io_kstats) && (!RDC_IS_DISKQ(krdc->group))) {
- mutex_enter(krdc->io_kstats->ks_lock);
- kstat_waitq_exit(KSTAT_IO_PTR(krdc->io_kstats));
- mutex_exit(krdc->io_kstats->ks_lock);
- waitq = 0;
- }
-
-
- rc = _rdc_rsrv_devs(krdc, rtype, RDC_INTERNAL);
- if (rc != 0) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!_rdc_remote_flush: reserve, index %d, rc %d",
- aio->index, rc);
-#endif
- goto failed;
- }
-
- reserved = 1;
- /*
- * Case where we are multihop and calling with no ANON bufs
- * Need to do the read to fill the buf.
- */
- if (!aio->handle) {
- rc = nsc_alloc_buf(RDC_U_FD(krdc), aio->pos, aio->len,
- (aio->flag & ~NSC_WRITE) | NSC_READ, &h);
- if (!RDC_SUCCESS(rc)) {
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!_rdc_remote_flush: alloc_buf, index %d, pos %"
- NSC_SZFMT ", len %" NSC_SZFMT ", rc %d",
- aio->index, aio->pos, aio->len, rc);
-#endif
-
- goto failed;
- }
- aio->handle = h;
- aio->handle->sb_user = RDC_NULLBUFREAD;
- }
-
- mutex_enter(qlock);
- if (group->asyncdis) {
- if (group->asyncstall == 0) {
- group->asyncdis = 0;
- }
- aio->iostatus = RDC_IO_CANCELLED;
- mutex_exit(qlock);
- goto failed;
- }
- group->asyncstall++;
- mutex_exit(qlock);
-
-
- if (krdc->remote_index < 0) {
- /*
- * this should be ok, we are flushing, not rev syncing.
- * remote_index could be -1 if we lost a race with
- * resume and the flusher trys to flush an io from
- * another set that has not resumed
- */
- krdc->remote_index = rdc_net_state(krdc->index, CCIO_SLAVE);
- DTRACE_PROBE1(remote_index_negative, int, krdc->remote_index);
-
- }
-
- /*
- * double check for logging, no check in net_write()
- * skip the write if you can, otherwise, if logging
- * avoid clearing the bit .. you don't know whose bit it may
- * also be.
- */
- if (IS_STATE(urdc, RDC_LOGGING) || IS_STATE(urdc, RDC_SYNCING)) {
- aio->iostatus = RDC_IO_CANCELLED;
- mutex_enter(qlock);
- group->asyncstall--;
- mutex_exit(qlock);
- goto failed;
- }
-
- rc = rdc_net_write(krdc->index, krdc->remote_index,
- aio->handle, aio->pos, aio->len, aio->seq, aio->qpos, &netret);
-
- mutex_enter(qlock);
- group->asyncstall--;
- if (group->asyncdis) {
- if (group->asyncstall == 0) {
- group->asyncdis = 0;
- }
- aio->iostatus = RDC_IO_CANCELLED;
- mutex_exit(qlock);
- goto failed;
- }
-
- if (IS_STATE(urdc, RDC_LOGGING) || IS_STATE(urdc, RDC_SYNCING)) {
- mutex_exit(qlock);
- aio->iostatus = RDC_IO_CANCELLED;
- goto failed;
- }
-
- ASSERT(aio->handle);
- if (rc != 0) {
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!_rdc_remote_flush: write, index %d, pos %" NSC_SZFMT
- ", len %" NSC_SZFMT ", "
- "rc %d seq %u group seq %u seqack %u qpos %" NSC_SZFMT,
- aio->index, aio->pos, aio->len, rc, aio->seq,
- group->seq, group->seqack, aio->qpos);
-#endif
- if (rc == ENOLINK) {
- cmn_err(CE_WARN,
- "!Hard timeout detected (%d sec) "
- "on SNDR set %s:%s",
- rdc_rpc_tmout, urdc->secondary.intf,
- urdc->secondary.file);
- }
- mutex_exit(qlock);
- goto failed;
- } else {
- aio->iostatus = RDC_IO_DONE;
- }
-
- if (RDC_IS_DISKQ(group)) {
- /* free locally alloc'd handle */
- if (aio->handle->sb_user == RDC_NULLBUFREAD) {
- (void) nsc_free_buf(aio->handle);
- aio->handle = NULL;
- }
- aio->qhandle->sb_user--;
- if (aio->qhandle->sb_user == 0) {
- (void) _rdc_rsrv_diskq(group);
- rdc_fixlen(aio);
- (void) nsc_free_buf(aio->qhandle);
- aio->qhandle = NULL;
- aio->handle = NULL;
- _rdc_rlse_diskq(group);
- }
-
- } else {
- (void) nsc_free_buf(aio->handle);
- aio->handle = NULL;
- }
-
- mutex_exit(qlock);
-
- _rdc_rlse_devs(krdc, rtype);
-
- if (netret.result == 0) {
- vflags = rdc_get_vflags(urdc);
-
- if (!(vflags & (RDC_BMP_FAILED|RDC_VOL_FAILED|RDC_LOGGING))) {
- RDC_CLR_BITMAP(krdc, aio->pos, aio->len, \
- 0xffffffff, RDC_BIT_BUMP);
-
- if (RDC_IS_DISKQ(krdc->group)) {
- if (!IS_STATE(urdc, RDC_LOGGING)) {
- /* tell queue data has been flushed */
- rdc_clr_iohdr(krdc, aio->qpos);
- } else { /* throw away queue, logging */
- mutex_enter(qlock);
- rdc_dump_iohdrs(q);
- SET_QNXTIO(q, QHEAD(q));
- SET_QCOALBOUNDS(q, QHEAD(q));
- mutex_exit(qlock);
- }
- }
- }
-
- mutex_enter(qlock);
- /*
- * Check to see if the reply has arrived out of
- * order, if so don't update seqack.
- */
- if (!RDC_INFRONT(aio->seq, group->seqack)) {
- group->seqack = aio->seq;
- }
-#ifdef DEBUG
- else {
- rdc_ooreply++;
- }
-#endif
- if (group->asyncstall) {
- cv_broadcast(&group->asyncqcv);
- }
- mutex_exit(qlock);
- } else if (netret.result < 0) {
- aio->iostatus = RDC_IO_FAILED;
- }
-
- /*
- * see if we have any pending async requests we can mark
- * as done.
- */
-
- if (netret.vecdata.vecdata_len) {
- net_pendvec_t *vecp;
- net_pendvec_t *vecpe;
- vecp = netret.vecdata.vecdata_val;
- vecpe = netret.vecdata.vecdata_val + netret.vecdata.vecdata_len;
- while (vecp < vecpe) {
- rdc_k_info_t *krdcp = &rdc_k_info[vecp->pindex];
- rdc_u_info_t *urdcp = &rdc_u_info[vecp->pindex];
- /*
- * we must always still be in the same group.
- */
- ASSERT(krdcp->group == group);
- vflags = rdc_get_vflags(urdcp);
-
- if (!(vflags &
- (RDC_BMP_FAILED|RDC_VOL_FAILED|RDC_LOGGING))) {
- RDC_CLR_BITMAP(krdcp, vecp->apos, vecp->alen, \
- 0xffffffff, RDC_BIT_BUMP);
- if (RDC_IS_DISKQ(krdcp->group)) {
- if (!IS_STATE(urdc, RDC_LOGGING)) {
- /* update queue info */
- rdc_clr_iohdr(krdc, vecp->qpos);
- } else { /* we've gone logging */
- mutex_enter(qlock);
- rdc_dump_iohdrs(q);
- SET_QNXTIO(q, QHEAD(q));
- SET_QCOALBOUNDS(q, QHEAD(q));
- mutex_exit(qlock);
- }
- }
- }
-
- /*
- * see if we can re-start transmission
- */
- mutex_enter(qlock);
- if (!RDC_INFRONT(vecp->seq, group->seqack)) {
- group->seqack = vecp->seq;
- }
-#ifdef DEBUG
- else {
- rdc_ooreply++;
- }
-#endif
- DTRACE_PROBE1(pendvec_return, int, vecp->seq);
-
- if (group->asyncstall) {
- cv_broadcast(&group->asyncqcv);
- }
- mutex_exit(qlock);
- vecp++;
- }
- }
- if (netret.vecdata.vecdata_val)
- kmem_free(netret.vecdata.vecdata_val,
- netret.vecdata.vecdata_len * sizeof (net_pendvec_t));
- return;
-failed:
-
- /* perhaps we have a few threads stuck .. */
- if (group->asyncstall) {
- group->asyncdis = 1;
- cv_broadcast(&group->asyncqcv);
- }
- if (netret.vecdata.vecdata_val)
- kmem_free(netret.vecdata.vecdata_val,
- netret.vecdata.vecdata_len * sizeof (net_pendvec_t));
-
- mutex_enter(qlock);
- if (RDC_IS_DISKQ(group)) {
- /* free locally alloc'd hanlde */
- if ((aio->handle) &&
- (aio->handle->sb_user == RDC_NULLBUFREAD)) {
- (void) nsc_free_buf(aio->handle);
- aio->handle = NULL;
- }
- aio->qhandle->sb_user--;
- if (aio->qhandle->sb_user == 0) {
- (void) _rdc_rsrv_diskq(group);
- rdc_fixlen(aio);
- (void) nsc_free_buf(aio->qhandle);
- aio->qhandle = NULL;
- aio->handle = NULL;
- _rdc_rlse_diskq(group);
- }
- } else {
- if (aio->handle) {
- (void) nsc_free_buf(aio->handle);
- aio->handle = NULL;
- }
- }
- mutex_exit(qlock);
-
- if (reserved) {
- _rdc_rlse_devs(krdc, rtype);
- }
-
- if ((waitq && krdc->io_kstats) && (!RDC_IS_DISKQ(krdc->group))) {
- mutex_enter(krdc->io_kstats->ks_lock);
- kstat_waitq_exit(KSTAT_IO_PTR(krdc->io_kstats));
- mutex_exit(krdc->io_kstats->ks_lock);
- }
-
- /* make sure that the bit is still set */
- RDC_CHECK_BIT(krdc, aio->pos, aio->len);
-
- if (aio->iostatus != RDC_IO_CANCELLED)
- aio->iostatus = RDC_IO_FAILED;
-}
-
-
-/*
- * rdc_drain_disk_queue
- * drain the async network queue for the whole group. Bail out if nothing
- * happens in 20 sec
- * returns -1 if it bails before the queues are drained.
- */
-#define NUM_RETRIES 15 /* Number of retries to wait if no progress */
-int
-rdc_drain_disk_queue(int index)
-{
- rdc_k_info_t *krdc = &rdc_k_info[index];
- volatile rdc_group_t *group;
- volatile disk_queue *diskq;
- int threads, counter;
- long blocks;
-
- /* Sanity checking */
- if (index > rdc_max_sets)
- return (0);
-
- /*
- * If there is no group or diskq configured, we can leave now
- */
- if (!(group = krdc->group) || !(diskq = &group->diskq))
- return (0);
-
- /*
- * No need to wait if EMPTY and threads are gone
- */
- counter = 0;
- while (!QEMPTY(diskq) || group->rdc_thrnum) {
-
- /*
- * Capture counters to determine if progress is being made
- */
- blocks = QBLOCKS(diskq);
- threads = group->rdc_thrnum;
-
- /*
- * Wait
- */
- delay(HZ);
-
- /*
- * Has the group or disk queue gone away while delayed?
- */
- if (!(group = krdc->group) || !(diskq = &group->diskq))
- return (0);
-
- /*
- * Are we still seeing progress?
- */
- if (blocks == QBLOCKS(diskq) && threads == group->rdc_thrnum) {
- /*
- * No progress seen, increment retry counter
- */
- if (counter++ > NUM_RETRIES) {
- return (-1);
- }
- } else {
- /*
- * Reset counter, as we've made progress
- */
- counter = 0;
- }
- }
-
- return (0);
-}
-
-/*
- * decide what needs to be drained, disk or core
- * and drain it
- */
-int
-rdc_drain_queue(int index)
-{
- rdc_k_info_t *krdc = &rdc_k_info[index];
- rdc_group_t *group = krdc->group;
-
- if (!group)
- return (0);
-
- if (RDC_IS_DISKQ(group))
- return (rdc_drain_disk_queue(index));
- if (RDC_IS_MEMQ(group))
- return (rdc_drain_net_queue(index));
- /* oops.. */
-#ifdef DEBUG
- cmn_err(CE_WARN, "!rdc_drain_queue: "
- "attempting drain of unknown Q type");
-#endif
- return (0);
-}
-
-/*
- * rdc_drain_net_queue
- * drain the async network queue for the whole group. Bail out if nothing
- * happens in 20 sec
- * returns -1 if it bails before the queues are drained.
- */
-int
-rdc_drain_net_queue(int index)
-{
- rdc_k_info_t *krdc = &rdc_k_info[index];
- volatile net_queue *q;
- int bail = 20; /* bail out in about 20 secs */
- nsc_size_t blocks;
-
- /* Sanity checking */
- if (index > rdc_max_sets)
- return (0);
- if (!krdc->group)
- return (0);
- /* LINTED */
- if (!(q = &krdc->group->ra_queue))
- return (0);
-
- /* CONSTCOND */
- while (1) {
-
- if (((volatile rdc_aio_t *)q->net_qhead == NULL) &&
- (krdc->group->rdc_thrnum == 0)) {
- break;
- }
-
- blocks = q->blocks;
-
- q = (volatile net_queue *)&krdc->group->ra_queue;
-
- if ((blocks == q->blocks) &&
- (--bail <= 0)) {
- break;
- }
-
- delay(HZ);
- }
-
- if (bail <= 0)
- return (-1);
-
- return (0);
-}
-
-/*
- * rdc_dump_queue
- * We want to release all the blocks currently on the network flushing queue
- * We already have them logged in the bitmap.
- */
-void
-rdc_dump_queue(int index)
-{
- rdc_k_info_t *krdc = &rdc_k_info[index];
- rdc_aio_t *aio;
- net_queue *q;
- rdc_group_t *group;
- disk_queue *dq;
- kmutex_t *qlock;
-
- group = krdc->group;
-
- q = &group->ra_queue;
- dq = &group->diskq;
-
- /*
- * gotta have both locks here for diskq
- */
-
- if (RDC_IS_DISKQ(group)) {
- mutex_enter(&q->net_qlock);
- if (q->qfill_sleeping == RDC_QFILL_AWAKE) {
- int tries = 3;
-#ifdef DEBUG_DISKQ
- cmn_err(CE_NOTE,
- "!dumpq sending diskq->memq flusher to sleep");
-#endif
- q->qfflags |= RDC_QFILLSLEEP;
- mutex_exit(&q->net_qlock);
- while (q->qfill_sleeping == RDC_QFILL_AWAKE && tries--)
- delay(5);
- mutex_enter(&q->net_qlock);
- }
- }
-
- if (RDC_IS_DISKQ(group)) {
- qlock = &dq->disk_qlock;
- (void) _rdc_rsrv_diskq(group);
- } else {
- qlock = &q->net_qlock;
- }
-
- mutex_enter(qlock);
-
- group->seq = RDC_NEWSEQ; /* reset the sequence number */
- group->seqack = RDC_NEWSEQ;
-
- /* if the q is on disk, dump the q->iohdr chain */
- if (RDC_IS_DISKQ(group)) {
- rdc_dump_iohdrs(dq);
-
- /* back up the nxtio pointer */
- SET_QNXTIO(dq, QHEAD(dq));
- SET_QCOALBOUNDS(dq, QHEAD(dq));
- }
-
- while (q->net_qhead) {
- rdc_k_info_t *tmpkrdc;
- aio = q->net_qhead;
- tmpkrdc = &rdc_k_info[aio->index];
-
- if (RDC_IS_DISKQ(group)) {
- aio->qhandle->sb_user--;
- if (aio->qhandle->sb_user == 0) {
- rdc_fixlen(aio);
- (void) nsc_free_buf(aio->qhandle);
- aio->qhandle = NULL;
- aio->handle = NULL;
- }
- } else {
- if (aio->handle) {
- (void) nsc_free_buf(aio->handle);
- aio->handle = NULL;
- }
- }
-
- q->net_qhead = aio->next;
- RDC_CHECK_BIT(tmpkrdc, aio->pos, aio->len);
-
- kmem_free(aio, sizeof (*aio));
- if (tmpkrdc->io_kstats && !RDC_IS_DISKQ(group)) {
- mutex_enter(tmpkrdc->io_kstats->ks_lock);
- kstat_waitq_exit(KSTAT_IO_PTR(tmpkrdc->io_kstats));
- mutex_exit(tmpkrdc->io_kstats->ks_lock);
- }
-
- }
-
- q->net_qtail = NULL;
- q->blocks = 0;
- q->nitems = 0;
-
- /*
- * See if we have stalled threads.
- */
-done:
- if (group->asyncstall) {
- group->asyncdis = 1;
- cv_broadcast(&group->asyncqcv);
- }
- mutex_exit(qlock);
- if (RDC_IS_DISKQ(group)) {
- mutex_exit(&q->net_qlock);
- _rdc_rlse_diskq(group);
- }
-
-}
-
-
-/*
- * rdc_clnt_get
- * Get a CLIENT handle and cache it
- */
-
-static int
-rdc_clnt_get(rdc_srv_t *svp, rpcvers_t vers, struct chtab **rch, CLIENT **clp)
-{
- uint_t max_msgsize;
- int retries;
- int ret;
- struct cred *cred;
- int num_clnts = 0;
- register struct chtab *ch;
- struct chtab **plistp;
- CLIENT *client = 0;
-
- if (rch) {
- *rch = 0;
- }
-
- if (clp) {
- *clp = 0;
- }
-
- retries = 6; /* Never used for COTS in Solaris */
- cred = ddi_get_cred();
- max_msgsize = RDC_RPC_MAX;
-
- mutex_enter(&rdc_clnt_lock);
-
- ch = rdc_chtable;
- plistp = &rdc_chtable;
-
- /* find the right ch_list chain */
-
- for (ch = rdc_chtable; ch != NULL; ch = ch->ch_next) {
- if (ch->ch_prog == RDC_PROGRAM &&
- ch->ch_vers == vers &&
- ch->ch_dev == svp->ri_knconf->knc_rdev &&
- ch->ch_protofmly != NULL &&
- strcmp(ch->ch_protofmly,
- svp->ri_knconf->knc_protofmly) == 0) {
- /* found the correct chain to walk */
- break;
- }
- plistp = &ch->ch_next;
- }
-
- if (ch != NULL) {
- /* walk the ch_list and try and find a free client */
-
- for (num_clnts = 0; ch != NULL; ch = ch->ch_list, num_clnts++) {
- if (ch->ch_inuse == FALSE) {
- /* suitable handle to reuse */
- break;
- }
- plistp = &ch->ch_list;
- }
- }
-
- if (ch == NULL && num_clnts >= MAXCLIENTS) {
- /* alloc a temporary handle and return */
-
- rdc_clnt_toomany++;
- mutex_exit(&rdc_clnt_lock);
-
- ret = clnt_tli_kcreate(svp->ri_knconf, &(svp->ri_addr),
- RDC_PROGRAM, vers, max_msgsize, retries, cred, &client);
-
- if (ret != 0) {
- cmn_err(CE_NOTE,
- "!rdc_call: tli_kcreate failed %d", ret);
- return (ret);
- }
-
- *rch = 0;
- *clp = client;
- (void) CLNT_CONTROL(client, CLSET_PROGRESS, NULL);
- return (ret);
- }
-
- if (ch != NULL) {
- /* reuse a cached handle */
-
- ch->ch_inuse = TRUE;
- ch->ch_timesused++;
- mutex_exit(&rdc_clnt_lock);
-
- *rch = ch;
-
- if (ch->ch_client == NULL) {
- ret = clnt_tli_kcreate(svp->ri_knconf, &(svp->ri_addr),
- RDC_PROGRAM, vers, max_msgsize, retries,
- cred, &ch->ch_client);
- if (ret != 0) {
- ch->ch_inuse = FALSE;
- return (ret);
- }
-
- (void) CLNT_CONTROL(ch->ch_client, CLSET_PROGRESS,
- NULL);
- *clp = ch->ch_client;
-
- return (0);
- } else {
- /*
- * Consecutive calls to CLNT_CALL() on the same client handle
- * get the same transaction ID. We want a new xid per call,
- * so we first reinitialise the handle.
- */
- (void) clnt_tli_kinit(ch->ch_client, svp->ri_knconf,
- &(svp->ri_addr), max_msgsize, retries, cred);
-
- *clp = ch->ch_client;
- return (0);
- }
- }
-
- /* create new handle and cache it */
- ch = (struct chtab *)kmem_zalloc(sizeof (*ch), KM_SLEEP);
-
- if (ch) {
- ch->ch_inuse = TRUE;
- ch->ch_prog = RDC_PROGRAM;
- ch->ch_vers = vers;
- ch->ch_dev = svp->ri_knconf->knc_rdev;
- ch->ch_protofmly = (char *)kmem_zalloc(
- strlen(svp->ri_knconf->knc_protofmly)+1, KM_SLEEP);
- if (ch->ch_protofmly)
- (void) strcpy(ch->ch_protofmly,
- svp->ri_knconf->knc_protofmly);
- *plistp = ch;
- }
-
- mutex_exit(&rdc_clnt_lock);
-
- ret = clnt_tli_kcreate(svp->ri_knconf, &(svp->ri_addr),
- RDC_PROGRAM, vers, max_msgsize, retries, cred, clp);
-
- if (ret != 0) {
- if (ch)
- ch->ch_inuse = FALSE;
- cmn_err(CE_NOTE, "!rdc_call: tli_kcreate failed %d", ret);
- return (ret);
- }
-
- *rch = ch;
- if (ch)
- ch->ch_client = *clp;
-
- (void) CLNT_CONTROL(*clp, CLSET_PROGRESS, NULL);
-
- return (ret);
-}
-
-
-long rdc_clnt_count = 0;
-
-/*
- * rdc_clnt_call
- * Arguments:
- * rdc_srv_t *svp - rdc servinfo
- * rpcproc_t proc; - rpcid
- * rpcvers_t vers; - protocol version
- * xdrproc_t xargs;- xdr function
- * caddr_t argsp;- args to xdr function
- * xdrproc_t xres;- xdr function
- * caddr_t resp;- args to xdr function
- * struct timeval timeout;
- * Performs RPC client call using specific protocol and version
- */
-
-int
-rdc_clnt_call(rdc_srv_t *svp, rpcproc_t proc, rpcvers_t vers,
- xdrproc_t xargs, caddr_t argsp,
- xdrproc_t xres, caddr_t resp, struct timeval *timeout)
-{
- CLIENT *rh = NULL;
- int err;
- int tries = 0;
- struct chtab *ch = NULL;
-
- err = rdc_clnt_get(svp, vers, &ch, &rh);
- if (err || !rh)
- return (err);
-
- do {
- DTRACE_PROBE3(rdc_clnt_call_1,
- CLIENT *, rh, rpcproc_t, proc, xdrproc_t, xargs);
-
- err = cl_call_sig(rh, proc, xargs, argsp, xres, resp, *timeout);
-
- DTRACE_PROBE1(rdc_clnt_call_end, int, err);
-
- switch (err) {
- case RPC_SUCCESS: /* bail now */
- goto done;
- case RPC_INTR: /* No recovery from this */
- goto done;
- case RPC_PROGVERSMISMATCH:
- goto done;
- case RPC_TLIERROR:
- /* fall thru */
- case RPC_XPRTFAILED:
- /* Delay here to err on side of caution */
- /* fall thru */
- case RPC_VERSMISMATCH:
-
- default:
- if (IS_UNRECOVERABLE_RPC(err)) {
- goto done;
- }
- tries++;
- /*
- * The call is in progress (over COTS)
- * Try the CLNT_CALL again, but don't
- * print a noisy error message
- */
- if (err == RPC_INPROGRESS)
- break;
- cmn_err(CE_NOTE, "!SNDR client: err %d %s",
- err, clnt_sperrno(err));
- }
- } while (tries && (tries < 2));
-done:
- ++rdc_clnt_count;
- rdc_clnt_free(ch, rh);
- return (err);
-}
-
-
-/*
- * Call an rpc from the client side, not caring which protocol is used.
- */
-int
-rdc_clnt_call_any(rdc_srv_t *svp, rdc_if_t *ip, rpcproc_t proc,
- xdrproc_t xargs, caddr_t argsp,
- xdrproc_t xres, caddr_t resp, struct timeval *timeout)
-{
- rpcvers_t vers;
- int rc;
-
- if (ip != NULL) {
- vers = ip->rpc_version;
- } else {
- vers = RDC_VERS_MAX;
- }
-
- do {
- rc = rdc_clnt_call(svp, proc, vers, xargs, argsp,
- xres, resp, timeout);
-
- if (rc == RPC_PROGVERSMISMATCH) {
- /*
- * Downgrade and try again.
- */
- vers--;
- }
- } while ((vers >= RDC_VERS_MIN) && (rc == RPC_PROGVERSMISMATCH));
-
- if ((rc == 0) && (ip != NULL) && (vers != ip->rpc_version)) {
- mutex_enter(&rdc_ping_lock);
- ip->rpc_version = vers;
- mutex_exit(&rdc_ping_lock);
- }
-
- return (rc);
-}
-
-/*
- * Call an rpc from the client side, starting with protocol specified
- */
-int
-rdc_clnt_call_walk(rdc_k_info_t *krdc, rpcproc_t proc, xdrproc_t xargs,
- caddr_t argsp, xdrproc_t xres, caddr_t resp,
- struct timeval *timeout)
-{
- int rc;
- rpcvers_t vers;
- rdc_srv_t *svp = krdc->lsrv;
- rdc_if_t *ip = krdc->intf;
- vers = krdc->rpc_version;
-
- do {
- rc = rdc_clnt_call(svp, proc, vers, xargs, argsp,
- xres, resp, timeout);
-
- if (rc == RPC_PROGVERSMISMATCH) {
- /*
- * Downgrade and try again.
- */
- vers--;
- }
- } while ((vers >= RDC_VERS_MIN) && (rc == RPC_PROGVERSMISMATCH));
-
- if ((rc == 0) && (ip != NULL) && (vers != ip->rpc_version)) {
- mutex_enter(&rdc_ping_lock);
- ip->rpc_version = vers;
- mutex_exit(&rdc_ping_lock);
- }
-
- return (rc);
-}
-
-/*
- * rdc_clnt_free
- * Free a client structure into the cache, or if this was a temporary
- * handle allocated above MAXCLIENTS, destroy it.
- */
-static void
-rdc_clnt_free(struct chtab *ch, CLIENT *clp)
-{
- if (ch != NULL) {
- /* cached client, just clear inuse flag and return */
- ASSERT(ch->ch_client == clp);
- ch->ch_inuse = FALSE;
- return;
- }
-
- /* temporary handle allocated above MAXCLIENTS, so destroy it */
-
- if (clp->cl_auth) {
- AUTH_DESTROY(clp->cl_auth);
- clp->cl_auth = 0;
- }
-
- CLNT_DESTROY(clp);
-}
-
-
-/*
- * _rdc_clnt_destroy
- * Free a chain (ch_list or ch_next) of cached clients
- */
-static int
-_rdc_clnt_destroy(struct chtab **p, const int list)
-{
- struct chtab *ch;
- int leak = 0;
-
- if (!p)
- return (0);
-
- while (*p != NULL) {
- ch = *p;
-
- /*
- * unlink from the chain
- * - this leaks the client if it was inuse
- */
-
- *p = list ? ch->ch_list : ch->ch_next;
-
- if (!ch->ch_inuse) {
- /* unused client - destroy it */
-
- if (ch->ch_client) {
- if (ch->ch_client->cl_auth) {
- AUTH_DESTROY(ch->ch_client->cl_auth);
- ch->ch_client->cl_auth = 0;
- }
-
- CLNT_DESTROY(ch->ch_client);
- ch->ch_client = 0;
- }
-
- if (ch->ch_protofmly)
- kmem_free(ch->ch_protofmly,
- strlen(ch->ch_protofmly)+1);
-
- kmem_free(ch, sizeof (*ch));
- } else {
- /* remember client leak */
- leak++;
- }
- }
-
- return (leak);
-}
-
-
-/*
- * rdc_clnt_destroy
- * Free client caching table on unconfigure
- */
-void
-rdc_clnt_destroy(void)
-{
- struct chtab *ch;
- int leak = 0;
-
- mutex_enter(&rdc_clnt_lock);
-
- /* destroy each ch_list chain */
-
- for (ch = rdc_chtable; ch; ch = ch->ch_next) {
- leak += _rdc_clnt_destroy(&ch->ch_list, 1);
- }
-
- /* destroy the main ch_next chain */
- leak += _rdc_clnt_destroy(&rdc_chtable, 0);
-
- if (leak) {
- /* we are about to leak clients */
- cmn_err(CE_WARN,
- "!rdc_clnt_destroy: leaking %d inuse clients", leak);
- }
-
- mutex_exit(&rdc_clnt_lock);
-}
-
-#ifdef DEBUG
-/*
- * Function to send an asynchronous net_data6 request
- * direct to a server to allow the generation of
- * out of order requests for ZatoIchi tests.
- */
-int
-rdc_async6(void *arg, int mode, int *rvp)
-{
- int index;
- rdc_async6_t async6;
- struct net_data6 data6;
- rdc_k_info_t *krdc;
- rdc_u_info_t *urdc;
- char *data;
- int datasz;
- char *datap;
- int rc;
- struct timeval t;
- struct netwriteres netret;
- int i;
-
- rc = 0;
- *rvp = 0;
- /*
- * copyin the user's arguments.
- */
- if (ddi_copyin(arg, &async6, sizeof (async6), mode) < 0) {
- return (EFAULT);
- }
-
- /*
- * search by the secondary host and file.
- */
- mutex_enter(&rdc_conf_lock);
- for (index = 0; index < rdc_max_sets; index++) {
- urdc = &rdc_u_info[index];
- krdc = &rdc_k_info[index];
-
- if (!IS_CONFIGURED(krdc))
- continue;
- if (!IS_ENABLED(urdc))
- continue;
- if (!IS_ASYNC(urdc))
- continue;
- if (krdc->rpc_version < RDC_VERSION6)
- continue;
-
- if ((strncmp(urdc->secondary.intf, async6.sechost,
- MAX_RDC_HOST_SIZE) == 0) &&
- (strncmp(urdc->secondary.file, async6.secfile,
- NSC_MAXPATH) == 0)) {
- break;
- }
- }
- mutex_exit(&rdc_conf_lock);
- if (index >= rdc_max_sets) {
- return (ENOENT);
- }
-
- if (async6.spos != -1) {
- if ((async6.spos < async6.pos) ||
- ((async6.spos + async6.slen) >
- (async6.pos + async6.len))) {
- cmn_err(CE_WARN, "!Sub task not within range "
- "start %d length %d sub start %d sub length %d",
- async6.pos, async6.len, async6.spos, async6.slen);
- return (EIO);
- }
- }
-
- datasz = FBA_SIZE(1);
- data = kmem_alloc(datasz, KM_SLEEP);
- datap = data;
- while (datap < &data[datasz]) {
- /* LINTED */
- *datap++ = async6.pat;
- }
-
- /*
- * Fill in the net databuffer prior to transmission.
- */
-
- data6.local_cd = krdc->index;
- if (krdc->remote_index == -1) {
- cmn_err(CE_WARN, "!Remote index not known");
- kmem_free(data, datasz);
- return (EIO);
- } else {
- data6.cd = krdc->remote_index;
- }
- data6.pos = async6.pos;
- data6.len = async6.len;
- data6.flag = 0;
- data6.idx = async6.idx;
- data6.seq = async6.seq;
-
- if (async6.spos == -1) {
- data6.sfba = async6.pos;
- data6.nfba = async6.len;
- data6.endoblk = 1;
-
- } else {
- data6.sfba = async6.spos;
- data6.nfba = async6.slen;
- data6.endoblk = async6.endind;
- }
-
- data6.data.data_len = datasz;
- data6.data.data_val = data;
-
- t.tv_sec = rdc_rpc_tmout;
- t.tv_usec = 0;
-
- netret.vecdata.vecdata_val = NULL;
- netret.vecdata.vecdata_len = 0;
-
-
- rc = rdc_clnt_call(krdc->lsrv, RDCPROC_WRITE6, krdc->rpc_version,
- xdr_net_data6, (char *)&data6, xdr_netwriteres, (char *)&netret,
- &t);
-
- kmem_free(data, datasz);
- if (rc == 0) {
- if (netret.result < 0) {
- rc = -netret.result;
- }
- cmn_err(CE_NOTE, "!async6: seq %u result %d index %d "
- "pendcnt %d",
- netret.seq, netret.result, netret.index,
- netret.vecdata.vecdata_len);
- for (i = 0; i < netret.vecdata.vecdata_len; i++) {
- net_pendvec_t pvec;
- bcopy(netret.vecdata.vecdata_val + i, &pvec,
- sizeof (net_pendvec_t));
- cmn_err(CE_NOTE, "!Seq %u pos %llu len %llu",
- pvec.seq, (unsigned long long)pvec.apos,
- (unsigned long long)pvec.alen);
- }
- if (netret.vecdata.vecdata_val)
- kmem_free(netret.vecdata.vecdata_val,
- netret.vecdata.vecdata_len *
- sizeof (net_pendvec_t));
- } else {
- cmn_err(CE_NOTE, "!async6: rpc call failed %d", rc);
- }
- *rvp = netret.index;
- return (rc);
-}
-
-/*
- * Function to send an net_read6 request
- * direct to a server to allow the generation of
- * read requests.
- */
-int
-rdc_readgen(void *arg, int mode, int *rvp)
-{
- int index;
- rdc_readgen_t readgen;
- rdc_readgen32_t readgen32;
- struct rread6 read6;
- struct rread read5;
- rdc_k_info_t *krdc;
- int ret;
- struct timeval t;
- struct rdcrdresult rr;
- int err;
-
- *rvp = 0;
- rr.rr_bufsize = 0; /* rpc data buffer length (bytes) */
- rr.rr_data = NULL; /* rpc data buffer */
- if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
- if (ddi_copyin(arg, &readgen32, sizeof (readgen32), mode)) {
- return (EFAULT);
- }
- (void) strncpy(readgen.sechost, readgen32.sechost,
- MAX_RDC_HOST_SIZE);
- (void) strncpy(readgen.secfile, readgen32.secfile, NSC_MAXPATH);
- readgen.len = readgen32.len;
- readgen.pos = readgen32.pos;
- readgen.idx = readgen32.idx;
- readgen.flag = readgen32.flag;
- readgen.data = (void *)(unsigned long)readgen32.data;
- readgen.rpcversion = readgen32.rpcversion;
- } else {
- if (ddi_copyin(arg, &readgen, sizeof (readgen), mode)) {
- return (EFAULT);
- }
- }
- switch (readgen.rpcversion) {
- case 5:
- case 6:
- break;
- default:
- return (EINVAL);
- }
-
- mutex_enter(&rdc_conf_lock);
- index = rdc_lookup_byhostdev(readgen.sechost, readgen.secfile);
- if (index >= 0) {
- krdc = &rdc_k_info[index];
- }
- if (index < 0 || (krdc->type_flag & RDC_DISABLEPEND)) {
- mutex_exit(&rdc_conf_lock);
- return (ENODEV);
- }
- /*
- * we should really call setbusy here.
- */
- mutex_exit(&rdc_conf_lock);
-
- t.tv_sec = rdc_rpc_tmout;
- t.tv_usec = 0;
- if (krdc->remote_index == -1) {
- cmn_err(CE_WARN, "!Remote index not known");
- ret = EIO;
- goto out;
- }
- if (readgen.rpcversion == 6) {
- read6.cd = krdc->remote_index;
- read6.len = readgen.len;
- read6.pos = readgen.pos;
- read6.idx = readgen.idx;
- read6.flag = readgen.flag;
- } else {
- read5.cd = krdc->remote_index;
- read5.len = readgen.len;
- read5.pos = readgen.pos;
- read5.idx = readgen.idx;
- read5.flag = readgen.flag;
- }
-
- if (readgen.flag & RDC_RREAD_START) {
- if (readgen.rpcversion == 6) {
- err = rdc_clnt_call(krdc->lsrv, RDCPROC_READ6,
- RDC_VERSION6, xdr_rread6, (char *)&read6,
- xdr_int, (char *)&ret, &t);
- } else {
- err = rdc_clnt_call(krdc->lsrv, RDCPROC_READ5,
- RDC_VERSION5, xdr_rread, (char *)&read5,
- xdr_int, (char *)&ret, &t);
- }
- if (err == 0) {
- *rvp = ret;
- ret = 0;
- } else {
- ret = EPROTO;
- }
- } else {
- if (readgen.rpcversion == 6) {
- err = rdc_clnt_call(krdc->lsrv, RDCPROC_READ6,
- RDC_VERSION6, xdr_rread6, (char *)&read6,
- xdr_rdresult, (char *)&rr, &t);
- } else {
- err = rdc_clnt_call(krdc->lsrv, RDCPROC_READ5,
- RDC_VERSION5, xdr_rread, (char *)&read5,
- xdr_rdresult, (char *)&rr, &t);
- }
- if (err == 0) {
- if (rr.rr_status != RDC_OK) {
- ret = EIO;
- goto out;
- }
- *rvp = rr.rr_bufsize;
- if (ddi_copyout(rr.rr_data, readgen.data,
- rr.rr_bufsize, mode) != 0) {
- ret = EFAULT;
- goto out;
- }
- ret = 0;
- } else {
- ret = EPROTO;
- goto out;
- }
- }
-out:
- if (rr.rr_data) {
- kmem_free(rr.rr_data, rr.rr_bufsize);
- }
- return (ret);
-}
-
-
-#endif
diff --git a/usr/src/uts/common/avs/ns/rdc/rdc_clnt.h b/usr/src/uts/common/avs/ns/rdc/rdc_clnt.h
deleted file mode 100644
index d58a0bdc8f..0000000000
--- a/usr/src/uts/common/avs/ns/rdc/rdc_clnt.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _RDC_CLNT_H
-#define _RDC_CLNT_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern kmutex_t rdc_clnt_lock;
-
-struct chtab {
- uint_t ch_timesused;
- bool_t ch_inuse;
- ulong_t ch_prog;
- rpcvers_t ch_vers;
- dev_t ch_dev;
- char *ch_protofmly;
- CLIENT *ch_client;
- struct chtab *ch_next; /* chain of different prog/vers/dev/proto */
- struct chtab *ch_list; /* chain of similar clients */
-};
-
-#define MAXCLIENTS 64
-
-extern int rdc_clnt_call(rdc_srv_t *, rpcproc_t, rpcvers_t, xdrproc_t,
- caddr_t, xdrproc_t, caddr_t, struct timeval *);
-extern int rdc_clnt_call_any(rdc_srv_t *, rdc_if_t *, rpcproc_t,
- xdrproc_t, caddr_t, xdrproc_t, caddr_t,
- struct timeval *);
-extern int rdc_clnt_call_walk(rdc_k_info_t *, rpcproc_t, xdrproc_t, caddr_t,
- xdrproc_t, caddr_t, struct timeval *);
-
-extern int rdc_rpc_tmout;
-
-extern int rdc_aio_coalesce(rdc_aio_t *, rdc_aio_t *);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _RDC_CLNT_H */
diff --git a/usr/src/uts/common/avs/ns/rdc/rdc_dev.c b/usr/src/uts/common/avs/ns/rdc/rdc_dev.c
deleted file mode 100644
index 7957999c59..0000000000
--- a/usr/src/uts/common/avs/ns/rdc/rdc_dev.c
+++ /dev/null
@@ -1,3019 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-
-#include <sys/types.h>
-#include <sys/ksynch.h>
-#include <sys/kmem.h>
-#include <sys/errno.h>
-#include <sys/cmn_err.h>
-#include <sys/debug.h>
-#include <sys/cred.h>
-#include <sys/file.h>
-#include <sys/ddi.h>
-#include <sys/nsc_thread.h>
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_errors.h>
-
-#include <sys/unistat/spcs_s_k.h>
-#ifdef DS_DDICT
-#include "../contract.h"
-#endif
-
-#include <sys/nsctl/nsctl.h>
-
-#include <sys/sdt.h> /* dtrace is S10 or later */
-
-#include "rdc.h"
-#include "rdc_io.h"
-#include "rdc_bitmap.h"
-
-/*
- * Remote Dual Copy
- *
- * This file contains the nsctl io provider functionality for RDC.
- *
- * RDC is implemented as a simple filter module that pushes itself between
- * user (SIMCKD, STE, etc.) and SDBC.
- */
-
-
-static int _rdc_open_count;
-int rdc_eio_nobmp = 0;
-
-nsc_io_t *_rdc_io_hc;
-static nsc_io_t *_rdc_io_hr;
-static nsc_def_t _rdc_fd_def[], _rdc_io_def[], _rdc_ior_def[];
-
-void _rdc_deinit_dev();
-int rdc_diskq_enqueue(rdc_k_info_t *, rdc_aio_t *);
-extern void rdc_unintercept_diskq(rdc_group_t *);
-rdc_aio_t *rdc_aio_tbuf_get(void *, void *, int, int, int, int, int);
-
-static nsc_buf_t *_rdc_alloc_handle(void (*)(), void (*)(),
- void (*)(), rdc_fd_t *);
-static int _rdc_free_handle(rdc_buf_t *, rdc_fd_t *);
-
-#ifdef DEBUG
-int rdc_overlap_cnt;
-int rdc_overlap_hnd_cnt;
-#endif
-
-static rdc_info_dev_t *rdc_devices;
-
-extern int _rdc_rsrv_diskq(rdc_group_t *group);
-extern void _rdc_rlse_diskq(rdc_group_t *group);
-
-/*
- * _rdc_init_dev
- * Initialise the io provider.
- */
-
-int
-_rdc_init_dev()
-{
- _rdc_io_hc = nsc_register_io("rdc-high-cache",
- NSC_RDCH_ID|NSC_REFCNT|NSC_FILTER, _rdc_io_def);
- if (_rdc_io_hc == NULL)
- cmn_err(CE_WARN, "!rdc: nsc_register_io (high, cache) failed.");
-
- _rdc_io_hr = nsc_register_io("rdc-high-raw",
- NSC_RDCHR_ID|NSC_REFCNT|NSC_FILTER, _rdc_ior_def);
- if (_rdc_io_hr == NULL)
- cmn_err(CE_WARN, "!rdc: nsc_register_io (high, raw) failed.");
-
- if (!_rdc_io_hc || !_rdc_io_hr) {
- _rdc_deinit_dev();
- return (ENOMEM);
- }
-
- return (0);
-}
-
-
-/*
- * _rdc_deinit_dev
- * De-initialise the io provider.
- *
- */
-
-void
-_rdc_deinit_dev()
-{
- int rc;
-
- if (_rdc_io_hc) {
- if ((rc = nsc_unregister_io(_rdc_io_hc, 0)) != 0)
- cmn_err(CE_WARN,
- "!rdc: nsc_unregister_io (high, cache) failed: %d",
- rc);
- }
-
- if (_rdc_io_hr) {
- if ((rc = nsc_unregister_io(_rdc_io_hr, 0)) != 0)
- cmn_err(CE_WARN,
- "!rdc: nsc_unregister_io (high, raw) failed: %d",
- rc);
- }
-}
-
-
-/*
- * rdc_idev_open
- * - Open the nsctl file descriptors for the data devices.
- *
- * Must be called with rdc_conf_lock held.
- * id_sets is protected by rdc_conf_lock.
- */
-static rdc_info_dev_t *
-rdc_idev_open(rdc_k_info_t *krdc, char *pathname, int *rc)
-{
- rdc_info_dev_t *dp;
-
- ASSERT(MUTEX_HELD(&rdc_conf_lock));
-
- for (dp = rdc_devices; dp; dp = dp->id_next) {
- if (dp->id_cache_dev.bi_fd &&
- strcmp(pathname, nsc_pathname(dp->id_cache_dev.bi_fd)) == 0)
- break;
- }
-
- if (!dp) {
- dp = kmem_zalloc(sizeof (*dp), KM_SLEEP);
- if (!dp)
- return (NULL);
-
- dp->id_cache_dev.bi_krdc = krdc;
- dp->id_cache_dev.bi_fd = nsc_open(pathname,
- NSC_RDCHR_ID|NSC_RDWR|NSC_DEVICE,
- _rdc_fd_def, (blind_t)&dp->id_cache_dev, rc);
- if (!dp->id_cache_dev.bi_fd) {
- kmem_free(dp, sizeof (*dp));
- return (NULL);
- }
-
- dp->id_raw_dev.bi_krdc = krdc;
- dp->id_raw_dev.bi_fd = nsc_open(pathname,
- NSC_RDCHR_ID|NSC_RDWR|NSC_DEVICE,
- _rdc_fd_def, (blind_t)&dp->id_raw_dev, rc);
- if (!dp->id_raw_dev.bi_fd) {
- (void) nsc_close(dp->id_cache_dev.bi_fd);
- kmem_free(dp, sizeof (*dp));
- return (NULL);
- }
-
- mutex_init(&dp->id_rlock, NULL, MUTEX_DRIVER, NULL);
- cv_init(&dp->id_rcv, NULL, CV_DRIVER, NULL);
-
- dp->id_next = rdc_devices;
- rdc_devices = dp;
- }
-
- dp->id_sets++;
- return (dp);
-}
-
-
-/*
- * rdc_idev_close
- * - Close the nsctl file descriptors for the data devices.
- *
- * Must be called with rdc_conf_lock and dp->id_rlock held.
- * Will release dp->id_rlock before returning.
- *
- * id_sets is protected by rdc_conf_lock.
- */
-static void
-rdc_idev_close(rdc_k_info_t *krdc, rdc_info_dev_t *dp)
-{
- rdc_info_dev_t **dpp;
-#ifdef DEBUG
- int count = 0;
-#endif
-
- ASSERT(MUTEX_HELD(&rdc_conf_lock));
- ASSERT(MUTEX_HELD(&dp->id_rlock));
-
- dp->id_sets--;
- if (dp->id_sets > 0) {
- mutex_exit(&dp->id_rlock);
- return;
- }
-
- /* external references must have gone */
- ASSERT((krdc->c_ref + krdc->r_ref + krdc->b_ref) == 0);
-
- /* unlink from chain */
-
- for (dpp = &rdc_devices; *dpp; dpp = &((*dpp)->id_next)) {
- if (*dpp == dp) {
- /* unlink */
- *dpp = dp->id_next;
- break;
- }
- }
-
- /*
- * Wait for all reserves to go away - the rpc server is
- * running asynchronously with this close, and so we
- * have to wait for it to spot that the krdc is !IS_ENABLED()
- * and throw away the nsc_buf_t's that it has allocated
- * and release the device.
- */
-
- while (IS_CRSRV(krdc) || IS_RRSRV(krdc)) {
-#ifdef DEBUG
- if (!(++count % 16)) {
- cmn_err(CE_NOTE,
- "!_rdc_idev_close(%s): waiting for nsc_release",
- rdc_u_info[krdc->index].primary.file);
- }
- if (count > (16*20)) {
- /* waited for 20 seconds - too long - panic */
- cmn_err(CE_PANIC,
- "!_rdc_idev_close(%s, %p): lost nsc_release",
- rdc_u_info[krdc->index].primary.file, (void *)krdc);
- }
-#endif
- mutex_exit(&dp->id_rlock);
- delay(HZ>>4);
- mutex_enter(&dp->id_rlock);
- }
-
- if (dp->id_cache_dev.bi_fd) {
- (void) nsc_close(dp->id_cache_dev.bi_fd);
- dp->id_cache_dev.bi_fd = NULL;
- }
-
- if (dp->id_raw_dev.bi_fd) {
- (void) nsc_close(dp->id_raw_dev.bi_fd);
- dp->id_raw_dev.bi_fd = NULL;
- }
-
- mutex_exit(&dp->id_rlock);
- mutex_destroy(&dp->id_rlock);
- cv_destroy(&dp->id_rcv);
-
- kmem_free(dp, sizeof (*dp));
-}
-
-
-/*
- * This function provokes an nsc_reserve() for the device which
- * if successful will populate krdc->maxfbas and urdc->volume_size
- * via the _rdc_attach_fd() callback.
- */
-void
-rdc_get_details(rdc_k_info_t *krdc)
-{
- int rc;
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- nsc_size_t vol_size, maxfbas;
-
- if (_rdc_rsrv_devs(krdc, RDC_RAW, RDC_INTERNAL) == 0) {
- /*
- * if the vol is already reserved,
- * volume_size won't be populated on enable because
- * it is a *fake* reserve and does not make it to
- * _rdc_attach_fd(). So do it here.
- */
- rc = nsc_partsize(RDC_U_FD(krdc), &vol_size);
- if (rc != 0) {
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!rdc_get_details: partsize failed (%d)", rc);
-#endif /* DEBUG */
- urdc->volume_size = vol_size = 0;
- }
-
- urdc->volume_size = vol_size;
- rc = nsc_maxfbas(RDC_U_FD(krdc), 0, &maxfbas);
- if (rc != 0) {
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!rdc_get_details: maxfbas failed (%d)", rc);
-#endif /* DEBUG */
- maxfbas = 0;
- }
- krdc->maxfbas = min(RDC_MAX_MAXFBAS, maxfbas);
-
- _rdc_rlse_devs(krdc, RDC_RAW);
- }
-}
-
-
-/*
- * Should only be used by the config code.
- */
-
-int
-rdc_dev_open(rdc_set_t *rdc_set, int options)
-{
- rdc_k_info_t *krdc;
- int index;
- int rc;
- char *pathname;
-
- ASSERT(MUTEX_HELD(&rdc_conf_lock));
-
- if (options & RDC_OPT_PRIMARY)
- pathname = rdc_set->primary.file;
- else
- pathname = rdc_set->secondary.file;
-
- for (index = 0; index < rdc_max_sets; index++) {
- krdc = &rdc_k_info[index];
-
- if (!IS_CONFIGURED(krdc))
- break;
- }
-
- if (index == rdc_max_sets) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!rdc_dev_open: out of cd\'s");
-#endif
- index = -EINVAL;
- goto out;
- }
-
- if (krdc->devices && (krdc->c_fd || krdc->r_fd)) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!rdc_dev_open: %s already open", pathname);
-#endif
- index = -EINVAL;
- goto out;
- }
-
- _rdc_open_count++;
-
- krdc->devices = rdc_idev_open(krdc, pathname, &rc);
- if (!krdc->devices) {
- index = -rc;
- goto open_fail;
- }
-
- /*
- * Grab the device size and maxfbas now.
- */
-
- rdc_get_details(krdc);
-
-out:
- return (index);
-
-open_fail:
- _rdc_open_count--;
-
- return (index);
-}
-
-
-void
-rdc_dev_close(rdc_k_info_t *krdc)
-{
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
-
- mutex_enter(&rdc_conf_lock);
-
- if (krdc->devices)
- mutex_enter(&krdc->devices->id_rlock);
-
-#ifdef DEBUG
- if (!krdc->devices || !krdc->c_fd || !krdc->r_fd) {
- cmn_err(CE_WARN,
- "!rdc_dev_close(%p): c_fd %p r_fd %p", (void *)krdc,
- (void *) (krdc->devices ? krdc->c_fd : 0),
- (void *) (krdc->devices ? krdc->r_fd : 0));
- }
-#endif
-
- if (krdc->devices) {
- /* rdc_idev_close will release id_rlock */
- rdc_idev_close(krdc, krdc->devices);
- krdc->devices = NULL;
- }
-
- urdc->primary.file[0] = '\0';
-
- if (_rdc_open_count <= 0) {
- cmn_err(CE_WARN, "!rdc: _rdc_open_count corrupt: %d",
- _rdc_open_count);
- }
-
- _rdc_open_count--;
-
- mutex_exit(&rdc_conf_lock);
-}
-
-
-/*
- * rdc_intercept
- *
- * Register for IO on this device with nsctl.
- *
- * For a 1-to-many primary we register for each krdc and let nsctl sort
- * out which it wants to be using. This means that we cannot tell which
- * krdc will receive the incoming io from nsctl, though we do know that
- * at any one time only one krdc will be 'attached' and so get io from
- * nsctl.
- *
- * So the krdc->many_next pointer is maintained as a circular list. The
- * result of these multiple nsc_register_paths is that we will see a
- * few more attach and detach io provider calls during enable/resume
- * and disable/suspend of the 1-to-many whilst nsctl settles down to
- * using a single krdc.
- *
- * The major advantage of this scheme is that nsctl sorts out all the
- * rdc_fd_t's so that they can only point to krdc's that are currently
- * active.
- */
-int
-rdc_intercept(rdc_k_info_t *krdc)
-{
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- char *pathname;
- char *bitmap;
-
- if (rdc_get_vflags(urdc) & RDC_PRIMARY) {
- pathname = urdc->primary.file;
- bitmap = urdc->primary.bitmap;
- } else {
- pathname = urdc->secondary.file;
- bitmap = urdc->secondary.bitmap;
- }
-
- if (!krdc->b_tok)
- krdc->b_tok = nsc_register_path(bitmap, NSC_CACHE | NSC_DEVICE,
- _rdc_io_hc);
-
- if (!krdc->c_tok)
- krdc->c_tok = nsc_register_path(pathname, NSC_CACHE,
- _rdc_io_hc);
-
- if (!krdc->r_tok)
- krdc->r_tok = nsc_register_path(pathname, NSC_DEVICE,
- _rdc_io_hr);
-
- if (!krdc->c_tok || !krdc->r_tok) {
- (void) rdc_unintercept(krdc);
- return (ENXIO);
- }
-
- return (0);
-}
-
-
-static void
-wait_unregistering(rdc_k_info_t *krdc)
-{
- while (krdc->group->unregistering > 0)
- (void) cv_wait_sig(&krdc->group->unregistercv, &rdc_conf_lock);
-}
-
-static void
-set_unregistering(rdc_k_info_t *krdc)
-{
- wait_unregistering(krdc);
-
- krdc->group->unregistering++;
-}
-
-static void
-wakeup_unregistering(rdc_k_info_t *krdc)
-{
- if (krdc->group->unregistering <= 0)
- return;
-
- krdc->group->unregistering--;
- cv_broadcast(&krdc->group->unregistercv);
-}
-
-
-/*
- * rdc_unintercept
- *
- * Unregister for IO on this device.
- *
- * See comments above rdc_intercept.
- */
-int
-rdc_unintercept(rdc_k_info_t *krdc)
-{
- int err = 0;
- int rc;
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
-
- mutex_enter(&rdc_conf_lock);
- set_unregistering(krdc);
- krdc->type_flag |= RDC_UNREGISTER;
- mutex_exit(&rdc_conf_lock);
-
- if (krdc->r_tok) {
- rc = nsc_unregister_path(krdc->r_tok, 0);
- if (rc) {
- cmn_err(CE_WARN, "!rdc: unregister rawfd %d", rc);
- err = rc;
- }
- krdc->r_tok = NULL;
- }
-
- if (krdc->c_tok) {
- rc = nsc_unregister_path(krdc->c_tok, 0);
- if (rc) {
- cmn_err(CE_WARN, "!rdc: unregister cachefd %d", rc);
- if (!err)
- err = rc;
- }
- krdc->c_tok = NULL;
- }
-
- if (krdc->b_tok) {
- rc = nsc_unregister_path(krdc->b_tok, 0);
- if (rc) {
- cmn_err(CE_WARN, "!rdc: unregister bitmap %d", rc);
- err = rc;
- }
- krdc->b_tok = NULL;
- }
-
- rdc_group_enter(krdc);
-
- /* Wait for all necessary _rdc_close() calls to complete */
- while ((krdc->c_ref + krdc->r_ref + krdc->b_ref) != 0) {
- krdc->closing++;
- cv_wait(&krdc->closingcv, &krdc->group->lock);
- krdc->closing--;
- }
-
- rdc_clr_flags(urdc, RDC_ENABLED);
- rdc_group_exit(krdc);
-
-
- /*
- * Check there are no outstanding writes in progress.
- * This can happen when a set is being disabled which
- * is one of the 'one_to_many' chain, that did not
- * intercept the original write call.
- */
-
- for (;;) {
- rdc_group_enter(krdc);
- if (krdc->aux_state & RDC_AUXWRITE) {
- rdc_group_exit(krdc);
- /*
- * This doesn't happen very often,
- * just delay a bit and re-look.
- */
- delay(50);
- } else {
- rdc_group_exit(krdc);
- break;
- }
- }
-
- mutex_enter(&rdc_conf_lock);
- krdc->type_flag &= ~RDC_UNREGISTER;
- wakeup_unregistering(krdc);
- mutex_exit(&rdc_conf_lock);
-
- return (err);
-}
-
-
-/*
- * _rdc_rlse_d
- * Internal version of _rdc_rlse_devs(), only concerned with the
- * data device, not the bitmap.
- */
-
-static void
-_rdc_rlse_d(rdc_k_info_t *krdc, int devs)
-{
- _rdc_info_dev_t *cip;
- _rdc_info_dev_t *rip;
- int raw = (devs & RDC_RAW);
-
- if (!krdc) {
- cmn_err(CE_WARN, "!rdc: _rdc_rlse_devs null krdc");
- return;
- }
-
- ASSERT((devs & (~RDC_BMP)) != 0);
-
- cip = &krdc->devices->id_cache_dev;
- rip = &krdc->devices->id_raw_dev;
-
- if (IS_RSRV(cip)) {
- /* decrement count */
-
- if (raw) {
- if (cip->bi_ofailed > 0) {
- cip->bi_ofailed--;
- } else if (cip->bi_orsrv > 0) {
- cip->bi_orsrv--;
- }
- } else {
- if (cip->bi_failed > 0) {
- cip->bi_failed--;
- } else if (cip->bi_rsrv > 0) {
- cip->bi_rsrv--;
- }
- }
-
- /*
- * reset nsc_fd ownership back link, it is only set if
- * we have really done an underlying reserve, not for
- * failed (faked) reserves.
- */
-
- if (cip->bi_rsrv > 0 || cip->bi_orsrv > 0) {
- nsc_set_owner(cip->bi_fd, krdc->iodev);
- } else {
- nsc_set_owner(cip->bi_fd, NULL);
- }
-
- /* release nsc_fd */
-
- if (!IS_RSRV(cip)) {
- nsc_release(cip->bi_fd);
- }
- } else if (IS_RSRV(rip)) {
- /* decrement count */
-
- if (raw) {
- if (rip->bi_failed > 0) {
- rip->bi_failed--;
- } else if (rip->bi_rsrv > 0) {
- rip->bi_rsrv--;
- }
- } else {
- if (rip->bi_ofailed > 0) {
- rip->bi_ofailed--;
- } else if (rip->bi_orsrv > 0) {
- rip->bi_orsrv--;
- }
- }
-
- /*
- * reset nsc_fd ownership back link, it is only set if
- * we have really done an underlying reserve, not for
- * failed (faked) reserves.
- */
-
- if (rip->bi_rsrv > 0 || rip->bi_orsrv > 0) {
- nsc_set_owner(rip->bi_fd, krdc->iodev);
- } else {
- nsc_set_owner(rip->bi_fd, NULL);
- }
-
- /* release nsc_fd and any waiters */
-
- if (!IS_RSRV(rip)) {
- rip->bi_flag = 0;
- nsc_release(rip->bi_fd);
- cv_broadcast(&krdc->devices->id_rcv);
- }
- } else {
- cmn_err(CE_WARN, "!rdc: _rdc_rlse_devs no reserve? krdc %p",
- (void *) krdc);
- }
-}
-
-/*
- * _rdc_rlse_devs
- * Release named underlying devices and take care of setting the
- * back link on the nsc_fd to the correct parent iodev.
- *
- * NOTE: the 'devs' argument must be the same as that passed to
- * the preceding _rdc_rsrv_devs call.
- */
-
-void
-_rdc_rlse_devs(rdc_k_info_t *krdc, int devs)
-{
-
- DTRACE_PROBE(_rdc_rlse_devs_start);
- mutex_enter(&krdc->devices->id_rlock);
-
- ASSERT(!(devs & RDC_CACHE));
-
- if ((devs & (~RDC_BMP)) != 0) {
- _rdc_rlse_d(krdc, devs);
- }
-
- if ((devs & RDC_BMP) != 0) {
- if (krdc->bmaprsrv > 0 && --krdc->bmaprsrv == 0) {
- nsc_release(krdc->bitmapfd);
- }
- }
-
- mutex_exit(&krdc->devices->id_rlock);
-
-}
-
-/*
- * _rdc_rsrv_d
- * Reserve device flagged, unless its companion is already reserved,
- * in that case increase the reserve on the companion. Take care
- * of setting the nsc_fd ownership back link to the correct parent
- * iodev pointer.
- */
-
-static int
-_rdc_rsrv_d(int raw, _rdc_info_dev_t *rid, _rdc_info_dev_t *cid, int flag,
- rdc_k_info_t *krdc)
-{
- _rdc_info_dev_t *p = NULL;
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- int other = 0;
- int rc;
-
-
-#ifdef DEBUG
- if ((rid->bi_rsrv < 0) ||
- (cid->bi_rsrv < 0) ||
- (rid->bi_orsrv < 0) ||
- (cid->bi_orsrv < 0) ||
- (rid->bi_failed < 0) ||
- (cid->bi_failed < 0) ||
- (rid->bi_ofailed < 0) ||
- (cid->bi_ofailed < 0)) {
- cmn_err(CE_WARN,
- "!_rdc_rsrv_d: negative counts (rsrv %d %d orsrv %d %d)",
- rid->bi_rsrv, cid->bi_rsrv,
- rid->bi_orsrv, cid->bi_orsrv);
- cmn_err(CE_WARN,
- "!_rdc_rsrv_d: negative counts (fail %d %d ofail %d %d)",
- rid->bi_failed, cid->bi_failed,
- rid->bi_ofailed, cid->bi_ofailed);
- cmn_err(CE_PANIC, "_rdc_rsrv_d: negative counts (krdc %p)",
- (void *) krdc);
- }
-#endif
-
- /*
- * If user wants to do a cache reserve and it's already
- * raw reserved internally, we need to do a real nsc_reserve, so wait
- * until the release has been done.
- */
- if (IS_RSRV(rid) && (flag == RDC_EXTERNAL) &&
- (raw == 0) && (rid->bi_flag != RDC_EXTERNAL)) {
- krdc->devices->id_release++;
- while (IS_RSRV(rid))
- cv_wait(&krdc->devices->id_rcv,
- &krdc->devices->id_rlock);
- krdc->devices->id_release--;
- }
-
- /* select underlying device to use */
-
- if (IS_RSRV(rid)) {
- p = rid;
- if (!raw) {
- other = 1;
- }
- } else if (IS_RSRV(cid)) {
- p = cid;
- if (raw) {
- other = 1;
- }
- }
-
- /* just increment count and return if already reserved */
-
- if (p && !RFAILED(p)) {
- if (other) {
- p->bi_orsrv++;
- } else {
- p->bi_rsrv++;
- }
-
- /* set nsc_fd ownership back link */
- nsc_set_owner(p->bi_fd, krdc->iodev);
- return (0);
- }
-
- /* attempt reserve */
-
- if (!p) {
- p = raw ? rid : cid;
- }
-
- if (!p->bi_fd) {
- /* rpc server raced with rdc_dev_close() */
- return (EIO);
- }
- if ((rc = nsc_reserve(p->bi_fd, 0)) == 0) {
- /*
- * convert failed counts into reserved counts, and add
- * in this reserve.
- */
-
- p->bi_orsrv = p->bi_ofailed;
- p->bi_rsrv = p->bi_failed;
-
- if (other) {
- p->bi_orsrv++;
- } else {
- p->bi_rsrv++;
- }
-
- p->bi_ofailed = 0;
- p->bi_failed = 0;
-
- /* set nsc_fd ownership back link */
-
- nsc_set_owner(p->bi_fd, krdc->iodev);
- } else if (rc != EINTR) {
- /*
- * If this is the master, and the secondary is not
- * failed, then just fake this external reserve so that
- * we can do remote io to the secondary and continue to
- * provide service to the client.
- *
- * Subsequent calls to _rdc_rsrv_d() will re-try the
- * nsc_reserve() until it succeeds.
- */
-
- if ((rdc_get_vflags(urdc) & RDC_PRIMARY) &&
- !(rdc_get_vflags(urdc) & RDC_LOGGING) &&
- !((rdc_get_vflags(urdc) & RDC_SLAVE) &&
- (rdc_get_vflags(urdc) & RDC_SYNCING))) {
- if (!(rdc_get_vflags(urdc) & RDC_VOL_FAILED)) {
- rdc_many_enter(krdc);
- /* Primary, so reverse sync needed */
- rdc_set_mflags(urdc, RDC_RSYNC_NEEDED);
- rdc_set_flags_log(urdc, RDC_VOL_FAILED,
- "nsc_reserve failed");
- rdc_many_exit(krdc);
- rc = -1;
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!nsc_reserve failed "
- "with rc == %d\n", rc);
-#endif
- } else {
- rc = 0;
- }
-
- if (other) {
- p->bi_ofailed++;
- } else {
- p->bi_failed++;
- }
-
- if (krdc->maxfbas == 0) {
- /*
- * fake a maxfbas value for remote i/o,
- * this will get reset when the next
- * successful reserve happens as part
- * of the rdc_attach_fd() callback.
- */
- krdc->maxfbas = 128;
- }
- }
- }
-
- if (rc == 0 && raw) {
- p->bi_flag = flag;
- }
-
-
- return (rc);
-}
-
-/*
- * _rdc_rsrv_devs
- * Reserve named underlying devices.
- *
- */
-
-int
-_rdc_rsrv_devs(rdc_k_info_t *krdc, int devs, int flag)
-{
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- int write = 0;
- int rc = 0;
- int got = 0;
-
- if (!krdc) {
- return (EINVAL);
- }
-
- ASSERT(!(devs & RDC_CACHE));
-
- mutex_enter(&krdc->devices->id_rlock);
-
- if ((devs & (~RDC_BMP)) != 0) {
- if ((rc = _rdc_rsrv_d((devs & RDC_CACHE) == 0,
- &krdc->devices->id_raw_dev, &krdc->devices->id_cache_dev,
- flag, krdc)) != 0) {
- if (rc == -1) {
- /*
- * we need to call rdc_write_state()
- * after we drop the mutex
- */
- write = 1;
- rc = 0;
- } else {
- cmn_err(CE_WARN,
- "!rdc: nsc_reserve(%s) failed %d\n",
- nsc_pathname(krdc->c_fd), rc);
- }
- } else {
- got |= (devs & (~RDC_BMP));
- }
- }
-
- if (rc == 0 && (devs & RDC_BMP) != 0) {
- if (krdc->bitmapfd == NULL)
- rc = EIO;
- else if ((krdc->bmaprsrv == 0) &&
- (rc = nsc_reserve(krdc->bitmapfd, 0)) != 0) {
- cmn_err(CE_WARN, "!rdc: nsc_reserve(%s) failed %d\n",
- nsc_pathname(krdc->bitmapfd), rc);
- } else {
- krdc->bmaprsrv++;
- got |= RDC_BMP;
- }
- if (!RDC_SUCCESS(rc)) {
- /* Undo any previous reserve */
- if (got != 0)
- _rdc_rlse_d(krdc, got);
- }
- }
-
- mutex_exit(&krdc->devices->id_rlock);
-
- if (write) {
- rdc_write_state(urdc);
- }
-
- return (rc);
-}
-
-
-/*
- * Read from the remote end, ensuring that if this is a many group in
- * slave mode that we only remote read from the secondary with the
- * valid data.
- */
-int
-_rdc_remote_read(rdc_k_info_t *krdc, nsc_buf_t *h, nsc_off_t pos,
- nsc_size_t len, int flag)
-{
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- rdc_k_info_t *this = krdc; /* krdc that was requested */
- int rc;
-
- if (flag & NSC_RDAHEAD) {
- /*
- * no point in doing readahead remotely,
- * just say we did it ok - the client is about to
- * throw this buffer away as soon as we return.
- */
- return (NSC_DONE);
- }
-
- /*
- * If this is a many group with a reverse sync in progress and
- * this is not the slave krdc/urdc, then search for the slave
- * so that we can do the remote io from the correct secondary.
- */
- if ((rdc_get_mflags(urdc) & RDC_SLAVE) &&
- !(rdc_get_vflags(urdc) & RDC_SLAVE)) {
- rdc_many_enter(krdc);
- for (krdc = krdc->many_next; krdc != this;
- krdc = krdc->many_next) {
- urdc = &rdc_u_info[krdc->index];
- if (!IS_ENABLED(urdc))
- continue;
- if (rdc_get_vflags(urdc) & RDC_SLAVE)
- break;
- }
- rdc_many_exit(krdc);
-
- this = krdc;
- }
-
-read1:
- if (rdc_get_vflags(urdc) & RDC_LOGGING) {
- /* cannot do remote io without the remote node! */
- rc = ENETDOWN;
- goto read2;
- }
-
-
- /* wait for the remote end to have the latest data */
-
- if (IS_ASYNC(urdc)) {
- while (krdc->group->ra_queue.blocks != 0) {
- if (!krdc->group->rdc_writer)
- (void) rdc_writer(krdc->index);
-
- (void) rdc_drain_queue(krdc->index);
- }
- }
-
- if (krdc->io_kstats) {
- mutex_enter(krdc->io_kstats->ks_lock);
- kstat_runq_enter(KSTAT_IO_PTR(krdc->io_kstats));
- mutex_exit(krdc->io_kstats->ks_lock);
- }
-
- rc = rdc_net_read(krdc->index, krdc->remote_index, h, pos, len);
-
- if (krdc->io_kstats) {
- mutex_enter(krdc->io_kstats->ks_lock);
- kstat_runq_exit(KSTAT_IO_PTR(krdc->io_kstats));
- mutex_exit(krdc->io_kstats->ks_lock);
- }
-
- /* If read error keep trying every secondary until no more */
-read2:
- if (!RDC_SUCCESS(rc) && IS_MANY(krdc) &&
- !(rdc_get_mflags(urdc) & RDC_SLAVE)) {
- rdc_many_enter(krdc);
- for (krdc = krdc->many_next; krdc != this;
- krdc = krdc->many_next) {
- urdc = &rdc_u_info[krdc->index];
- if (!IS_ENABLED(urdc))
- continue;
- rdc_many_exit(krdc);
- goto read1;
- }
- rdc_many_exit(krdc);
- }
-
- return (rc);
-}
-
-
-/*
- * _rdc_alloc_buf
- * Allocate a buffer of data
- *
- * Calling/Exit State:
- * Returns NSC_DONE or NSC_HIT for success, NSC_PENDING for async
- * I/O, > 0 is an error code.
- *
- * Description:
- */
-int rdcbufs = 0;
-
-static int
-_rdc_alloc_buf(rdc_fd_t *rfd, nsc_off_t pos, nsc_size_t len, int flag,
- rdc_buf_t **ptr)
-{
- rdc_k_info_t *krdc = rfd->rdc_info;
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- nsc_vec_t *vec = NULL;
- rdc_buf_t *h;
- size_t size;
- int ioflag;
- int rc = 0;
-
- if (RDC_IS_BMP(rfd) || RDC_IS_QUE(rfd))
- return (EIO);
-
- if (len == 0)
- return (EINVAL);
-
- if (flag & NSC_WRBUF) {
-
- if (!(rdc_get_vflags(urdc) & RDC_PRIMARY) &&
- !(rdc_get_vflags(urdc) & RDC_LOGGING)) {
- /*
- * Forbid writes to secondary unless logging.
- */
- return (EIO);
- }
- }
-
- if (!(rdc_get_vflags(urdc) & RDC_PRIMARY) &&
- (rdc_get_vflags(urdc) & RDC_SYNC_NEEDED)) {
- /*
- * Forbid any io to secondary if it needs a sync.
- */
- return (EIO);
- }
-
- if ((rdc_get_vflags(urdc) & RDC_PRIMARY) &&
- (rdc_get_vflags(urdc) & RDC_RSYNC_NEEDED) &&
- !(rdc_get_vflags(urdc) & RDC_VOL_FAILED) &&
- !(rdc_get_vflags(urdc) & RDC_SLAVE)) {
- /*
- * Forbid any io to primary if it needs a reverse sync
- * and is not actively syncing.
- */
- return (EIO);
- }
-
- /* Bounds checking */
- ASSERT(urdc->volume_size != 0);
- if (pos + len > urdc->volume_size) {
-#ifdef DEBUG
- cmn_err(CE_NOTE,
- "!rdc: Attempt to access beyond end of rdc volume");
-#endif
- return (EIO);
- }
-
- h = *ptr;
- if (h == NULL) {
- /* should never happen (nsctl does this for us) */
-#ifdef DEBUG
- cmn_err(CE_WARN, "!_rdc_alloc_buf entered without buffer!");
-#endif
- h = (rdc_buf_t *)_rdc_alloc_handle(NULL, NULL, NULL, rfd);
- if (h == NULL)
- return (ENOMEM);
-
- h->rdc_bufh.sb_flag &= ~NSC_HALLOCATED;
- *ptr = h;
- }
-
- if (flag & NSC_NOBLOCK) {
- cmn_err(CE_WARN,
- "!_rdc_alloc_buf: removing unsupported NSC_NOBLOCK flag");
- flag &= ~(NSC_NOBLOCK);
- }
-
- h->rdc_bufh.sb_error = 0;
- h->rdc_bufh.sb_flag |= flag;
- h->rdc_bufh.sb_pos = pos;
- h->rdc_bufh.sb_len = len;
- ioflag = flag;
-
- bzero(&h->rdc_sync, sizeof (h->rdc_sync));
- mutex_init(&h->rdc_sync.lock, NULL, MUTEX_DRIVER, NULL);
- cv_init(&h->rdc_sync.cv, NULL, CV_DRIVER, NULL);
-
- if (flag & NSC_WRBUF)
- _rdc_async_throttle(krdc, len); /* throttle incoming io */
-
- /*
- * Use remote io when:
- * - local volume is failed
- * - reserve status is failed
- */
- if ((rdc_get_vflags(urdc) & RDC_VOL_FAILED) || IS_RFAILED(krdc)) {
- rc = EIO;
- } else {
- rc = nsc_alloc_buf(RDC_U_FD(krdc), pos, len,
- ioflag, &h->rdc_bufp);
- if (!RDC_SUCCESS(rc)) {
- rdc_many_enter(krdc);
- if (rdc_get_vflags(urdc) & RDC_PRIMARY) {
- /* Primary, so reverse sync needed */
- rdc_set_mflags(urdc, RDC_RSYNC_NEEDED);
- } else {
- /* Secondary, so forward sync needed */
- rdc_set_flags(urdc, RDC_SYNC_NEEDED);
- }
- rdc_set_flags_log(urdc, RDC_VOL_FAILED,
- "nsc_alloc_buf failed");
- rdc_many_exit(krdc);
- rdc_write_state(urdc);
- }
- }
-
- if (RDC_SUCCESS(rc)) {
- h->rdc_bufh.sb_vec = h->rdc_bufp->sb_vec;
- h->rdc_flags |= RDC_ALLOC;
-
- /*
- * If in slave and reading data, remote read on top of
- * the buffer to ensure that we have the latest data.
- */
- if ((flag & NSC_READ) &&
- (rdc_get_vflags(urdc) & RDC_PRIMARY) &&
- (rdc_get_mflags(urdc) & RDC_SLAVE)) {
- rc = _rdc_remote_read(krdc, &h->rdc_bufh,
- pos, len, flag);
- /*
- * Set NSC_MIXED so that the
- * cache will throw away this buffer when we free
- * it since we have combined data from multiple
- * sources into a single buffer.
- */
- h->rdc_bufp->sb_flag |= NSC_MIXED;
- }
- }
-
- /*
- * If nsc_alloc_buf above fails, or local volume is failed or
- * bitmap is failed or reserve, then we fill the buf from remote
- */
-
- if ((!RDC_SUCCESS(rc)) && (rdc_get_vflags(urdc) & RDC_PRIMARY) &&
- !(rdc_get_vflags(urdc) & RDC_LOGGING)) {
- if (flag & NSC_NODATA) {
- ASSERT(!(flag & NSC_READ));
- h->rdc_flags |= RDC_REMOTE_BUF;
- h->rdc_bufh.sb_vec = NULL;
- } else {
- size = sizeof (nsc_vec_t) * 2;
- h->rdc_vsize = size + FBA_SIZE(len);
- vec = kmem_zalloc(h->rdc_vsize, KM_SLEEP);
-
- if (!vec) {
- rc = ENOMEM;
- goto error;
- }
-
- /* single flat buffer */
-
- vec[0].sv_addr = (uchar_t *)vec + size;
- vec[0].sv_len = FBA_SIZE(len);
- vec[0].sv_vme = 0;
-
- /* null terminator */
-
- vec[1].sv_addr = NULL;
- vec[1].sv_len = 0;
- vec[1].sv_vme = 0;
-
- h->rdc_bufh.sb_vec = vec;
- h->rdc_flags |= RDC_REMOTE_BUF;
- h->rdc_flags |= RDC_VEC_ALLOC;
- }
-
- if (flag & NSC_READ) {
- rc = _rdc_remote_read(krdc, &h->rdc_bufh,
- pos, len, flag);
- } else {
- rc = NSC_DONE;
- }
- }
-error:
- if (!RDC_SUCCESS(rc)) {
- h->rdc_bufh.sb_error = rc;
- }
-
- return (rc);
-}
-
-
-/*
- * _rdc_free_buf
- */
-
-static int
-_rdc_free_buf(rdc_buf_t *h)
-{
- int rc = 0;
-
- if (h->rdc_flags & RDC_ALLOC) {
- if (h->rdc_bufp) {
- rc = nsc_free_buf(h->rdc_bufp);
- }
- h->rdc_flags &= ~(RDC_ALLOC);
-
- if (!RDC_SUCCESS(rc)) {
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!_rdc_free_buf(%p): nsc_free_buf(%p) returned %d",
- (void *) h, (void *) h->rdc_bufp, rc);
-#endif
- return (rc);
- }
- }
-
- if (h->rdc_flags & (RDC_REMOTE_BUF|RDC_VEC_ALLOC)) {
- if (h->rdc_flags & RDC_VEC_ALLOC) {
- kmem_free(h->rdc_bufh.sb_vec, h->rdc_vsize);
- }
- h->rdc_flags &= ~(RDC_REMOTE_BUF|RDC_VEC_ALLOC);
- }
-
- if (h->rdc_anon) {
- /* anon buffers still pending */
- DTRACE_PROBE1(rdc_free_buf_err, aio_buf_t, h->rdc_anon);
- }
-
- if ((h->rdc_bufh.sb_flag & NSC_HALLOCATED) == 0) {
- rc = _rdc_free_handle(h, h->rdc_fd);
- if (!RDC_SUCCESS(rc)) {
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!_rdc_free_buf(%p): _rdc_free_handle returned %d",
- (void *) h, rc);
-#endif
- return (rc);
- }
- } else {
- h->rdc_bufh.sb_flag = NSC_HALLOCATED;
- h->rdc_bufh.sb_vec = NULL;
- h->rdc_bufh.sb_error = 0;
- h->rdc_bufh.sb_pos = 0;
- h->rdc_bufh.sb_len = 0;
- h->rdc_anon = NULL;
- h->rdc_vsize = 0;
-
- cv_destroy(&h->rdc_sync.cv);
- mutex_destroy(&h->rdc_sync.lock);
-
- }
-
- return (0);
-}
-
-
-/*
- * _rdc_open
- * Open a device
- *
- * Calling/Exit State:
- * Returns a token to identify the device.
- *
- * Description:
- * Performs the housekeeping operations associated with an upper layer
- * of the nsctl stack opening a device.
- */
-
-/* ARGSUSED */
-
-static int
-_rdc_open(char *path, int flag, blind_t *cdp, nsc_iodev_t *iodev)
-{
- rdc_k_info_t *krdc;
-#ifdef DEBUG
- rdc_u_info_t *urdc;
-#endif
- rdc_fd_t *rfd;
- int raw = ((flag & NSC_CACHE) == 0);
- int index;
- int bmp = 0;
- int queue = 0;
-
- rfd = kmem_zalloc(sizeof (*rfd), KM_SLEEP);
- if (!rfd)
- return (ENOMEM);
-
- /*
- * Take config lock to prevent a race with the
- * (de)configuration code.
- */
-
- mutex_enter(&rdc_conf_lock);
-
- index = rdc_lookup_enabled(path, 0);
- if (index < 0) {
- index = rdc_lookup_bitmap(path);
- if (index >= 0)
- bmp = 1;
- }
- if (index < 0) {
- index = rdc_lookup_diskq(path);
- if (index >= 0)
- queue = 1;
- }
- if (index < 0) {
- /* not found in config */
- mutex_exit(&rdc_conf_lock);
- kmem_free(rfd, sizeof (*rfd));
- return (ENXIO);
- }
-#ifdef DEBUG
- urdc = &rdc_u_info[index];
-#endif
- krdc = &rdc_k_info[index];
-
- mutex_exit(&rdc_conf_lock);
-
- rdc_group_enter(krdc);
-
- ASSERT(IS_ENABLED(urdc));
-
- if (bmp) {
- krdc->b_ref++;
- } else if (raw) {
- krdc->r_ref++;
- } else if (!queue) {
- krdc->c_ref++;
- }
-
- rfd->rdc_info = krdc;
- if (bmp)
- rfd->rdc_type = RDC_BMP;
- else if (queue)
- rfd->rdc_type = RDC_QUE;
- else
- rfd->rdc_oflags = flag;
-
- rdc_group_exit(krdc);
-
- *cdp = (blind_t)rfd;
-
- return (0);
-}
-
-static int
-_rdc_openc(char *path, int flag, blind_t *cdp, nsc_iodev_t *iodev)
-{
- return (_rdc_open(path, NSC_CACHE|flag, cdp, iodev));
-}
-
-static int
-_rdc_openr(char *path, int flag, blind_t *cdp, nsc_iodev_t *iodev)
-{
- return (_rdc_open(path, NSC_DEVICE|flag, cdp, iodev));
-}
-
-
-/*
- * _rdc_close
- * Close a device
- *
- * Calling/Exit State:
- * Always succeeds - returns 0
- *
- * Description:
- * Performs the housekeeping operations associated with an upper layer
- * of the sd stack closing a shadowed device.
- */
-
-static int
-_rdc_close(rfd)
-rdc_fd_t *rfd;
-{
- rdc_k_info_t *krdc = rfd->rdc_info;
- int bmp = RDC_IS_BMP(rfd);
- int raw = RDC_IS_RAW(rfd);
- int queue = RDC_IS_QUE(rfd);
-
- /*
- * we don't keep ref counts for the queue, so skip this stuff.
- * we may not even have a valid krdc at this point
- */
- if (queue)
- goto queue;
- rdc_group_enter(krdc);
-
- if (bmp) {
- krdc->b_ref--;
- } else if (raw && !queue) {
- krdc->r_ref--;
- } else if (!queue) {
- krdc->c_ref--;
- }
-
- if (krdc->closing) {
- cv_broadcast(&krdc->closingcv);
- }
-
- rdc_group_exit(krdc);
-queue:
- kmem_free(rfd, sizeof (*rfd));
- return (0);
-}
-
-/*
- * _rdc_alloc_handle
- * Allocate a handle
- *
- */
-
-static nsc_buf_t *
-_rdc_alloc_handle(void (*d_cb)(), void (*r_cb)(), void (*w_cb)(), rdc_fd_t *rfd)
-{
- rdc_buf_t *h;
-
- h = kmem_zalloc(sizeof (*h), KM_SLEEP);
- if (!h)
- return (NULL);
-
- h->rdc_bufp = nsc_alloc_handle(RDC_FD(rfd), d_cb, r_cb, w_cb);
- if (!h->rdc_bufp) {
- if (!IS_RFAILED(rfd->rdc_info)) {
- /*
- * This is a real failure from the io provider below.
- */
- kmem_free(h, sizeof (*h));
- return (NULL);
- } else {
- /* EMPTY */
- /*
- * This is just a failed primary device where
- * we can do remote io to the secondary.
- */
- }
- }
-
- h->rdc_bufh.sb_flag = NSC_HALLOCATED;
- h->rdc_fd = rfd;
- mutex_init(&h->aio_lock, NULL, MUTEX_DRIVER, NULL);
-
- return (&h->rdc_bufh);
-}
-
-
-/*
- * _rdc_free_handle
- * Free a handle
- *
- */
-
-/* ARGSUSED */
-static int
-_rdc_free_handle(rdc_buf_t *h, rdc_fd_t *rfd)
-{
- int rc;
-
- mutex_destroy(&h->aio_lock);
- if (h->rdc_bufp) {
- rc = nsc_free_handle(h->rdc_bufp);
- if (!RDC_SUCCESS(rc))
- return (rc);
- }
- kmem_free(h, sizeof (rdc_buf_t));
- return (0);
-}
-
-
-/*
- * _rdc_attach
- * Attach
- *
- * Calling/Exit State:
- * Returns 0 for success, errno on failure.
- *
- * Description:
- */
-
-static int
-_rdc_attach(rdc_fd_t *rfd, nsc_iodev_t *iodev)
-{
- rdc_k_info_t *krdc;
- int raw = RDC_IS_RAW(rfd);
- int rc;
-
- if ((RDC_IS_BMP(rfd)) || RDC_IS_QUE(rfd))
- return (EINVAL);
-
- krdc = rfd->rdc_info;
- if (krdc == NULL)
- return (EINVAL);
-
- mutex_enter(&krdc->devices->id_rlock);
- krdc->iodev = iodev;
- mutex_exit(&krdc->devices->id_rlock);
-
- rc = _rdc_rsrv_devs(krdc, (raw ? RDC_RAW : RDC_CACHE), RDC_EXTERNAL);
- return (rc);
-}
-
-
-/*
- * _rdc_detach
- * Detach
- *
- * Calling/Exit State:
- * Returns 0 for success, always succeeds
- *
- * Description:
- */
-
-static int
-_rdc_detach(rdc_fd_t *rfd, nsc_iodev_t *iodev)
-{
- rdc_k_info_t *krdc = rfd->rdc_info;
- int raw = RDC_IS_RAW(rfd);
-
- /*
- * Flush the async queue if necessary.
- */
-
- if (IS_ASYNC(&rdc_u_info[krdc->index]) && !RDC_IS_DISKQ(krdc->group)) {
- int tries = 1;
-
- while (krdc->group->ra_queue.blocks != 0 && tries--) {
- if (!krdc->group->rdc_writer)
- (void) rdc_writer(krdc->index);
-
- (void) rdc_drain_queue(krdc->index);
- }
-
- /* force disgard of possibly blocked flusher threads */
- if (rdc_drain_queue(krdc->index) != 0) {
-#ifdef DEBUG
- net_queue *qp = &krdc->group->ra_queue;
-#endif
- do {
- mutex_enter(&krdc->group->ra_queue.net_qlock);
- krdc->group->asyncdis = 1;
- cv_broadcast(&krdc->group->asyncqcv);
- mutex_exit(&krdc->group->ra_queue.net_qlock);
- cmn_err(CE_WARN,
- "!RDC: async I/O pending and not drained "
- "for %s during detach",
- rdc_u_info[krdc->index].primary.file);
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!nitems: %" NSC_SZFMT " nblocks: %"
- NSC_SZFMT " head: 0x%p tail: 0x%p",
- qp->nitems, qp->blocks,
- (void *)qp->net_qhead,
- (void *)qp->net_qtail);
-#endif
- } while (krdc->group->rdc_thrnum > 0);
- }
- }
-
- mutex_enter(&krdc->devices->id_rlock);
- if (krdc->iodev != iodev)
- cmn_err(CE_WARN, "!_rdc_detach: iodev mismatch %p : %p",
- (void *) krdc->iodev, (void *) iodev);
-
- krdc->iodev = NULL;
- mutex_exit(&krdc->devices->id_rlock);
-
- _rdc_rlse_devs(krdc, (raw ? RDC_RAW : RDC_CACHE));
-
- return (0);
-}
-
-/*
- * _rdc_get_pinned
- *
- * only affects local node.
- */
-
-static int
-_rdc_get_pinned(rdc_fd_t *rfd)
-{
- return (nsc_get_pinned(RDC_FD(rfd)));
-}
-
-/*
- * _rdc_discard_pinned
- *
- * only affects local node.
- */
-
-static int
-_rdc_discard_pinned(rdc_fd_t *rfd, nsc_off_t pos, nsc_size_t len)
-{
- return (nsc_discard_pinned(RDC_FD(rfd), pos, len));
-}
-
-/*
- * _rdc_partsize
- *
- * only affects the local node.
- */
-
-static int
-_rdc_partsize(rdc_fd_t *rfd, nsc_size_t *ptr)
-{
- rdc_u_info_t *urdc;
-
- urdc = &rdc_u_info[rfd->rdc_info->index];
- /* Always return saved size */
- ASSERT(urdc->volume_size != 0);
- *ptr = urdc->volume_size;
- return (0);
-}
-
-/*
- * _rdc_maxfbas
- *
- * only affects local node
- */
-
-/* ARGSUSED */
-static int
-_rdc_maxfbas(rdc_fd_t *rfd, int flag, nsc_size_t *ptr)
-{
- rdc_k_info_t *krdc = rfd->rdc_info;
- int raw = RDC_IS_RAW(rfd);
- int rtype = raw ? RDC_RAW : RDC_CACHE;
- int rc = 0;
-
- if (krdc == NULL)
- return (EINVAL);
- if (flag == NSC_RDAHEAD || flag == NSC_CACHEBLK) {
- rc = _rdc_rsrv_devs(krdc, rtype, RDC_INTERNAL);
- if (rc == 0) {
- rc = nsc_maxfbas(RDC_U_FD(krdc), flag, ptr);
- _rdc_rlse_devs(krdc, rtype);
- }
- } else {
- /* Always return saved size */
- ASSERT(krdc->maxfbas != 0);
- *ptr = krdc->maxfbas - 1;
- }
-
- return (rc);
-}
-
-/* ARGSUSED */
-static int
-_rdc_control(rdc_fd_t *rfd, int cmd, void *ptr, int len)
-{
- return (nsc_control(RDC_FD(rfd), cmd, ptr, len));
-}
-
-/*
- * _rdc_attach_fd
- *
- * called by nsctl as part of nsc_reserve() processing when one of
- * SNDR's underlying file descriptors becomes available and metadata
- * should be re-acquired.
- */
-static int
-_rdc_attach_fd(blind_t arg)
-{
- _rdc_info_dev_t *dip = (_rdc_info_dev_t *)arg;
- rdc_k_info_t *krdc;
- rdc_u_info_t *urdc;
- nsc_size_t maxfbas, partsize;
- int rc;
-
- krdc = dip->bi_krdc;
- urdc = &rdc_u_info[krdc->index];
-
- if ((rc = nsc_partsize(dip->bi_fd, &partsize)) != 0) {
- cmn_err(CE_WARN,
- "!SNDR: cannot get volume size of %s, error %d",
- nsc_pathname(dip->bi_fd), rc);
- } else if (urdc->volume_size == 0 && partsize > 0) {
- /* set volume size for the first time */
- urdc->volume_size = partsize;
- } else if (urdc->volume_size != partsize) {
- /*
- * SNDR cannot yet cope with a volume being resized,
- * so fail it.
- */
- if (!(rdc_get_vflags(urdc) & RDC_VOL_FAILED)) {
- rdc_many_enter(krdc);
- if (rdc_get_vflags(urdc) & RDC_PRIMARY)
- rdc_set_mflags(urdc, RDC_RSYNC_NEEDED);
- else
- rdc_set_mflags(urdc, RDC_SYNC_NEEDED);
- rdc_set_flags_log(urdc, RDC_VOL_FAILED,
- "volume resized");
- rdc_many_exit(krdc);
- rdc_write_state(urdc);
- }
-
- cmn_err(CE_WARN,
- "!SNDR: %s changed size from %" NSC_SZFMT " to %" NSC_SZFMT,
- nsc_pathname(dip->bi_fd), urdc->volume_size, partsize);
- }
-
- if ((rc = nsc_maxfbas(dip->bi_fd, 0, &maxfbas)) != 0) {
- cmn_err(CE_WARN,
- "!SNDR: cannot get max transfer size for %s, error %d",
- nsc_pathname(dip->bi_fd), rc);
- } else if (maxfbas > 0) {
- krdc->maxfbas = min(RDC_MAX_MAXFBAS, maxfbas);
- }
-
- return (0);
-}
-
-
-/*
- * _rdc_pinned
- *
- * only affects local node
- */
-
-static void
-_rdc_pinned(_rdc_info_dev_t *dip, nsc_off_t pos, nsc_size_t len)
-{
- nsc_pinned_data(dip->bi_krdc->iodev, pos, len);
-}
-
-
-/*
- * _rdc_unpinned
- *
- * only affects local node.
- */
-
-static void
-_rdc_unpinned(_rdc_info_dev_t *dip, nsc_off_t pos, nsc_size_t len)
-{
- nsc_unpinned_data(dip->bi_krdc->iodev, pos, len);
-}
-
-
-/*
- * _rdc_read
- *
- * read the specified data into the buffer - go remote if local down,
- * or the remote end has more recent data because an reverse sync is
- * in progress.
- */
-
-static int
-_rdc_read(rdc_buf_t *h, nsc_off_t pos, nsc_size_t len, int flag)
-{
- rdc_k_info_t *krdc = h->rdc_fd->rdc_info;
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- int remote = (RDC_REMOTE(h) || (rdc_get_mflags(urdc) & RDC_SLAVE));
- int rc1, rc2;
-
- rc1 = rc2 = 0;
-
- if (!RDC_HANDLE_LIMITS(&h->rdc_bufh, pos, len)) {
- cmn_err(CE_WARN,
- "!_rdc_read: bounds check: io(handle) pos %" NSC_XSZFMT
- "(%" NSC_XSZFMT ") len %" NSC_XSZFMT "(%" NSC_XSZFMT ")",
- pos, h->rdc_bufh.sb_pos, len, h->rdc_bufh.sb_len);
- h->rdc_bufh.sb_error = EINVAL;
- return (h->rdc_bufh.sb_error);
- }
-
- if (flag & NSC_NOBLOCK) {
- cmn_err(CE_WARN,
- "!_rdc_read: removing unsupported NSC_NOBLOCK flag");
- flag &= ~(NSC_NOBLOCK);
- }
-
-
- if (!remote) {
- rc1 = nsc_read(h->rdc_bufp, pos, len, flag);
- }
-
- if (remote || !RDC_SUCCESS(rc1)) {
- rc2 = _rdc_remote_read(krdc, &h->rdc_bufh, pos, len, flag);
- }
-
- if (remote && !RDC_SUCCESS(rc2))
- h->rdc_bufh.sb_error = rc2;
- else if (!RDC_SUCCESS(rc1) && !RDC_SUCCESS(rc2))
- h->rdc_bufh.sb_error = rc1;
-
- return (h->rdc_bufh.sb_error);
-}
-
-
-static int
-_rdc_remote_write(rdc_k_info_t *krdc, rdc_buf_t *h, nsc_buf_t *nsc_h,
- nsc_off_t pos, nsc_size_t len, int flag, uint_t bitmask)
-{
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- int rc = 0;
- nsc_size_t plen, syncblockpos;
- aio_buf_t *anon = NULL;
-
- if (!(rdc_get_vflags(urdc) & RDC_PRIMARY))
- return (EINVAL);
-
- if ((rdc_get_vflags(urdc) & RDC_LOGGING) &&
- (!IS_STATE(urdc, RDC_QUEUING))) {
- goto done;
- }
-
- /*
- * this check for RDC_SYNCING may seem redundant, but there is a window
- * in rdc_sync, where an async set has not yet been transformed into a
- * sync set.
- */
- if ((!IS_ASYNC(urdc) || IS_STATE(urdc, RDC_SYNCING)) ||
- RDC_REMOTE(h) ||
- krdc->group->synccount > 0 ||
- (rdc_get_vflags(urdc) & RDC_SLAVE) ||
- (rdc_get_vflags(urdc) & RDC_VOL_FAILED) ||
- (rdc_get_vflags(urdc) & RDC_BMP_FAILED)) {
-
- /* sync mode, or remote io mode, or local device is dead */
- rc = rdc_net_write(krdc->index, krdc->remote_index,
- nsc_h, pos, len, RDC_NOSEQ, RDC_NOQUE, NULL);
-
- if ((rc == 0) &&
- !(rdc_get_vflags(urdc) & RDC_BMP_FAILED) &&
- !(rdc_get_vflags(urdc) & RDC_VOL_FAILED)) {
- if (IS_STATE(urdc, RDC_SYNCING) &&
- !IS_STATE(urdc, RDC_FULL) ||
- !IS_STATE(urdc, RDC_SLAVE)) {
- mutex_enter(&krdc->syncbitmutex);
-
- syncblockpos = LOG_TO_FBA_NUM(krdc->syncbitpos);
-
- DTRACE_PROBE4(rdc_remote_write,
- nsc_off_t, krdc->syncbitpos,
- nsc_off_t, syncblockpos,
- nsc_off_t, pos,
- nsc_size_t, len);
-
- /*
- * If the current I/O's position plus length is
- * greater then the sync block position, only
- * clear those blocks upto sync block position
- */
- if (pos < syncblockpos) {
- if ((pos + len) > syncblockpos)
- plen = syncblockpos - pos;
- else
- plen = len;
- RDC_CLR_BITMAP(krdc, pos, plen, bitmask,
- RDC_BIT_BUMP);
- }
- mutex_exit(&krdc->syncbitmutex);
- } else {
- RDC_CLR_BITMAP(krdc, pos, len, bitmask,
- RDC_BIT_BUMP);
- }
- } else if (rc != 0) {
- rdc_group_enter(krdc);
- rdc_set_flags_log(urdc, RDC_LOGGING,
- "net write failed");
- rdc_write_state(urdc);
- if (rdc_get_vflags(urdc) & RDC_SYNCING)
- krdc->disk_status = 1;
- rdc_group_exit(krdc);
- }
- } else if (!IS_STATE(urdc, RDC_SYNCING)) {
- DTRACE_PROBE1(async_enque_start, rdc_buf_t *, h);
-
- ASSERT(krdc->group->synccount == 0);
- /* async mode */
- if ((h == NULL) || ((h->rdc_flags & RDC_ASYNC_VEC) == 0)) {
-
- rc = _rdc_enqueue_write(krdc, pos, len, flag, NULL);
-
- } else {
- anon = rdc_aio_buf_get(h, krdc->index);
- if (anon == NULL) {
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!enqueue write failed for handle %p",
- (void *) h);
-#endif
- return (EINVAL);
- }
- rc = _rdc_enqueue_write(krdc, pos, len, flag,
- anon->rdc_abufp);
-
- /*
- * get rid of the aio_buf_t now, as this
- * may not be the set that this rdc_buf
- * was allocated on, we are done with it anyways
- * enqueuing code frees the nsc_abuf
- */
- rdc_aio_buf_del(h, krdc);
- }
-
- } else {
- ASSERT(IS_STATE(urdc, RDC_SYNCING));
- ASSERT(0);
- }
-
-done:
- if ((anon == NULL) && h && (h->rdc_flags & RDC_ASYNC_VEC)) {
- /*
- * Toss the anonymous buffer if we have one allocated.
- */
- anon = rdc_aio_buf_get(h, krdc->index);
- if (anon) {
- (void) nsc_free_buf(anon->rdc_abufp);
- rdc_aio_buf_del(h, krdc);
- }
- }
-
- return (rc);
-}
-
-/*
- * _rdc_multi_write
- *
- * Send to multihop remote. Obeys 1 to many if present and we are crazy
- * enough to support it.
- *
- */
-int
-_rdc_multi_write(nsc_buf_t *h, nsc_off_t pos, nsc_size_t len, int flag,
- rdc_k_info_t *krdc)
-{
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- rdc_k_info_t *this = krdc; /* krdc that was requested */
- int rc, retval;
- uint_t bitmask;
-
- retval = rc = 0;
- if (!RDC_HANDLE_LIMITS(h, pos, len)) {
- cmn_err(CE_WARN,
- "!_rdc_multi_write: bounds check: io(handle) pos %"
- NSC_XSZFMT "(%" NSC_XSZFMT ") len %" NSC_XSZFMT "(%"
- NSC_XSZFMT ")", pos, h->sb_pos, len, h->sb_len);
- return (EINVAL);
- }
-
- /* if this is a 1 to many, set all the bits for all the sets */
- do {
- if (RDC_SET_BITMAP(krdc, pos, len, &bitmask) < 0) {
- (void) nsc_uncommit(h, pos, len, flag);
- /* set the error, but try other sets */
- retval = EIO;
- }
- if (IS_MANY(krdc) && IS_STATE(urdc, RDC_PRIMARY)) {
- rdc_many_enter(krdc);
- for (krdc = krdc->many_next; krdc != this;
- krdc = krdc->many_next) {
- urdc = &rdc_u_info[krdc->index];
- if (!IS_ENABLED(urdc))
- continue;
- break;
- }
- rdc_many_exit(krdc);
- }
- } while (krdc != this);
-
- urdc = &rdc_u_info[krdc->index];
-
- if (flag & NSC_NOBLOCK) {
- cmn_err(CE_WARN,
- "!_rdc_multi_write: removing unsupported NSC_NOBLOCK flag");
- flag &= ~(NSC_NOBLOCK);
- }
-
-multiwrite1:
- if ((rdc_get_vflags(urdc) & RDC_PRIMARY) &&
- (!IS_STATE(urdc, RDC_LOGGING) ||
- (IS_STATE(urdc, RDC_LOGGING) &&
- IS_STATE(urdc, RDC_QUEUING)))) {
- rc = _rdc_remote_write(krdc, NULL, h, pos, len, flag, bitmask);
- }
-
- if (!RDC_SUCCESS(rc) && retval == 0) {
- retval = rc;
- }
-
-multiwrite2:
- if (IS_MANY(krdc) && (rdc_get_vflags(urdc) && RDC_PRIMARY)) {
- rdc_many_enter(krdc);
- for (krdc = krdc->many_next; krdc != this;
- krdc = krdc->many_next) {
- urdc = &rdc_u_info[krdc->index];
- if (!IS_ENABLED(urdc))
- continue;
- rc = 0;
- rdc_many_exit(krdc);
-
- goto multiwrite1;
- }
- rdc_many_exit(krdc);
- }
-
- return (retval);
-}
-
-void
-_rdc_diskq_enqueue_thr(rdc_aio_t *p)
-{
- rdc_thrsync_t *sync = (rdc_thrsync_t *)p->next;
- rdc_k_info_t *krdc = &rdc_k_info[p->index];
- int rc2;
-
-
- rc2 = rdc_diskq_enqueue(krdc, p);
-
- /*
- * overload flag with error return if any
- */
- if (!RDC_SUCCESS(rc2)) {
- p->flag = rc2;
- } else {
- p->flag = 0;
- }
- mutex_enter(&sync->lock);
- sync->complete++;
- cv_broadcast(&sync->cv);
- mutex_exit(&sync->lock);
-}
-
-/*
- * _rdc_sync_write_thr
- * syncronous write thread which writes to network while
- * local write is occuring
- */
-void
-_rdc_sync_write_thr(rdc_aio_t *p)
-{
- rdc_thrsync_t *sync = (rdc_thrsync_t *)p->next;
- rdc_buf_t *h = (rdc_buf_t *)p->handle;
- rdc_k_info_t *krdc = &rdc_k_info[p->index];
-#ifdef DEBUG
- rdc_u_info_t *urdc;
-#endif
- int rc2;
- int bitmask;
-
- rdc_group_enter(krdc);
- krdc->aux_state |= RDC_AUXWRITE;
-#ifdef DEBUG
- urdc = &rdc_u_info[krdc->index];
- if (!IS_ENABLED(urdc)) {
- cmn_err(CE_WARN, "!rdc_sync_write_thr: set not enabled %s:%s",
- urdc->secondary.file,
- urdc->secondary.bitmap);
- }
-#endif
- rdc_group_exit(krdc);
- bitmask = p->iostatus; /* overload */
- rc2 = _rdc_remote_write(krdc, h, &h->rdc_bufh, p->pos, p->len,
- p->flag, bitmask);
-
-
- /*
- * overload flag with error return if any
- */
- if (!RDC_SUCCESS(rc2)) {
- p->flag = rc2;
- } else {
- p->flag = 0;
- }
-
- rdc_group_enter(krdc);
- krdc->aux_state &= ~RDC_AUXWRITE;
- rdc_group_exit(krdc);
-
- mutex_enter(&sync->lock);
- sync->complete++;
- cv_broadcast(&sync->cv);
- mutex_exit(&sync->lock);
-}
-
-/*
- * _rdc_write
- *
- * Commit changes to the buffer locally and send remote.
- *
- * If this write is whilst the local primary volume is being synced,
- * then we write the remote end first to ensure that the new data
- * cannot be overwritten by a concurrent sync operation.
- */
-
-static int
-_rdc_write(rdc_buf_t *h, nsc_off_t pos, nsc_size_t len, int flag)
-{
- rdc_k_info_t *krdc = h->rdc_fd->rdc_info;
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- rdc_k_info_t *this;
- rdc_k_info_t *multi = NULL;
- int remote = RDC_REMOTE(h);
- int rc1, rc2;
- uint_t bitmask;
- int first;
- int rsync;
- int nthr;
- int winddown;
- int thrrc = 0;
- rdc_aio_t *bp[SNDR_MAXTHREADS];
- aio_buf_t *anon;
- nsthread_t *tp;
- rdc_thrsync_t *sync = &h->rdc_sync;
-
- /* If this is the multi-hop secondary, move along to the primary */
- if (IS_MULTI(krdc) && !IS_PRIMARY(urdc)) {
- multi = krdc;
- krdc = krdc->multi_next;
- urdc = &rdc_u_info[krdc->index];
-
- if (!IS_ENABLED(urdc)) {
- krdc = h->rdc_fd->rdc_info;
- urdc = &rdc_u_info[krdc->index];
- multi = NULL;
- }
- }
- this = krdc;
-
- rsync = (IS_PRIMARY(urdc)) && (IS_SLAVE(urdc));
-
- /*
- * If this is a many group with a reverse sync in progress and
- * this is not the slave krdc/urdc, then search for the slave
- * so that we can do the remote io to the correct secondary
- * before the local io.
- */
- if (rsync && !(IS_SLAVE(urdc))) {
- rdc_many_enter(krdc);
- for (krdc = krdc->many_next; krdc != this;
- krdc = krdc->many_next) {
- urdc = &rdc_u_info[krdc->index];
- if (!IS_ENABLED(urdc))
- continue;
- if (rdc_get_vflags(urdc) & RDC_SLAVE)
- break;
- }
- rdc_many_exit(krdc);
-
- this = krdc;
- }
-
- urdc = &rdc_u_info[krdc->index];
-
- rc1 = rc2 = 0;
- first = 1;
- nthr = 0;
- if (!RDC_HANDLE_LIMITS(&h->rdc_bufh, pos, len)) {
- cmn_err(CE_WARN,
- "!_rdc_write: bounds check: io(handle) pos %" NSC_XSZFMT
- "(%" NSC_XSZFMT ") len %" NSC_XSZFMT "(%" NSC_XSZFMT ")",
- pos, h->rdc_bufh.sb_pos, len, h->rdc_bufh.sb_len);
- h->rdc_bufh.sb_error = EINVAL;
- return (h->rdc_bufh.sb_error);
- }
-
- DTRACE_PROBE(rdc_write_bitmap_start);
-
- /* if this is a 1 to many, set all the bits for all the sets */
- do {
- if (RDC_SET_BITMAP(krdc, pos, len, &bitmask) < 0) {
- if (rdc_eio_nobmp) {
- (void) nsc_uncommit
- (h->rdc_bufp, pos, len, flag);
- /* set the error, but try the other sets */
- h->rdc_bufh.sb_error = EIO;
- }
- }
-
- if (IS_MANY(krdc) && IS_STATE(urdc, RDC_PRIMARY)) {
- rdc_many_enter(krdc);
- for (krdc = krdc->many_next; krdc != this;
- krdc = krdc->many_next) {
- urdc = &rdc_u_info[krdc->index];
- if (!IS_ENABLED(urdc))
- continue;
- break;
- }
- rdc_many_exit(krdc);
- }
-
- } while (krdc != this);
-
- urdc = &rdc_u_info[krdc->index];
-
- DTRACE_PROBE(rdc_write_bitmap_end);
-
-write1:
- /* just in case we switch mode during write */
- if (IS_ASYNC(urdc) && (!IS_STATE(urdc, RDC_SYNCING)) &&
- (!IS_STATE(urdc, RDC_LOGGING) ||
- IS_STATE(urdc, RDC_QUEUING))) {
- h->rdc_flags |= RDC_ASYNC_BUF;
- }
- if (BUF_IS_ASYNC(h)) {
- /*
- * We are async mode
- */
- aio_buf_t *p;
- DTRACE_PROBE(rdc_write_async_start);
-
- if ((krdc->type_flag & RDC_DISABLEPEND) ||
- ((IS_STATE(urdc, RDC_LOGGING) &&
- !IS_STATE(urdc, RDC_QUEUING)))) {
- goto localwrite;
- }
- if (IS_STATE(urdc, RDC_VOL_FAILED)) {
- /*
- * overload remote as we don't want to do local
- * IO later. forge ahead with async
- */
- remote++;
- }
- if ((IS_STATE(urdc, RDC_SYNCING)) ||
- (IS_STATE(urdc, RDC_LOGGING) &&
- !IS_STATE(urdc, RDC_QUEUING))) {
- goto localwrite;
- }
-
- p = rdc_aio_buf_add(krdc->index, h);
- if (p == NULL) {
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!rdc_alloc_buf aio_buf allocation failed");
-#endif
- goto localwrite;
- }
-
- mutex_enter(&h->aio_lock);
-
- DTRACE_PROBE(rdc_write_async__allocabuf_start);
- rc1 = nsc_alloc_abuf(pos, len, 0, &p->rdc_abufp);
- DTRACE_PROBE(rdc_write_async__allocabuf_end);
- if (!RDC_SUCCESS(rc1)) {
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!rdc_alloc_buf NSC_ANON allocation failed rc %d",
- rc1);
-#endif
- mutex_exit(&h->aio_lock);
- goto localwrite;
- }
- h->rdc_flags |= RDC_ASYNC_VEC;
- mutex_exit(&h->aio_lock);
-
- /*
- * Copy buffer into anonymous buffer
- */
-
- DTRACE_PROBE(rdc_write_async_nsccopy_start);
- rc1 =
- nsc_copy(&h->rdc_bufh, p->rdc_abufp, pos, pos, len);
- DTRACE_PROBE(rdc_write_async_nsccopy_end);
- if (!RDC_SUCCESS(rc1)) {
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!_rdc_write: nsc_copy failed rc=%d state %x",
- rc1, rdc_get_vflags(urdc));
-#endif
- rc1 = nsc_free_buf(p->rdc_abufp);
- rdc_aio_buf_del(h, krdc);
- rdc_group_enter(krdc);
- rdc_group_log(krdc, RDC_FLUSH|RDC_OTHERREMOTE,
- "nsc_copy failure");
- rdc_group_exit(krdc);
- }
- DTRACE_PROBE(rdc_write_async_end);
-
- /*
- * using a diskq, launch a thread to queue it
- * and free the aio->h and aio
- * if the thread fails, do it the old way (see localwrite)
- */
-
- if (RDC_IS_DISKQ(krdc->group)) {
-
- if (nthr >= SNDR_MAXTHREADS) {
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!nthr overrun in _rdc_write");
-#endif
- thrrc = ENOEXEC;
- goto localwrite;
- }
-
- anon = rdc_aio_buf_get(h, krdc->index);
- if (anon == NULL) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!rdc_aio_buf_get failed for "
- "%p", (void *)h);
-#endif
- thrrc = ENOEXEC;
- goto localwrite;
- }
-
- /* get a populated rdc_aio_t */
- bp[nthr] =
- rdc_aio_tbuf_get(sync, anon->rdc_abufp, pos, len,
- flag, krdc->index, bitmask);
-
- if (bp[nthr] == NULL) {
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!_rdcwrite: "
- "kmem_alloc failed bp aio (1)");
-#endif
- thrrc = ENOEXEC;
- goto localwrite;
- }
- /* start the queue io */
- tp = nst_create(_rdc_ioset, _rdc_diskq_enqueue_thr,
- (void *)bp[nthr], NST_SLEEP);
-
- if (tp == NULL) {
-#ifdef DEBUG
- cmn_err(CE_NOTE,
- "!_rdcwrite: nst_create failure");
-#endif
- thrrc = ENOEXEC;
- } else {
- mutex_enter(&(sync->lock));
- sync->threads++;
- mutex_exit(&(sync->lock));
- nthr++;
-
- }
- /*
- * the handle that is to be enqueued is now in
- * the rdc_aio_t, and will be freed there.
- * dump the aio_t now. If this is 1 to many
- * we may not do this in _rdc_free_buf()
- * if this was not the index that the rdc_buf_t
- * was allocated on.
- */
- rdc_aio_buf_del(h, krdc);
-
- }
- } /* end of async */
-
- /*
- * We try to overlap local and network IO for the sync case
- * (we already do it for async)
- * If one to many, we need to track the resulting nst_thread
- * so we don't trash the nsc_buf on a free
- * Start network IO first then do local (sync only)
- */
-
- if (IS_PRIMARY(urdc) && !IS_STATE(urdc, RDC_LOGGING) &&
- !BUF_IS_ASYNC(h)) {
- /*
- * if forward syncing, we must do local IO first
- * then remote io. Don't spawn thread
- */
- if (!rsync && (IS_STATE(urdc, RDC_SYNCING))) {
- thrrc = ENOEXEC;
- goto localwrite;
- }
- if (IS_MULTI(krdc)) {
- rdc_k_info_t *ktmp;
- rdc_u_info_t *utmp;
-
- ktmp = krdc->multi_next;
- utmp = &rdc_u_info[ktmp->index];
- if (IS_ENABLED(utmp))
- multi = ktmp;
- }
- if (nthr >= SNDR_MAXTHREADS) {
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!nthr overrun in _rdc_write");
-#endif
- thrrc = ENOEXEC;
- goto localwrite;
- }
-
- bp[nthr] = rdc_aio_tbuf_get(sync, h, pos, len,
- flag, krdc->index, bitmask);
-
- if (bp[nthr] == NULL) {
- thrrc = ENOEXEC;
- goto localwrite;
- }
- tp = nst_create(_rdc_ioset, _rdc_sync_write_thr,
- (void *)bp[nthr], NST_SLEEP);
- if (tp == NULL) {
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!_rdcwrite: nst_create failure");
-#endif
- thrrc = ENOEXEC;
- } else {
- mutex_enter(&(sync->lock));
- sync->threads++;
- mutex_exit(&(sync->lock));
- nthr++;
- }
- }
-localwrite:
- if (!remote && !rsync && first) {
- DTRACE_PROBE(rdc_write_nscwrite_start);
- rc1 = nsc_write(h->rdc_bufp, pos, len, flag);
- DTRACE_PROBE(rdc_write_nscwrite_end);
- if (!RDC_SUCCESS(rc1)) {
- rdc_many_enter(krdc);
- if (IS_PRIMARY(urdc))
- /* Primary, so reverse sync needed */
- rdc_set_mflags(urdc, RDC_RSYNC_NEEDED);
- else
- /* Secondary, so sync needed */
- rdc_set_flags(urdc, RDC_SYNC_NEEDED);
- rdc_set_flags_log(urdc, RDC_VOL_FAILED,
- "local write failed");
- rdc_many_exit(krdc);
- rdc_write_state(urdc);
- }
- }
-
- /*
- * This is where we either enqueue async IO for the flusher
- * or do sync IO in the case of an error in thread creation
- * or we are doing a forward sync
- * NOTE: if we are async, and using a diskq, we have
- * already enqueued this write.
- * _rdc_remote_write will end up enqueuueing to memory,
- * or in case of a thread creation error above, try again
- * enqueue the diskq write if thrrc == ENOEXEC
- */
- if ((IS_PRIMARY(urdc)) && (thrrc == ENOEXEC) ||
- (BUF_IS_ASYNC(h) && !RDC_IS_DISKQ(krdc->group))) {
- thrrc = 0;
- if (IS_MULTI(krdc)) {
- rdc_k_info_t *ktmp;
- rdc_u_info_t *utmp;
-
- ktmp = krdc->multi_next;
- utmp = &rdc_u_info[ktmp->index];
- if (IS_ENABLED(utmp))
- multi = ktmp;
- }
-
- DTRACE_PROBE(rdc_write_remote_start);
-
- rc2 = _rdc_remote_write(krdc, h, &h->rdc_bufh,
- pos, len, flag, bitmask);
-
- DTRACE_PROBE(rdc_rdcwrite_remote_end);
- }
-
- if (!RDC_SUCCESS(rc1)) {
- if ((IS_PRIMARY(urdc)) && !RDC_SUCCESS(rc2)) {
- h->rdc_bufh.sb_error = rc1;
- }
- } else if ((remote || rsync) && !RDC_SUCCESS(rc2)) {
- h->rdc_bufh.sb_error = rc2;
- }
-write2:
- /*
- * If one to many, jump back into the loop to continue IO
- */
- if (IS_MANY(krdc) && (IS_PRIMARY(urdc))) {
- rdc_many_enter(krdc);
- for (krdc = krdc->many_next; krdc != this;
- krdc = krdc->many_next) {
- urdc = &rdc_u_info[krdc->index];
- if (!IS_ENABLED(urdc))
- continue;
- rc2 = first = 0;
- h->rdc_flags &= ~RDC_ASYNC_BUF;
- rdc_many_exit(krdc);
- goto write1;
- }
- rdc_many_exit(krdc);
- }
- urdc = &rdc_u_info[krdc->index];
-
- /*
- * collect all of our threads if any
- */
- if (nthr) {
-
- mutex_enter(&(sync->lock));
- /* wait for the threads */
- while (sync->complete != sync->threads) {
- cv_wait(&(sync->cv), &(sync->lock));
- }
- mutex_exit(&(sync->lock));
-
- /* collect status */
-
- winddown = 0;
- while (winddown < nthr) {
- /*
- * Get any error return from thread
- */
- if ((remote || rsync) && bp[winddown]->flag) {
- h->rdc_bufh.sb_error = bp[winddown]->flag;
- }
- if (bp[winddown])
- kmem_free(bp[winddown], sizeof (rdc_aio_t));
- winddown++;
- }
- }
-
- if (rsync && !(IS_STATE(urdc, RDC_VOL_FAILED))) {
- rc1 = nsc_write(h->rdc_bufp, pos, len, flag);
- if (!RDC_SUCCESS(rc1)) {
- /* rsync, so reverse sync needed already set */
- rdc_many_enter(krdc);
- rdc_set_flags_log(urdc, RDC_VOL_FAILED,
- "rsync local write failed");
- rdc_many_exit(krdc);
- rdc_write_state(urdc);
-
- /*
- * only report the error if a remote error
- * occurred as well.
- */
- if (h->rdc_bufh.sb_error)
- h->rdc_bufh.sb_error = rc1;
- }
- }
-
- if (multi) {
- /* Multi-hop secondary, just set bits in the bitmap */
- (void) RDC_SET_BITMAP(multi, pos, len, &bitmask);
- }
-
- return (h->rdc_bufh.sb_error);
-}
-
-
-static void
-_rdc_bzero(nsc_buf_t *h, nsc_off_t pos, nsc_size_t len)
-{
- nsc_vec_t *v;
- uchar_t *a;
- size_t sz;
- int l;
-
- if (!RDC_HANDLE_LIMITS(h, pos, len)) {
- cmn_err(CE_WARN,
- "!_rdc_bzero: bounds check: io(handle) pos %" NSC_XSZFMT
- "(%" NSC_XSZFMT ") len %" NSC_XSZFMT "(%" NSC_XSZFMT ")",
- pos, h->sb_pos, len, h->sb_len);
- return;
- }
-
- if (!len)
- return;
-
- /* find starting point */
-
- v = h->sb_vec;
- pos -= h->sb_pos;
-
- for (; pos >= FBA_NUM(v->sv_len); v++)
- pos -= FBA_NUM(v->sv_len);
-
- a = v->sv_addr + FBA_SIZE(pos);
- l = v->sv_len - FBA_SIZE(pos);
-
- /* zero */
-
- len = FBA_SIZE(len); /* convert to bytes */
-
- while (len) {
- if (!a) /* end of vec */
- break;
-
- sz = (size_t)min((nsc_size_t)l, len);
-
- bzero(a, sz);
-
- len -= sz;
- l -= sz;
- a += sz;
-
- if (!l) {
- v++;
- a = v->sv_addr;
- l = v->sv_len;
- }
- }
-}
-
-
-/*
- * _rdc_zero
- *
- * Zero and commit the specified area of the buffer.
- *
- * If this write is whilst the local primary volume is being synced,
- * then we write the remote end first to ensure that the new data
- * cannot be overwritten by a concurrent sync operation.
- */
-
-static int
-_rdc_zero(rdc_buf_t *h, nsc_off_t pos, nsc_size_t len, int flag)
-{
- rdc_k_info_t *krdc = h->rdc_fd->rdc_info;
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- rdc_k_info_t *this;
- rdc_k_info_t *multi = NULL;
- int remote = RDC_REMOTE(h);
- int rc1, rc2;
- uint_t bitmask;
- int first;
- int rsync;
-
- /* If this is the multi-hop secondary, move along to the primary */
- if (IS_MULTI(krdc) && !(rdc_get_vflags(urdc) & RDC_PRIMARY)) {
- multi = krdc;
- krdc = krdc->multi_next;
- urdc = &rdc_u_info[krdc->index];
-
- if (!IS_ENABLED(urdc)) {
- krdc = h->rdc_fd->rdc_info;
- urdc = &rdc_u_info[krdc->index];
- multi = NULL;
- }
- }
- this = krdc;
-
- rsync = ((rdc_get_vflags(urdc) & RDC_PRIMARY) &&
- (rdc_get_mflags(urdc) & RDC_SLAVE));
-
- /*
- * If this is a many group with a reverse sync in progress and
- * this is not the slave krdc/urdc, then search for the slave
- * so that we can do the remote io to the correct secondary
- * before the local io.
- */
- if (rsync && !(rdc_get_vflags(urdc) & RDC_SLAVE)) {
- rdc_many_enter(krdc);
- for (krdc = krdc->many_next; krdc != this;
- krdc = krdc->many_next) {
- urdc = &rdc_u_info[krdc->index];
- if (!IS_ENABLED(urdc))
- continue;
- if (rdc_get_vflags(urdc) & RDC_SLAVE)
- break;
- }
- rdc_many_exit(krdc);
-
- this = krdc;
- }
-
- rc1 = rc2 = 0;
- first = 1;
-
- if (!RDC_HANDLE_LIMITS(&h->rdc_bufh, pos, len)) {
- cmn_err(CE_WARN,
- "!_rdc_zero: bounds check: io(handle) pos %" NSC_XSZFMT
- "(%" NSC_XSZFMT ") len %" NSC_XSZFMT "(%" NSC_XSZFMT ")",
- pos, h->rdc_bufh.sb_pos, len, h->rdc_bufh.sb_len);
- h->rdc_bufh.sb_error = EINVAL;
- return (h->rdc_bufh.sb_error);
- }
-
-zero1:
- if (RDC_SET_BITMAP(krdc, pos, len, &bitmask) < 0) {
- (void) nsc_uncommit(h->rdc_bufp, pos, len, flag);
- h->rdc_bufh.sb_error = EIO;
- goto zero2;
- }
-
- if (IS_ASYNC(urdc)) {
- /*
- * We are async mode
- */
- aio_buf_t *p;
-
- if ((krdc->type_flag & RDC_DISABLEPEND) ||
- (rdc_get_vflags(urdc) & RDC_LOGGING)) {
- mutex_exit(&krdc->group->ra_queue.net_qlock);
- goto localzero;
- }
-
- if ((rdc_get_vflags(urdc) & RDC_VOL_FAILED) ||
- (rdc_get_vflags(urdc) & RDC_BMP_FAILED)) {
- mutex_exit(&krdc->group->ra_queue.net_qlock);
- goto zero2;
- }
- if (rdc_get_vflags(urdc) & RDC_LOGGING) {
- mutex_exit(&krdc->group->ra_queue.net_qlock);
- goto localzero;
- }
- p = rdc_aio_buf_add(krdc->index, h);
- if (p == NULL) {
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!rdc_alloc_buf aio_buf allocation failed");
-#endif
- goto localzero;
- }
- mutex_enter(&h->aio_lock);
- rc1 = nsc_alloc_abuf(pos, len, 0, &p->rdc_abufp);
- if (!RDC_SUCCESS(rc1)) {
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!rdc_alloc_buf NSC_ANON allocation failed rc %d",
- rc1);
-#endif
- mutex_exit(&h->aio_lock);
- goto localzero;
- }
- h->rdc_flags |= RDC_ASYNC_VEC;
- mutex_exit(&h->aio_lock);
-
- /*
- * Copy buffer into anonymous buffer
- */
-
- rc1 = nsc_zero(p->rdc_abufp, pos, len, flag);
- if (!RDC_SUCCESS(rc1)) {
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!_rdc_zero: nsc_zero failed rc=%d state %x",
- rc1, rdc_get_vflags(urdc));
-#endif
- rc1 = nsc_free_buf(p->rdc_abufp);
- rdc_aio_buf_del(h, krdc);
- rdc_group_enter(krdc);
- rdc_group_log(krdc, RDC_FLUSH | RDC_OTHERREMOTE,
- "nsc_zero failed");
- rdc_group_exit(krdc);
- }
- } /* end of async */
-
-localzero:
-
- if (flag & NSC_NOBLOCK) {
- cmn_err(CE_WARN,
- "!_rdc_zero: removing unsupported NSC_NOBLOCK flag");
- flag &= ~(NSC_NOBLOCK);
- }
-
- if (!remote && !rsync && first) {
- rc1 = nsc_zero(h->rdc_bufp, pos, len, flag);
- if (!RDC_SUCCESS(rc1)) {
- ASSERT(rdc_get_vflags(urdc) & RDC_PRIMARY);
- rdc_many_enter(krdc);
- /* Primary, so reverse sync needed */
- rdc_set_mflags(urdc, RDC_RSYNC_NEEDED);
- rdc_set_flags_log(urdc, RDC_VOL_FAILED,
- "nsc_zero failed");
- rdc_many_exit(krdc);
- rdc_write_state(urdc);
- }
- }
-
- /*
- * send new data to remote end - nsc_zero has zero'd
- * the data in the buffer, or _rdc_bzero will be used below.
- */
-
- if (rdc_get_vflags(urdc) & RDC_PRIMARY) {
- if (first && (remote || rsync || !RDC_SUCCESS(rc1))) {
- /* bzero so that we can send new data to remote node */
- _rdc_bzero(&h->rdc_bufh, pos, len);
- }
-
- if (IS_MULTI(krdc)) {
- rdc_k_info_t *ktmp;
- rdc_u_info_t *utmp;
-
- ktmp = krdc->multi_next;
- utmp = &rdc_u_info[ktmp->index];
- if (IS_ENABLED(utmp))
- multi = ktmp;
- }
-
- rc2 = _rdc_remote_write(krdc, h, &h->rdc_bufh,
- pos, len, flag, bitmask);
- }
-
- if (!RDC_SUCCESS(rc1)) {
- if ((rdc_get_vflags(urdc) & RDC_PRIMARY) && !RDC_SUCCESS(rc2)) {
- h->rdc_bufh.sb_error = rc1;
- }
- } else if ((remote || rsync) && !RDC_SUCCESS(rc2)) {
- h->rdc_bufh.sb_error = rc2;
- }
-
-zero2:
- if (IS_MANY(krdc) && (rdc_get_vflags(urdc) && RDC_PRIMARY)) {
- rdc_many_enter(krdc);
- for (krdc = krdc->many_next; krdc != this;
- krdc = krdc->many_next) {
- urdc = &rdc_u_info[krdc->index];
- if (!IS_ENABLED(urdc))
- continue;
- rc2 = first = 0;
- rdc_many_exit(krdc);
- goto zero1;
- }
- rdc_many_exit(krdc);
- }
-
- if (rsync && !(rdc_get_vflags(urdc) & RDC_VOL_FAILED)) {
- rc1 = nsc_write(h->rdc_bufp, pos, len, flag);
- if (!RDC_SUCCESS(rc1)) {
- /* rsync, so reverse sync needed already set */
- rdc_many_enter(krdc);
- rdc_set_flags_log(urdc, RDC_VOL_FAILED,
- "nsc_write failed");
- rdc_many_exit(krdc);
- rdc_write_state(urdc);
-
- /*
- * only report the error if a remote error
- * occurred as well.
- */
- if (h->rdc_bufh.sb_error)
- h->rdc_bufh.sb_error = rc1;
- }
- }
-
- if (multi) {
- /* Multi-hop secondary, just set bits in the bitmap */
- (void) RDC_SET_BITMAP(multi, pos, len, &bitmask);
- }
-
- return (h->rdc_bufh.sb_error);
-}
-
-
-/*
- * _rdc_uncommit
- * - refresh specified data region in the buffer to prevent the cache
- * serving the scribbled on data back to another client.
- *
- * Only needs to happen on the local node. If in remote io mode, then
- * just return 0 - we do not cache the data on the local node and the
- * changed data will not have made it to the cache on the other node,
- * so it has no need to uncommit.
- */
-
-static int
-_rdc_uncommit(rdc_buf_t *h, nsc_off_t pos, nsc_size_t len, int flag)
-{
- int remote = RDC_REMOTE(h);
- int rc = 0;
-
- if (!RDC_HANDLE_LIMITS(&h->rdc_bufh, pos, len)) {
- cmn_err(CE_WARN,
- "!_rdc_uncommit: bounds check: io(handle) pos %" NSC_XSZFMT
- "(%" NSC_XSZFMT ") len %" NSC_XSZFMT "(%" NSC_XSZFMT ")",
- pos, h->rdc_bufh.sb_pos, len, h->rdc_bufh.sb_len);
- h->rdc_bufh.sb_error = EINVAL;
- return (h->rdc_bufh.sb_error);
- }
-
- if (flag & NSC_NOBLOCK) {
- cmn_err(CE_WARN,
- "!_rdc_uncommit: removing unsupported NSC_NOBLOCK flag");
- flag &= ~(NSC_NOBLOCK);
- }
-
- if (!remote) {
- rc = nsc_uncommit(h->rdc_bufp, pos, len, flag);
- }
-
- if (!RDC_SUCCESS(rc))
- h->rdc_bufh.sb_error = rc;
-
- return (rc);
-}
-
-
-/*
- * _rdc_trksize
- *
- * only needs to happen on local node.
- */
-
-static int
-_rdc_trksize(rdc_fd_t *rfd, nsc_size_t trksize)
-{
- return (nsc_set_trksize(RDC_FD(rfd), trksize));
-}
-
-
-static nsc_def_t _rdc_fd_def[] = {
- "Attach", (uintptr_t)_rdc_attach_fd, 0,
- "Pinned", (uintptr_t)_rdc_pinned, 0,
- "Unpinned", (uintptr_t)_rdc_unpinned, 0,
- 0, 0, 0
-};
-
-
-static nsc_def_t _rdc_io_def[] = {
- "Open", (uintptr_t)_rdc_openc, 0,
- "Close", (uintptr_t)_rdc_close, 0,
- "Attach", (uintptr_t)_rdc_attach, 0,
- "Detach", (uintptr_t)_rdc_detach, 0,
- "AllocHandle", (uintptr_t)_rdc_alloc_handle, 0,
- "FreeHandle", (uintptr_t)_rdc_free_handle, 0,
- "AllocBuf", (uintptr_t)_rdc_alloc_buf, 0,
- "FreeBuf", (uintptr_t)_rdc_free_buf, 0,
- "GetPinned", (uintptr_t)_rdc_get_pinned, 0,
- "Discard", (uintptr_t)_rdc_discard_pinned, 0,
- "PartSize", (uintptr_t)_rdc_partsize, 0,
- "MaxFbas", (uintptr_t)_rdc_maxfbas, 0,
- "Control", (uintptr_t)_rdc_control, 0,
- "Read", (uintptr_t)_rdc_read, 0,
- "Write", (uintptr_t)_rdc_write, 0,
- "Zero", (uintptr_t)_rdc_zero, 0,
- "Uncommit", (uintptr_t)_rdc_uncommit, 0,
- "TrackSize", (uintptr_t)_rdc_trksize, 0,
- "Provide", 0, 0,
- 0, 0, 0
-};
-
-static nsc_def_t _rdc_ior_def[] = {
- "Open", (uintptr_t)_rdc_openr, 0,
- "Close", (uintptr_t)_rdc_close, 0,
- "Attach", (uintptr_t)_rdc_attach, 0,
- "Detach", (uintptr_t)_rdc_detach, 0,
- "AllocHandle", (uintptr_t)_rdc_alloc_handle, 0,
- "FreeHandle", (uintptr_t)_rdc_free_handle, 0,
- "AllocBuf", (uintptr_t)_rdc_alloc_buf, 0,
- "FreeBuf", (uintptr_t)_rdc_free_buf, 0,
- "GetPinned", (uintptr_t)_rdc_get_pinned, 0,
- "Discard", (uintptr_t)_rdc_discard_pinned, 0,
- "PartSize", (uintptr_t)_rdc_partsize, 0,
- "MaxFbas", (uintptr_t)_rdc_maxfbas, 0,
- "Control", (uintptr_t)_rdc_control, 0,
- "Read", (uintptr_t)_rdc_read, 0,
- "Write", (uintptr_t)_rdc_write, 0,
- "Zero", (uintptr_t)_rdc_zero, 0,
- "Uncommit", (uintptr_t)_rdc_uncommit, 0,
- "TrackSize", (uintptr_t)_rdc_trksize, 0,
- "Provide", 0, 0,
- 0, 0, 0
-};
diff --git a/usr/src/uts/common/avs/ns/rdc/rdc_diskq.c b/usr/src/uts/common/avs/ns/rdc/rdc_diskq.c
deleted file mode 100644
index b01866c9cc..0000000000
--- a/usr/src/uts/common/avs/ns/rdc/rdc_diskq.c
+++ /dev/null
@@ -1,3252 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/ksynch.h>
-#include <sys/cmn_err.h>
-#include <sys/kmem.h>
-#include <sys/stat.h>
-#include <sys/errno.h>
-
-#include "../solaris/nsc_thread.h"
-#ifdef DS_DDICT
-#include "../contract.h"
-#endif
-#include <sys/nsctl/nsctl.h>
-
-#include <sys/kmem.h>
-#include <sys/ddi.h>
-
-#include <sys/sdt.h> /* dtrace is S10 or later */
-
-#include "rdc_io.h"
-#include "rdc_bitmap.h"
-#include "rdc_diskq.h"
-#include "rdc_clnt.h"
-
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_k.h>
-#include <sys/unistat/spcs_errors.h>
-
-extern nsc_io_t *_rdc_io_hc;
-
-int rdc_diskq_coalesce = 0;
-
-int
-_rdc_rsrv_diskq(rdc_group_t *group)
-{
- int rc = 0;
-
- mutex_enter(&group->diskqmutex);
- if (group->diskqfd == NULL) {
- mutex_exit(&group->diskqmutex);
- return (EIO);
- } else if ((group->diskqrsrv == 0) &&
- (rc = nsc_reserve(group->diskqfd, 0)) != 0) {
- cmn_err(CE_WARN,
- "!rdc: nsc_reserve(%s) failed %d\n",
- nsc_pathname(group->diskqfd), rc);
- } else {
- group->diskqrsrv++;
- }
-
- mutex_exit(&group->diskqmutex);
- return (rc);
-}
-
-void
-_rdc_rlse_diskq(rdc_group_t *group)
-{
- mutex_enter(&group->diskqmutex);
- if (group->diskqrsrv > 0 && --group->diskqrsrv == 0) {
- nsc_release(group->diskqfd);
- }
- mutex_exit(&group->diskqmutex);
-}
-
-void
-rdc_wait_qbusy(disk_queue *q)
-{
- ASSERT(MUTEX_HELD(QLOCK(q)));
- while (q->busycnt > 0)
- cv_wait(&q->busycv, QLOCK(q));
-}
-
-void
-rdc_set_qbusy(disk_queue *q)
-{
- ASSERT(MUTEX_HELD(QLOCK(q)));
- q->busycnt++;
-}
-
-void
-rdc_clr_qbusy(disk_queue *q)
-{
- ASSERT(MUTEX_HELD(QLOCK(q)));
- q->busycnt--;
- if (q->busycnt == 0)
- cv_broadcast(&q->busycv);
-}
-
-int
-rdc_lookup_diskq(char *pathname)
-{
- rdc_u_info_t *urdc;
-#ifdef DEBUG
- rdc_k_info_t *krdc;
-#endif
- int index;
-
- for (index = 0; index < rdc_max_sets; index++) {
- urdc = &rdc_u_info[index];
-#ifdef DEBUG
- krdc = &rdc_k_info[index];
-#endif
- ASSERT(krdc->index == index);
- ASSERT(urdc->index == index);
- if (!IS_ENABLED(urdc))
- continue;
-
- if (strncmp(pathname, urdc->disk_queue,
- NSC_MAXPATH) == 0)
- return (index);
- }
-
- return (-1);
-}
-
-void
-rdc_unintercept_diskq(rdc_group_t *grp)
-{
- if (!RDC_IS_DISKQ(grp))
- return;
- if (grp->q_tok)
- (void) nsc_unregister_path(grp->q_tok, 0);
- grp->q_tok = NULL;
-}
-
-void
-rdc_close_diskq(rdc_group_t *grp)
-{
-
- if (grp == NULL) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!rdc_close_diskq: NULL group!");
-#endif
- return;
- }
-
- if (grp->diskqfd) {
- if (nsc_close(grp->diskqfd) != 0) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!nsc_close on diskq failed");
-#else
- ;
- /*EMPTY*/
-#endif
- }
- grp->diskqfd = 0;
- grp->diskqrsrv = 0;
- }
- bzero(&grp->diskq.disk_hdr, sizeof (diskq_header));
-}
-
-/*
- * nsc_open the diskq and attach
- * the nsc_fd to krdc->diskqfd
- */
-int
-rdc_open_diskq(rdc_k_info_t *krdc)
-{
- rdc_u_info_t *urdc;
- rdc_group_t *grp;
- int sts;
- nsc_size_t size;
- char *diskqname;
- int mutexheld = 0;
-
- grp = krdc->group;
- urdc = &rdc_u_info[krdc->index];
-
- mutex_enter(&grp->diskqmutex);
- mutexheld++;
- if (urdc->disk_queue[0] == '\0') {
- goto fail;
- }
-
- diskqname = &urdc->disk_queue[0];
-
- if (grp->diskqfd == NULL) {
- grp->diskqfd = nsc_open(diskqname,
- NSC_RDCHR_ID|NSC_DEVICE|NSC_WRITE, 0, 0, 0);
- if (grp->diskqfd == NULL) {
- cmn_err(CE_WARN, "!rdc_open_diskq: Unable to open %s",
- diskqname);
- goto fail;
- }
- }
- if (!grp->q_tok)
- grp->q_tok = nsc_register_path(urdc->disk_queue,
- NSC_DEVICE | NSC_CACHE, _rdc_io_hc);
-
- grp->diskqrsrv = 0; /* init reserve count */
-
- mutex_exit(&grp->diskqmutex);
- mutexheld--;
- /* just test a reserve release */
- sts = _rdc_rsrv_diskq(grp);
- if (!RDC_SUCCESS(sts)) {
- cmn_err(CE_WARN, "!rdc_open_diskq: Reserve failed for %s",
- diskqname);
- goto fail;
- }
- sts = nsc_partsize(grp->diskqfd, &size);
- _rdc_rlse_diskq(grp);
-
- if ((sts == 0) && (size < 1)) {
- rdc_unintercept_diskq(grp);
- rdc_close_diskq(grp);
- goto fail;
- }
-
- return (0);
-
-fail:
- bzero(&urdc->disk_queue, NSC_MAXPATH);
- if (mutexheld)
- mutex_exit(&grp->diskqmutex);
- return (-1);
-
-}
-
-/*
- * rdc_count_vecs
- * simply vec++'s until sb_addr is null
- * returns number of vectors encountered
- */
-int
-rdc_count_vecs(nsc_vec_t *vec)
-{
- nsc_vec_t *vecp;
- int i = 0;
- vecp = vec;
- while (vecp->sv_addr) {
- vecp++;
- i++;
- }
- return (i+1);
-}
-/*
- * rdc_setid2idx
- * given setid, return index
- */
-int
-rdc_setid2idx(int setid)
-{
-
- int index = 0;
-
- for (index = 0; index < rdc_max_sets; index++) {
- if (rdc_u_info[index].setid == setid)
- break;
- }
- if (index >= rdc_max_sets)
- index = -1;
- return (index);
-}
-
-/*
- * rdc_idx2setid
- * given an index, return its setid
- */
-int
-rdc_idx2setid(int index)
-{
- return (rdc_u_info[index].setid);
-}
-
-/*
- * rdc_fill_ioheader
- * fill in all the stuff you want to save on disk
- * at the beginnig of each queued write
- */
-void
-rdc_fill_ioheader(rdc_aio_t *aio, io_hdr *hd, int qpos)
-{
- ASSERT(MUTEX_HELD(&rdc_k_info[aio->index].group->diskq.disk_qlock));
-
- hd->dat.magic = RDC_IOHDR_MAGIC;
- hd->dat.type = RDC_QUEUEIO;
- hd->dat.pos = aio->pos;
- hd->dat.hpos = aio->pos;
- hd->dat.qpos = qpos;
- hd->dat.len = aio->len;
- hd->dat.flag = aio->flag;
- hd->dat.iostatus = aio->iostatus;
- hd->dat.setid = rdc_idx2setid(aio->index);
- hd->dat.time = nsc_time();
- if (!aio->handle)
- hd->dat.flag |= RDC_NULL_BUF; /* no real data to queue */
-}
-
-/*
- * rdc_dump_iohdrs
- * give back the iohdr list
- * and clear out q->lastio
- */
-void
-rdc_dump_iohdrs(disk_queue *q)
-{
- io_hdr *p, *r;
-
- ASSERT(MUTEX_HELD(QLOCK(q)));
-
- p = q->iohdrs;
- while (p) {
- r = p->dat.next;
- kmem_free(p, sizeof (*p));
- q->hdrcnt--;
- p = r;
- }
- q->iohdrs = q->hdr_last = NULL;
- q->hdrcnt = 0;
- if (q->lastio->handle)
- (void) nsc_free_buf(q->lastio->handle);
- bzero(&(*q->lastio), sizeof (*q->lastio));
-}
-
-/*
- * rdc_fail_diskq
- * set flags, throw away q info
- * clean up what you can
- * wait for flusher threads to stop (taking into account this may be one)
- * takes group_lock, so conf, many, and bitmap may not be held
- */
-void
-rdc_fail_diskq(rdc_k_info_t *krdc, int wait, int flag)
-{
- rdc_k_info_t *p;
- rdc_u_info_t *q = &rdc_u_info[krdc->index];
- rdc_group_t *group = krdc->group;
- disk_queue *dq = &krdc->group->diskq;
-
- if (IS_STATE(q, RDC_DISKQ_FAILED))
- return;
-
- if (!(flag & RDC_NOFAIL))
- cmn_err(CE_WARN, "!disk queue %s failure", q->disk_queue);
-
- if (flag & RDC_DOLOG) {
- rdc_group_enter(krdc);
- rdc_group_log(krdc, RDC_NOFLUSH | RDC_ALLREMOTE,
- "disk queue failed");
- rdc_group_exit(krdc);
- }
- mutex_enter(QHEADLOCK(dq));
- mutex_enter(QLOCK(dq));
- /*
- * quick stop of the flushers
- * other cleanup is done on the un-failing of the diskq
- */
- SET_QHEAD(dq, RDC_DISKQ_DATA_OFF);
- SET_QTAIL(dq, RDC_DISKQ_DATA_OFF);
- SET_QNXTIO(dq, RDC_DISKQ_DATA_OFF);
- SET_LASTQTAIL(dq, 0);
-
- rdc_dump_iohdrs(dq);
-
- mutex_exit(QLOCK(dq));
- mutex_exit(QHEADLOCK(dq));
-
- bzero(krdc->bitmap_ref, krdc->bitmap_size * BITS_IN_BYTE *
- BMAP_REF_PREF_SIZE);
-
- if (flag & RDC_DOLOG) /* otherwise, we already have the conf lock */
- rdc_group_enter(krdc);
-
- else if (!(flag & RDC_GROUP_LOCKED))
- ASSERT(MUTEX_HELD(&rdc_conf_lock));
-
- if (!(flag & RDC_NOFAIL)) {
- rdc_set_flags(q, RDC_DISKQ_FAILED);
- }
- rdc_clr_flags(q, RDC_QUEUING);
-
- for (p = krdc->group_next; p != krdc; p = p->group_next) {
- q = &rdc_u_info[p->index];
- if (!IS_ENABLED(q))
- continue;
- if (!(flag & RDC_NOFAIL)) {
- rdc_set_flags(q, RDC_DISKQ_FAILED);
- }
- rdc_clr_flags(q, RDC_QUEUING);
- bzero(p->bitmap_ref, p->bitmap_size * BITS_IN_BYTE *
- BMAP_REF_PREF_SIZE);
- /* RDC_QUEUING is cleared in group_log() */
- }
-
- if (flag & RDC_DOLOG)
- rdc_group_exit(krdc);
-
- /* can't wait for myself to go away, I'm a flusher */
- if (wait & RDC_WAIT)
- while (group->rdc_thrnum)
- delay(2);
-
-}
-
-/*
- * rdc_stamp_diskq
- * write out diskq header info
- * must have disk_qlock held
- * if rsrvd flag is 0, the nsc_reserve is done
- */
-int
-rdc_stamp_diskq(rdc_k_info_t *krdc, int rsrvd, int failflags)
-{
- nsc_vec_t vec[2];
- nsc_buf_t *head = NULL;
- rdc_group_t *grp;
- rdc_u_info_t *urdc;
- disk_queue *q;
- int rc, flags;
-
- grp = krdc->group;
- q = &krdc->group->diskq;
-
- ASSERT(MUTEX_HELD(&q->disk_qlock));
-
- urdc = &rdc_u_info[krdc->index];
-
- if (!rsrvd && _rdc_rsrv_diskq(grp)) {
- cmn_err(CE_WARN, "!rdc_stamp_diskq: %s reserve failed",
- urdc->disk_queue);
- mutex_exit(QLOCK(q));
- rdc_fail_diskq(krdc, RDC_NOWAIT, failflags);
- mutex_enter(QLOCK(q));
- return (-1);
- }
- flags = NSC_WRITE | NSC_NOCACHE | NSC_NODATA;
- rc = nsc_alloc_buf(grp->diskqfd, 0, 1, flags, &head);
-
- if (!RDC_SUCCESS(rc)) {
- cmn_err(CE_WARN, "!Alloc buf failed for disk queue %s",
- &urdc->disk_queue[0]);
- mutex_exit(QLOCK(q));
- rdc_fail_diskq(krdc, RDC_NOWAIT, failflags);
- mutex_enter(QLOCK(q));
- return (-1);
- }
- vec[0].sv_len = FBA_SIZE(1);
- vec[0].sv_addr = (uchar_t *)&q->disk_hdr;
- vec[1].sv_len = 0;
- vec[1].sv_addr = NULL;
-
- head->sb_vec = &vec[0];
-
-#ifdef DEBUG_DISKQ
- cmn_err(CE_NOTE, "!rdc_stamp_diskq: hdr: %p magic: %x state: "
- "%x head: %d tail: %d size: %d nitems: %d blocks: %d",
- q, QMAGIC(q), QSTATE(q), QHEAD(q),
- QTAIL(q), QSIZE(q), QNITEMS(q), QBLOCKS(q));
-#endif
-
- rc = nsc_write(head, 0, 1, 0);
-
- if (!RDC_SUCCESS(rc)) {
- if (!rsrvd)
- _rdc_rlse_diskq(grp);
- cmn_err(CE_CONT, "!disk queue %s failed rc %d",
- &urdc->disk_queue[0], rc);
- mutex_exit(QLOCK(q));
- rdc_fail_diskq(krdc, RDC_NOWAIT, failflags);
- mutex_enter(QLOCK(q));
- return (-1);
- }
-
- (void) nsc_free_buf(head);
- if (!rsrvd)
- _rdc_rlse_diskq(grp);
-
- return (0);
-}
-
-/*
- * rdc_init_diskq_header
- * load initial values into the header
- */
-void
-rdc_init_diskq_header(rdc_group_t *grp, dqheader *header)
-{
- int rc;
- int type = 0;
- disk_queue *q = &grp->diskq;
-
- ASSERT(MUTEX_HELD(QLOCK(q)));
-
- /* save q type if this is a failure */
- if (QSTATE(q) & RDC_QNOBLOCK)
- type = RDC_QNOBLOCK;
- bzero(header, sizeof (*header));
- header->h.magic = RDC_DISKQ_MAGIC;
- header->h.vers = RDC_DISKQ_VERS;
- header->h.state |= (RDC_SHUTDOWN_BAD|type); /* SHUTDOWN_OK on suspend */
- header->h.head_offset = RDC_DISKQ_DATA_OFF;
- header->h.tail_offset = RDC_DISKQ_DATA_OFF;
- header->h.nitems = 0;
- header->h.blocks = 0;
- header->h.qwrap = 0;
- SET_QNXTIO(q, QHEAD(q));
- SET_QCOALBOUNDS(q, RDC_DISKQ_DATA_OFF);
-
- /* do this last, as this might be a failure. get the kernel state ok */
- rc = _rdc_rsrv_diskq(grp);
- if (!RDC_SUCCESS(rc)) {
- cmn_err(CE_WARN, "!init_diskq_hdr: Reserve failed for queue");
- return;
- }
- (void) nsc_partsize(grp->diskqfd, &header->h.disk_size);
- _rdc_rlse_diskq(grp);
-
-}
-
-/*
- * rdc_unfail_diskq
- * the diskq failed for some reason, lets try and re-start it
- * the old stuff has already been thrown away
- * should just be called from rdc_sync
- */
-void
-rdc_unfail_diskq(rdc_k_info_t *krdc)
-{
- rdc_k_info_t *p;
- rdc_u_info_t *q = &rdc_u_info[krdc->index];
- rdc_group_t *group = krdc->group;
- disk_queue *dq = &group->diskq;
-
- rdc_group_enter(krdc);
- rdc_clr_flags(q, RDC_ASYNC);
- /* someone else won the race... */
- if (!IS_STATE(q, RDC_DISKQ_FAILED)) {
- rdc_group_exit(krdc);
- return;
- }
- rdc_clr_flags(q, RDC_DISKQ_FAILED);
- for (p = krdc->group_next; p != krdc; p = p->group_next) {
- q = &rdc_u_info[p->index];
- if (!IS_ENABLED(q))
- continue;
- rdc_clr_flags(q, RDC_DISKQ_FAILED);
- rdc_clr_flags(q, RDC_ASYNC);
- if (IS_STATE(q, RDC_QUEUING))
- rdc_clr_flags(q, RDC_QUEUING);
- }
- rdc_group_exit(krdc);
-
- mutex_enter(QLOCK(dq));
-
- rdc_init_diskq_header(group, &group->diskq.disk_hdr);
- /* real i/o to the queue */
- /* clear RDC_AUXSYNCIP because we cannot halt a sync that's not here */
- krdc->aux_state &= ~RDC_AUXSYNCIP;
- if (rdc_stamp_diskq(krdc, 0, RDC_GROUP_LOCKED | RDC_DOLOG) < 0) {
- mutex_exit(QLOCK(dq));
- goto fail;
- }
-
- SET_QNXTIO(dq, QHEAD(dq));
- SET_QHDRCNT(dq, 0);
- SET_QSTATE(dq, RDC_SHUTDOWN_BAD); /* only suspend can write good */
- dq->iohdrs = NULL;
- dq->hdr_last = NULL;
-
- /* should be none, but.. */
- rdc_dump_iohdrs(dq);
-
- mutex_exit(QLOCK(dq));
-
-
-fail:
- krdc->aux_state |= RDC_AUXSYNCIP;
- return;
-
-}
-
-int
-rdc_read_diskq_header(rdc_k_info_t *krdc)
-{
- int rc;
- diskq_header *header;
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
-
- if (krdc->group->diskqfd == NULL) {
- char buf[NSC_MAXPATH];
- (void) snprintf(buf, NSC_MAXPATH, "%s:%s", urdc->secondary.intf,
- &urdc->secondary.intf[0]);
- cmn_err(CE_WARN, "!Disk Queue Header read failed for %s",
- urdc->group_name[0] == '\0' ? buf:
- &urdc->group_name[0]);
- return (-1);
- }
-
- header = &krdc->group->diskq.disk_hdr.h;
- if (_rdc_rsrv_diskq(krdc->group)) {
- return (-1);
- }
-
- rc = rdc_ns_io(krdc->group->diskqfd, NSC_RDBUF, 0,
- (uchar_t *)header, sizeof (diskq_header));
-
- _rdc_rlse_diskq(krdc->group);
-
- if (!RDC_SUCCESS(rc)) {
- char buf[NSC_MAXPATH];
- (void) snprintf(buf, NSC_MAXPATH, "%s:%s", urdc->secondary.intf,
- &urdc->secondary.file[0]);
- cmn_err(CE_WARN, "!Disk Queue Header read failed(%d) for %s",
- rc, urdc->group_name[0] == '\0' ? buf :
- &urdc->group_name[0]);
- return (-1);
- }
- return (0);
-}
-
-/*
- * rdc_stop_diskq_flusher
- */
-void
-rdc_stop_diskq_flusher(rdc_k_info_t *krdc)
-{
- disk_queue q, *qp;
- rdc_group_t *group;
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!stopping flusher threads");
-#endif
- group = krdc->group;
- qp = &krdc->group->diskq;
-
- /* save the queue info */
- q = *qp;
-
- /* lie a little */
- SET_QTAIL(qp, RDC_DISKQ_DATA_OFF);
- SET_QHEAD(qp, RDC_DISKQ_DATA_OFF);
- SET_QSTATE(qp, RDC_QDISABLEPEND);
- SET_QSTATE(qp, RDC_STOPPINGFLUSH);
-
- /* drop locks to allow flushers to die */
- mutex_exit(QLOCK(qp));
- mutex_exit(QHEADLOCK(qp));
- rdc_group_exit(krdc);
-
- while (group->rdc_thrnum)
- delay(2);
-
- rdc_group_enter(krdc);
- mutex_enter(QHEADLOCK(qp));
- mutex_enter(QLOCK(qp));
-
- CLR_QSTATE(qp, RDC_STOPPINGFLUSH);
- *qp = q;
-}
-
-/*
- * rdc_enable_diskq
- * open the diskq
- * and stamp the header onto it.
- */
-int
-rdc_enable_diskq(rdc_k_info_t *krdc)
-{
- rdc_group_t *group;
- disk_queue *q;
-
- group = krdc->group;
- q = &group->diskq;
-
- if (rdc_open_diskq(krdc) < 0)
- goto fail;
-
- mutex_enter(QLOCK(q));
- rdc_init_diskq_header(group, &group->diskq.disk_hdr);
-
- if (rdc_stamp_diskq(krdc, 0, RDC_NOLOG) < 0) {
- mutex_exit(QLOCK(q));
- goto fail;
- }
-
- SET_QNXTIO(q, QHEAD(q));
-
- mutex_exit(QLOCK(q));
- return (0);
-
-fail:
- mutex_enter(&group->diskqmutex);
- rdc_close_diskq(group);
- mutex_exit(&group->diskqmutex);
-
- /* caller has to fail diskq after dropping conf & many locks */
- return (RDC_EQNOADD);
-}
-
-/*
- * rdc_resume_diskq
- * open the diskq and read the header
- */
-int
-rdc_resume_diskq(rdc_k_info_t *krdc)
-{
- rdc_u_info_t *urdc;
- rdc_group_t *group;
- disk_queue *q;
- int rc = 0;
-
- urdc = &rdc_u_info[krdc->index];
- group = krdc->group;
- q = &group->diskq;
-
- if (rdc_open_diskq(krdc) < 0) {
- rc = RDC_EQNOADD;
- goto fail;
- }
-
- mutex_enter(QLOCK(q));
-
- rdc_init_diskq_header(group, &group->diskq.disk_hdr);
-
- if (rdc_read_diskq_header(krdc) < 0) {
- SET_QSTATE(q, RDC_QBADRESUME);
- rc = RDC_EQNOADD;
- }
-
- /* check diskq magic number */
- if (QMAGIC(q) != RDC_DISKQ_MAGIC) {
- cmn_err(CE_WARN, "!SNDR: unable to resume diskq %s,"
- " incorrect magic number in header", urdc->disk_queue);
- rdc_init_diskq_header(group, &group->diskq.disk_hdr);
- SET_QSTATE(q, RDC_QBADRESUME);
- rc = RDC_EQNOADD;
- } else switch (QVERS(q)) {
- diskq_header1 h1; /* version 1 header */
- diskq_header *hc; /* current header */
-
-#ifdef NSC_MULTI_TERABYTE
- case RDC_DISKQ_VER_ORIG:
- /* version 1 diskq header, upgrade to 64bit version */
- h1 = *(diskq_header1 *)(&group->diskq.disk_hdr.h);
- hc = &group->diskq.disk_hdr.h;
-
- cmn_err(CE_WARN, "!SNDR: old version header for diskq %s,"
- " upgrading to current version", urdc->disk_queue);
- hc->vers = RDC_DISKQ_VERS;
- hc->state = h1.state;
- hc->head_offset = h1.head_offset;
- hc->tail_offset = h1.tail_offset;
- hc->disk_size = h1.disk_size;
- hc->nitems = h1.nitems;
- hc->blocks = h1.blocks;
- hc->qwrap = h1.qwrap;
- hc->auxqwrap = h1.auxqwrap;
- hc->seq_last = h1.seq_last;
- hc->ack_last = h1.ack_last;
-
- if (hc->nitems > 0) {
- cmn_err(CE_WARN, "!SNDR: unable to resume diskq %s,"
- " old version Q contains data", urdc->disk_queue);
- rdc_init_diskq_header(group, &group->diskq.disk_hdr);
- SET_QSTATE(q, RDC_QBADRESUME);
- rc = RDC_EQNOADD;
- }
- break;
-#else
- case RDC_DISKQ_VER_64BIT:
- cmn_err(CE_WARN, "!SNDR: unable to resume diskq %s,"
- " diskq header newer than current version",
- urdc->disk_queue);
- rdc_init_diskq_header(group, &group->diskq.disk_hdr);
- SET_QSTATE(q, RDC_QBADRESUME);
- rc = RDC_EQNOADD;
- break;
-#endif
- case RDC_DISKQ_VERS:
- /* okay, current version diskq */
- break;
- default:
- cmn_err(CE_WARN, "!SNDR: unable to resume diskq %s,"
- " unknown diskq header version", urdc->disk_queue);
- rdc_init_diskq_header(group, &group->diskq.disk_hdr);
- SET_QSTATE(q, RDC_QBADRESUME);
- rc = RDC_EQNOADD;
- break;
- }
- if (IS_QSTATE(q, RDC_SHUTDOWN_BAD)) {
- cmn_err(CE_WARN, "!SNDR: unable to resume diskq %s,"
- " unsafe shutdown", urdc->disk_queue);
- rdc_init_diskq_header(group, &group->diskq.disk_hdr);
- SET_QSTATE(q, RDC_QBADRESUME);
- rc = RDC_EQNOADD;
- }
-
- CLR_QSTATE(q, RDC_SHUTDOWN_OK);
- SET_QSTATE(q, RDC_SHUTDOWN_BAD);
-
- /* bad, until proven not bad */
- if (rdc_stamp_diskq(krdc, 0, RDC_NOLOG) < 0) {
- rdc_fail_diskq(krdc, RDC_NOWAIT, RDC_NOLOG);
- rc = RDC_EQNOADD;
- }
-
- SET_QNXTIO(q, QHEAD(q));
- group->diskq.nitems_hwm = QNITEMS(q);
- group->diskq.blocks_hwm = QBLOCKS(q);
-
- mutex_exit(QLOCK(q));
-
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!rdc_resume_diskq: resuming diskq %s \n",
- urdc->disk_queue);
- cmn_err(CE_NOTE, "!qinfo: " QDISPLAY(q));
-#endif
- if (rc == 0)
- return (0);
-
-fail:
-
- /* caller has to set the diskq failed after dropping it's locks */
- return (rc);
-
-}
-
-int
-rdc_suspend_diskq(rdc_k_info_t *krdc)
-{
- int rc;
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- disk_queue *q;
-
- q = &krdc->group->diskq;
-
- /* grab both diskq locks as we are going to kill the flusher */
- mutex_enter(QHEADLOCK(q));
- mutex_enter(QLOCK(q));
-
- if ((krdc->group->rdc_thrnum) && (!IS_QSTATE(q, RDC_STOPPINGFLUSH))) {
- SET_QSTATE(q, RDC_STOPPINGFLUSH);
- rdc_stop_diskq_flusher(krdc);
- CLR_QSTATE(q, RDC_STOPPINGFLUSH);
- }
-
- krdc->group->diskq.disk_hdr.h.state &= ~RDC_SHUTDOWN_BAD;
- krdc->group->diskq.disk_hdr.h.state |= RDC_SHUTDOWN_OK;
- krdc->group->diskq.disk_hdr.h.state &= ~RDC_QBADRESUME;
-
- /* let's make sure that the flusher has stopped.. */
- if (krdc->group->rdc_thrnum) {
- mutex_exit(QLOCK(q));
- mutex_exit(QHEADLOCK(q));
- rdc_group_exit(krdc);
-
- while (krdc->group->rdc_thrnum)
- delay(5);
-
- rdc_group_enter(krdc);
- mutex_enter(QLOCK(q));
- mutex_enter(QHEADLOCK(q));
- }
- /* write refcount to the bitmap */
- if ((rc = rdc_write_refcount(krdc)) < 0) {
- rdc_group_exit(krdc);
- goto fail;
- }
-
- if (!QEMPTY(q)) {
- rdc_set_flags(urdc, RDC_QUEUING);
- } else {
- rdc_clr_flags(urdc, RDC_QUEUING);
- }
-
- /* fill in diskq header info */
- krdc->group->diskq.disk_hdr.h.state &= ~RDC_QDISABLEPEND;
-
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!suspending disk queue\n" QDISPLAY(q));
-#endif
-
- /* to avoid a possible deadlock, release in order, and reacquire */
- mutex_exit(QLOCK(q));
- mutex_exit(QHEADLOCK(q));
-
- if (krdc->group->count > 1) {
- rdc_group_exit(krdc);
- goto fail; /* just stamp on the last suspend */
- }
- rdc_group_exit(krdc); /* in case this stamp fails */
- mutex_enter(QLOCK(q));
-
- rc = rdc_stamp_diskq(krdc, 0, RDC_NOLOG);
-
- mutex_exit(QLOCK(q));
-
-fail:
- rdc_group_enter(krdc);
-
- /* diskq already failed if stamp failed */
-
- return (rc);
-}
-
-/*
- * copy orig aio to copy, including the nsc_buf_t
- */
-int
-rdc_dup_aio(rdc_aio_t *orig, rdc_aio_t *copy)
-{
- int rc;
- bcopy(orig, copy, sizeof (*orig));
- copy->handle = NULL;
-
- if (orig->handle == NULL) /* no buf to alloc/copy */
- return (0);
-
- rc = nsc_alloc_abuf(orig->pos, orig->len, 0, &copy->handle);
- if (!RDC_SUCCESS(rc)) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!rdc_dup_aio: alloc_buf failed (%d)", rc);
-#endif
- return (rc);
- }
- rc = nsc_copy(orig->handle, copy->handle, orig->pos,
- orig->pos, orig->len);
- if (!RDC_SUCCESS(rc)) {
- (void) nsc_free_buf(copy->handle);
-#ifdef DEBUG
- cmn_err(CE_WARN, "!rdc_dup_aio: copy buf failed (%d)", rc);
-#endif
- return (rc);
- }
- return (0);
-}
-
-/*
- * rdc_qfill_shldwakeup()
- * 0 if the memory queue has filled, and the low water
- * mark has not been reached. 0 if diskq is empty.
- * 1 if less than low water mark
- * net_queue mutex is already held
- */
-int
-rdc_qfill_shldwakeup(rdc_k_info_t *krdc)
-{
- rdc_group_t *group = krdc->group;
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- net_queue *nq = &group->ra_queue;
- disk_queue *dq = &group->diskq;
-
- ASSERT(MUTEX_HELD(&nq->net_qlock));
-
- if (!RDC_IS_DISKQ(krdc->group))
- return (0);
-
- if (nq->qfill_sleeping != RDC_QFILL_ASLEEP)
- return (0);
-
- if (nq->qfflags & RDC_QFILLSTOP)
- return (1);
-
- if (nq->qfflags & RDC_QFILLSLEEP)
- return (0);
-
- if (IS_STATE(urdc, RDC_LOGGING) || IS_STATE(urdc, RDC_SYNCING))
- return (0);
-
- mutex_enter(QLOCK(dq));
- if ((QNXTIO(dq) == QTAIL(dq)) && !IS_QSTATE(dq, RDC_QFULL)) {
- mutex_exit(QLOCK(dq));
- return (0);
- }
- mutex_exit(QLOCK(dq));
-
- if (nq->qfill_sleeping == RDC_QFILL_ASLEEP) {
- if (nq->hwmhit) {
- if (nq->blocks <= RDC_LOW_QBLOCKS) {
- nq->hwmhit = 0;
- } else {
- return (0);
- }
- }
-#ifdef DEBUG_DISKQ_NOISY
- cmn_err(CE_NOTE, "!Waking up diskq->memq flusher, flags 0x%x"
- " idx: %d", rdc_get_vflags(urdc), urdc->index);
-#endif
- return (1);
- }
- return (0);
-
-}
-
-/*
- * rdc_diskq_enqueue
- * enqueue one i/o to the diskq
- * after appending some metadata to the front
- */
-int
-rdc_diskq_enqueue(rdc_k_info_t *krdc, rdc_aio_t *aio)
-{
- nsc_vec_t *vec = NULL;
- nsc_buf_t *bp = NULL;
- nsc_buf_t *qbuf = NULL;
- io_hdr *iohdr = NULL;
- disk_queue *q;
- rdc_group_t *group;
- int numvecs;
- int i, j, rc = 0;
- int retries = 0;
- rdc_u_info_t *urdc;
- nsc_size_t iofbas; /* len of io + io header len */
- int qtail;
- int delay_time = 2;
- int print_msg = 1;
-
-#ifdef DEBUG_WRITER_UBERNOISE
- int qhead;
-#endif
- urdc = &rdc_u_info[krdc->index];
- group = krdc->group;
- q = &group->diskq;
-
- mutex_enter(QLOCK(q));
-
- /*
- * there is a thread that is blocking because the queue is full,
- * don't try to set up this write until all is clear
- * check before and after for logging or failed queue just
- * in case a thread was in flight while the queue was full,
- * and in the proccess of failing
- */
- while (IS_QSTATE(q, RDC_QFULL)) {
- if (IS_STATE(urdc, RDC_DISKQ_FAILED) ||
- (IS_STATE(urdc, RDC_LOGGING) &&
- !IS_STATE(urdc, RDC_QUEUING))) {
- mutex_exit(QLOCK(q));
- if (aio->handle)
- (void) nsc_free_buf(aio->handle);
- return (-1);
- }
- cv_wait(&q->qfullcv, QLOCK(q));
-
- if (IS_STATE(urdc, RDC_DISKQ_FAILED) ||
- (IS_STATE(urdc, RDC_LOGGING) &&
- !IS_STATE(urdc, RDC_QUEUING))) {
- mutex_exit(QLOCK(q));
- if (aio->handle)
- (void) nsc_free_buf(aio->handle);
- return (-1);
- }
-
- }
-
- SET_QSTATE(q, QTAILBUSY);
-
- if (aio->handle == NULL) {
- /* we're only going to write the header to the queue */
- numvecs = 2; /* kmem_alloc io header + null terminate */
- iofbas = FBA_LEN(sizeof (io_hdr));
-
- } else {
- /* find out how many vecs */
- numvecs = rdc_count_vecs(aio->handle->sb_vec) + 1;
- iofbas = aio->len + FBA_LEN(sizeof (io_hdr));
- }
-
- /*
- * this, in conjunction with QTAILBUSY, will prevent
- * premature dequeuing
- */
-
- SET_LASTQTAIL(q, QTAIL(q));
-
- iohdr = (io_hdr *) kmem_zalloc(sizeof (io_hdr), KM_NOSLEEP);
- vec = (nsc_vec_t *) kmem_zalloc(sizeof (nsc_vec_t) * numvecs,
- KM_NOSLEEP);
-
- if (!vec || !iohdr) {
- if (!vec) {
- cmn_err(CE_WARN, "!vec kmem alloc failed");
- } else {
- cmn_err(CE_WARN, "!iohdr kmem alloc failed");
- }
- if (vec)
- kmem_free(vec, sizeof (*vec));
- if (iohdr)
- kmem_free(iohdr, sizeof (*iohdr));
- CLR_QSTATE(q, QTAILBUSY);
- SET_LASTQTAIL(q, 0);
- mutex_exit(QLOCK(q));
- if (aio->handle)
- (void) nsc_free_buf(aio->handle);
- return (ENOMEM);
- }
-
- vec[numvecs - 1].sv_len = 0;
- vec[numvecs - 1].sv_addr = 0;
-
- /* now add the write itself */
- bp = aio->handle;
-
- for (i = 1, j = 0; bp && bp->sb_vec[j].sv_addr &&
- i < numvecs; i++, j++) {
- vec[i].sv_len = bp->sb_vec[j].sv_len;
- vec[i].sv_addr = bp->sb_vec[j].sv_addr;
- }
-
-retry:
-
- /* check for queue wrap, then check for overflow */
- if (IS_STATE(urdc, RDC_DISKQ_FAILED) ||
- (IS_STATE(urdc, RDC_LOGGING) && !IS_STATE(urdc, RDC_QUEUING))) {
- kmem_free(iohdr, sizeof (*iohdr));
- kmem_free(vec, sizeof (*vec) * numvecs);
- CLR_QSTATE(q, QTAILBUSY);
- SET_LASTQTAIL(q, 0);
- if (IS_QSTATE(q, RDC_QFULL)) { /* wakeup blocked threads */
- CLR_QSTATE(q, RDC_QFULL);
- cv_broadcast(&q->qfullcv);
- }
- mutex_exit(QLOCK(q));
- if (aio->handle)
- (void) nsc_free_buf(aio->handle);
-
- return (-1);
- }
-
- if (QTAILSHLDWRAP(q, iofbas)) {
- /*
- * just go back to the beginning of the disk
- * it's not worth the trouble breaking up the write
- */
-#ifdef DEBUG_DISKQWRAP
- cmn_err(CE_NOTE, "!wrapping Q tail: " QDISPLAY(q));
-#endif
- /*LINTED*/
- WRAPQTAIL(q);
- }
-
- /*
- * prepend the write's metadata
- */
- rdc_fill_ioheader(aio, iohdr, QTAIL(q));
-
- vec[0].sv_len = FBA_SIZE(1);
- vec[0].sv_addr = (uchar_t *)iohdr;
-
- /* check for tail < head */
-
- if (!(FITSONQ(q, iofbas))) {
- /*
- * don't allow any more writes to start
- */
- SET_QSTATE(q, RDC_QFULL);
- mutex_exit(QLOCK(q));
-
- if ((!group->rdc_writer) && !IS_STATE(urdc, RDC_LOGGING))
- (void) rdc_writer(krdc->index);
-
- delay(delay_time);
- q->throttle_delay += delay_time;
- retries++;
- delay_time *= 2; /* fairly aggressive */
- if ((retries >= 8) || (delay_time >= 256)) {
- delay_time = 2;
- if (print_msg) {
- cmn_err(CE_WARN, "!enqueue: disk queue %s full",
- &urdc->disk_queue[0]);
- print_msg = 0;
-#ifdef DEBUG
- cmn_err(CE_WARN, "!qinfo: " QDISPLAY(q));
-#else
- cmn_err(CE_CONT, "!qinfo: " QDISPLAYND(q));
-#endif
- }
- /*
- * if this is a no-block queue, or this is a blocking
- * queue that is not flushing. reset and log
- */
- if ((QSTATE(q) & RDC_QNOBLOCK) ||
- (IS_STATE(urdc, RDC_QUEUING))) {
-
- if (IS_STATE(urdc, RDC_QUEUING)) {
- cmn_err(CE_WARN, "!SNDR: disk queue %s full and not flushing. "
- "giving up", &urdc->disk_queue[0]);
- cmn_err(CE_WARN, "!SNDR: %s:%s entering logging mode",
- urdc->secondary.intf, urdc->secondary.file);
- }
-
- rdc_fail_diskq(krdc, RDC_WAIT,
- RDC_DOLOG | RDC_NOFAIL);
- kmem_free(iohdr, sizeof (*iohdr));
- kmem_free(vec, sizeof (*vec) * numvecs);
- mutex_enter(QLOCK(q));
- CLR_QSTATE(q, QTAILBUSY | RDC_QFULL);
- cv_broadcast(&q->qfullcv);
- mutex_exit(QLOCK(q));
- SET_LASTQTAIL(q, 0);
- if (aio->handle)
- (void) nsc_free_buf(aio->handle);
- return (ENOMEM);
- }
- }
-
- mutex_enter(QLOCK(q));
- goto retry;
-
- }
-
- qtail = QTAIL(q);
-#ifdef DEBUG_WRITER_UBERNOISE
- qhead = QHEAD(q);
-#endif
-
- /* update tail pointer, nitems on queue and blocks on queue */
- INC_QTAIL(q, iofbas); /* increment tail over i/o size + ioheader size */
- INC_QNITEMS(q, 1);
- /* increment counter for i/o blocks only */
- INC_QBLOCKS(q, (iofbas - FBA_LEN(sizeof (io_hdr))));
-
- if (QNITEMS(q) > q->nitems_hwm)
- q->nitems_hwm = QNITEMS(q);
- if (QBLOCKS(q) > q->blocks_hwm)
- q->blocks_hwm = QBLOCKS(q);
-
- if (IS_QSTATE(q, RDC_QFULL)) {
- CLR_QSTATE(q, RDC_QFULL);
- cv_broadcast(&q->qfullcv);
- }
-
- mutex_exit(QLOCK(q));
-
- /*
- * if (krdc->io_kstats) {
- * mutex_enter(krdc->io_kstats->ks_lock);
- * kstat_waitq_enter(KSTAT_IO_PTR(krdc->io_kstats));
- * mutex_exit(krdc->io_kstats->ks_lock);
- * }
- */
-
- DTRACE_PROBE(rdc_diskq_rsrv);
-
- if (_rdc_rsrv_diskq(group)) {
- cmn_err(CE_WARN, "!rdc_enqueue: %s reserve failed",
- &urdc->disk_queue[0]);
- rdc_fail_diskq(krdc, RDC_WAIT, RDC_DOLOG);
- kmem_free(iohdr, sizeof (*iohdr));
- kmem_free(vec, sizeof (*vec) * numvecs);
- mutex_enter(QLOCK(q));
- CLR_QSTATE(q, QTAILBUSY);
- SET_LASTQTAIL(q, 0);
- mutex_exit(QLOCK(q));
- if (aio->handle)
- (void) nsc_free_buf(aio->handle);
- return (-1);
- }
-
-/* XXX for now do this, but later pre-alloc handle in enable/resume */
-
- DTRACE_PROBE(rdc_diskq_alloc_start);
- rc = nsc_alloc_buf(group->diskqfd, qtail, iofbas,
- NSC_NOCACHE | NSC_WRITE | NSC_NODATA, &qbuf);
-
- DTRACE_PROBE(rdc_diskq_alloc_end);
-
- if (!RDC_SUCCESS(rc)) {
- cmn_err(CE_WARN, "!disk queue %s alloc failed(%d) %" NSC_SZFMT,
- &urdc->disk_queue[0], rc, iofbas);
- rdc_fail_diskq(krdc, RDC_WAIT, RDC_DOLOG);
- rc = ENOMEM;
- goto fail;
- }
- /* move vec and write to queue */
- qbuf->sb_vec = &vec[0];
-
-#ifdef DEBUG_WRITER_UBERNOISE
-
- cmn_err(CE_NOTE, "!about to write to queue, qbuf: %p, qhead: %d, "
- "qtail: %d, len: %d contents: %c%c%c%c%c",
- (void *) qbuf, qhead, qtail, iofbas,
- qbuf->sb_vec[1].sv_addr[0],
- qbuf->sb_vec[1].sv_addr[1],
- qbuf->sb_vec[1].sv_addr[2],
- qbuf->sb_vec[1].sv_addr[3],
- qbuf->sb_vec[1].sv_addr[4]);
- cmn_err(CE_CONT, "!qinfo: " QDISPLAYND(q));
-
-#endif
-
- DTRACE_PROBE2(rdc_diskq_nswrite_start, int, qtail, nsc_size_t, iofbas);
- rc = nsc_write(qbuf, qtail, iofbas, 0);
- DTRACE_PROBE2(rdc_diskq_nswrite_end, int, qtail, nsc_size_t, iofbas);
-
- if (!RDC_SUCCESS(rc)) {
- cmn_err(CE_WARN, "!disk queue %s write failed %d",
- &urdc->disk_queue[0], rc);
- rdc_fail_diskq(krdc, RDC_WAIT, RDC_DOLOG);
- goto fail;
-
- }
-
- mutex_enter(QLOCK(q));
-
- SET_LASTQTAIL(q, 0);
- CLR_QSTATE(q, QTAILBUSY);
-
- mutex_exit(QLOCK(q));
-
-fail:
-
- /*
- * return what should be returned
- * the aio is returned in _rdc_write after status is gathered.
- */
-
- if (qbuf)
- qbuf->sb_vec = 0;
- (void) nsc_free_buf(qbuf);
-
- if (aio->handle)
- (void) nsc_free_buf(aio->handle);
-
- _rdc_rlse_diskq(group);
- DTRACE_PROBE(rdc_diskq_rlse);
-
- /* free the iohdr and the vecs */
-
- if (iohdr)
- kmem_free(iohdr, sizeof (*iohdr));
- if (vec)
- kmem_free(vec, sizeof (*vec) * numvecs);
-
- /* if no flusher running, start one */
- if ((!krdc->group->rdc_writer) && !IS_STATE(urdc, RDC_LOGGING))
- (void) rdc_writer(krdc->index);
-
- return (rc);
-}
-
-/*
- * place this on the pending list of io_hdr's out for flushing
- */
-void
-rdc_add_iohdr(io_hdr *header, rdc_group_t *group)
-{
- disk_queue *q = NULL;
-#ifdef DEBUG
- io_hdr *p;
-#endif
-
- q = &group->diskq;
-
- /* paranoia */
- header->dat.next = NULL;
-
- mutex_enter(QLOCK(q));
-#ifdef DEBUG /* AAAH! double flush!? */
- p = q->iohdrs;
- while (p) {
- if (p->dat.qpos == header->dat.qpos) {
- cmn_err(CE_WARN, "!ADDING DUPLICATE HEADER %" NSC_SZFMT,
- p->dat.qpos);
- kmem_free(header, sizeof (*header));
- mutex_exit(QLOCK(q));
- return;
- }
- p = p->dat.next;
- }
-#endif
- if (q->iohdrs == NULL) {
- q->iohdrs = q->hdr_last = header;
- q->hdrcnt = 1;
- mutex_exit(QLOCK(q));
- return;
- }
-
- q->hdr_last->dat.next = header;
- q->hdr_last = header;
- q->hdrcnt++;
- mutex_exit(QLOCK(q));
- return;
-
-}
-
-/*
- * mark an io header as flushed. If it is the qhead,
- * then update the qpointers
- * free the io_hdrs
- * called after the bitmap is cleared by flusher
- */
-void
-rdc_clr_iohdr(rdc_k_info_t *krdc, nsc_size_t qpos)
-{
- rdc_group_t *group = krdc->group;
- disk_queue *q = NULL;
- io_hdr *hp = NULL;
- io_hdr *p = NULL;
- int found = 0;
- int cnt = 0;
-
-#ifndef NSC_MULTI_TERABYTE
- ASSERT(qpos >= 0); /* assertion to validate change for 64bit */
- if (qpos < 0) /* not a diskq offset */
- return;
-#endif
-
- q = &group->diskq;
- mutex_enter(QLOCK(q));
-
- hp = p = q->iohdrs;
-
- /* find outstanding io_hdr */
- while (hp) {
- if (hp->dat.qpos == qpos) {
- found++;
- break;
- }
- cnt++;
- p = hp;
- hp = hp->dat.next;
- }
-
- if (!found) {
- if (RDC_BETWEEN(QHEAD(q), QNXTIO(q), qpos)) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!iohdr already cleared? "
- "qpos %" NSC_SZFMT " cnt %d ", qpos, cnt);
- cmn_err(CE_WARN, "!Qinfo: " QDISPLAY(q));
-#endif
- mutex_exit(QLOCK(q));
- return;
- }
- mutex_exit(QLOCK(q));
- return;
- }
-
- /* mark it as flushed */
- hp->dat.iostatus = RDC_IOHDR_DONE;
-
- /*
- * if it is the head pointer, travel the list updating the queue
- * pointers until the next unflushed is reached, freeing on the way.
- */
- while (hp && (hp->dat.qpos == QHEAD(q)) &&
- (hp->dat.iostatus == RDC_IOHDR_DONE)) {
-#ifdef DEBUG_FLUSHER_UBERNOISE
- cmn_err(CE_NOTE, "!clr_iohdr info: magic %x type %d pos %d"
- " qpos %d hpos %d len %d flag 0x%x iostatus %x setid %d",
- hp->dat.magic, hp->dat.type, hp->dat.pos, hp->dat.qpos,
- hp->dat.hpos, hp->dat.len, hp->dat.flag,
- hp->dat.iostatus, hp->dat.setid);
-#endif
- if (hp->dat.flag & RDC_NULL_BUF) {
- INC_QHEAD(q, FBA_LEN(sizeof (io_hdr)));
- } else {
- INC_QHEAD(q, FBA_LEN(sizeof (io_hdr)) + hp->dat.len);
- DEC_QBLOCKS(q, hp->dat.len);
- }
-
- DEC_QNITEMS(q, 1);
-
- if (QHEADSHLDWRAP(q)) { /* simple enough */
-#ifdef DEBUG_DISKQWRAP
- cmn_err(CE_NOTE, "!wrapping Q head: " QDISPLAY(q));
-#endif
- /*LINTED*/
- WRAPQHEAD(q);
- }
-
- /* get rid of the iohdr */
- if (hp == q->iohdrs) {
- q->iohdrs = hp->dat.next;
- kmem_free(hp, sizeof (*hp));
- hp = q->iohdrs;
- } else {
- if (hp == q->hdr_last)
- q->hdr_last = p;
- p->dat.next = hp->dat.next;
- kmem_free(hp, sizeof (*hp));
- hp = p->dat.next;
- }
- q->hdrcnt--;
- }
-
- if (QEMPTY(q) && !IS_QSTATE(q, RDC_QFULL) &&
- !(IS_QSTATE(q, RDC_QDISABLEPEND))) {
-#ifdef DEBUG_FLUSHER_UBERNOISE
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- cmn_err(CE_NOTE, "!clr_iohdr: diskq %s empty, "
- "resetting defaults", urdc->disk_queue);
-#endif
-
- rdc_init_diskq_header(group, &q->disk_hdr);
- SET_QNXTIO(q, QHEAD(q));
- }
-
- /* wakeup any blocked enqueue threads */
- cv_broadcast(&q->qfullcv);
- mutex_exit(QLOCK(q));
-}
-
-/*
- * put in whatever useful checks we can on the io header
- */
-int
-rdc_iohdr_ok(io_hdr *hdr)
-{
- if (hdr->dat.magic != RDC_IOHDR_MAGIC)
- goto bad;
- return (1);
-bad:
-
-#ifdef DEBUG
- cmn_err(CE_WARN, "!Bad io header magic %x type %d pos %" NSC_SZFMT
- " hpos %" NSC_SZFMT " qpos %" NSC_SZFMT " len %" NSC_SZFMT
- " flag %d iostatus %d setid %d", hdr->dat.magic,
- hdr->dat.type, hdr->dat.pos, hdr->dat.hpos, hdr->dat.qpos,
- hdr->dat.len, hdr->dat.flag, hdr->dat.iostatus, hdr->dat.setid);
-#else
- cmn_err(CE_WARN, "!Bad io header retrieved");
-#endif
- return (0);
-}
-
-/*
- * rdc_netqueue_insert()
- * add an item to a netqueue. No locks necessary as it should only
- * be used in a single threaded manor. If that changes, then
- * a lock or assertion should be done here
- */
-void
-rdc_netqueue_insert(rdc_aio_t *aio, net_queue *q)
-{
- rdc_k_info_t *krdc = &rdc_k_info[aio->index];
-
- /* paranoid check for bit set */
- RDC_CHECK_BIT(krdc, aio->pos, aio->len);
-
- if (q->net_qhead == NULL) {
- q->net_qhead = q->net_qtail = aio;
-
- } else {
- q->net_qtail->next = aio;
- q->net_qtail = aio;
- }
- q->blocks += aio->len;
- q->nitems++;
-
- if (q->nitems > q->nitems_hwm) {
- q->nitems_hwm = q->nitems;
- }
- if (q->blocks > q->blocks_hwm) {
- q->nitems_hwm = q->blocks;
- }
-}
-
-/*
- * rdc_fill_aio(aio, hdr)
- * take the pertinent info from an io_hdr and stick it in
- * an aio, including seq number, abuf.
- */
-void
-rdc_fill_aio(rdc_group_t *grp, rdc_aio_t *aio, io_hdr *hdr, nsc_buf_t *abuf)
-{
- if (hdr->dat.flag & RDC_NULL_BUF) {
- aio->handle = NULL;
- } else {
- aio->handle = abuf;
- }
- aio->qhandle = abuf;
- aio->pos = hdr->dat.pos;
- aio->qpos = hdr->dat.qpos;
- aio->len = hdr->dat.len;
- aio->flag = hdr->dat.flag;
- if ((aio->index = rdc_setid2idx(hdr->dat.setid)) < 0)
- return;
- mutex_enter(&grp->diskq.disk_qlock);
- if (grp->ra_queue.qfflags & RDC_QFILLSLEEP) {
- mutex_exit(&grp->diskq.disk_qlock);
- aio->seq = RDC_NOSEQ;
- return;
- }
- if (abuf && aio->qhandle) {
- abuf->sb_user++;
- }
- aio->seq = grp->seq++;
- if (grp->seq < aio->seq)
- grp->seq = RDC_NEWSEQ + 1;
- mutex_exit(&grp->diskq.disk_qlock);
- hdr->dat.iostatus = aio->seq;
-
-}
-
-#ifdef DEBUG
-int maxaios_perbuf = 0;
-int midaios_perbuf = 0;
-int aveaios_perbuf = 0;
-int totaios_perbuf = 0;
-int buf2qcalls = 0;
-
-void
-calc_perbuf(int items)
-{
- if (totaios_perbuf < 0) {
- maxaios_perbuf = 0;
- midaios_perbuf = 0;
- aveaios_perbuf = 0;
- totaios_perbuf = 0;
- buf2qcalls = 0;
- }
-
- if (items > maxaios_perbuf)
- maxaios_perbuf = items;
- midaios_perbuf = maxaios_perbuf / 2;
- totaios_perbuf += items;
- aveaios_perbuf = totaios_perbuf / buf2qcalls;
-}
-#endif
-
-/*
- * rdc_discard_tmpq()
- * free up the passed temporary queue
- * NOTE: no cv's or mutexes have been initialized
- */
-void
-rdc_discard_tmpq(net_queue *q)
-{
- rdc_aio_t *aio;
-
- if (q == NULL)
- return;
-
- while (q->net_qhead) {
- aio = q->net_qhead;
- q->net_qhead = q->net_qhead->next;
- if (aio->qhandle) {
- aio->qhandle->sb_user--;
- if (aio->qhandle->sb_user == 0) {
- rdc_fixlen(aio);
- (void) nsc_free_buf(aio->qhandle);
- }
- }
- kmem_free(aio, sizeof (*aio));
- q->nitems--;
- }
- kmem_free(q, sizeof (*q));
-
-}
-
-/*
- * rdc_diskq_buf2queue()
- * take a chunk of the diskq, parse it and assemble
- * a chain of rdc_aio_t's.
- * updates QNXTIO()
- */
-net_queue *
-rdc_diskq_buf2queue(rdc_group_t *grp, nsc_buf_t **abuf, int index)
-{
- rdc_aio_t *aio = NULL;
- nsc_vec_t *vecp = NULL;
- uchar_t *vaddr = NULL;
- uchar_t *ioaddr = NULL;
- net_queue *netq = NULL;
- io_hdr *hdr = NULL;
- nsc_buf_t *buf = *abuf;
- rdc_u_info_t *urdc = &rdc_u_info[index];
- rdc_k_info_t *krdc = &rdc_k_info[index];
- disk_queue *dq = &grp->diskq;
- net_queue *nq = &grp->ra_queue;
- int nullbuf = 0;
- nsc_off_t endobuf;
- nsc_off_t bufoff;
- int vlen;
- nsc_off_t fpos;
- long bufcnt = 0;
- int nullblocks = 0;
- int fail = 1;
-
- if (buf == NULL)
- return (NULL);
-
- netq = kmem_zalloc(sizeof (*netq), KM_NOSLEEP);
- if (netq == NULL) {
- cmn_err(CE_WARN, "!SNDR: unable to allocate net queue");
- return (NULL);
- }
-
- vecp = buf->sb_vec;
- vlen = vecp->sv_len;
- vaddr = vecp->sv_addr;
- bufoff = buf->sb_pos;
- endobuf = bufoff + buf->sb_len;
-
-#ifdef DEBUG_FLUSHER_UBERNOISE
- cmn_err(CE_WARN, "!BUFFOFFENTER %d", bufoff);
-#endif
- /* CONSTCOND */
- while (1) {
- if (IS_STATE(urdc, RDC_LOGGING) ||
- (nq->qfflags & RDC_QFILLSLEEP)) {
- fail = 0;
- goto fail;
- }
-#ifdef DEBUG_FLUSHER_UBERNOISE
- cmn_err(CE_WARN, "!BUFFOFF_0 %d", bufoff);
-#endif
-
- if ((vaddr == NULL) || (vlen == 0))
- break;
-
- if (vlen <= 0) {
- vecp++;
- vaddr = vecp->sv_addr;
- vlen = vecp->sv_len;
- if (vaddr == NULL)
- break;
- }
-
- /* get the iohdr information */
-
- hdr = kmem_zalloc(sizeof (*hdr), KM_NOSLEEP);
- if (hdr == NULL) {
- cmn_err(CE_WARN,
- "!SNDR: unable to alocate net queue header");
- goto fail;
- }
-
- ioaddr = (uchar_t *)hdr;
-
- bcopy(vaddr, ioaddr, sizeof (*hdr));
-
- if (!rdc_iohdr_ok(hdr)) {
- cmn_err(CE_WARN,
- "!unable to retrieve i/o data from queue %s "
- "at offset %" NSC_SZFMT " bp: %" NSC_SZFMT " bl: %"
- NSC_SZFMT, urdc->disk_queue,
- bufoff, buf->sb_pos, buf->sb_len);
-#ifdef DEBUG_DISKQ
- cmn_err(CE_WARN, "!FAILING QUEUE state: %x",
- rdc_get_vflags(urdc));
- cmn_err(CE_WARN, "!qinfo: " QDISPLAY(dq));
- cmn_err(CE_WARN, "!VADDR %p, IOADDR %p", vaddr, ioaddr);
- cmn_err(CE_WARN, "!BUF %p", buf);
-#endif
- cmn_err(CE_WARN, "!qinfo: " QDISPLAYND(dq));
-
- goto fail;
- }
-
- nullbuf = hdr->dat.flag & RDC_NULL_BUF;
-
- bufoff += FBA_NUM(sizeof (*hdr));
-
- /* out of buffer, set nxtio to re read this last hdr */
- if (!nullbuf && ((bufoff + hdr->dat.len) > endobuf)) {
- break;
- }
-
- bufcnt += FBA_NUM(sizeof (*hdr));
-
- aio = kmem_zalloc(sizeof (*aio), KM_NOSLEEP);
- if (aio == NULL) {
- bufcnt -= FBA_NUM(sizeof (*hdr));
- cmn_err(CE_WARN, "!SNDR: net queue aio alloc failed");
- goto fail;
- }
-
- if (!nullbuf) {
- /* move to next iohdr in big buf */
- bufoff += hdr->dat.len;
- bufcnt += hdr->dat.len;
- }
-
- rdc_fill_aio(grp, aio, hdr, buf);
-
- if (aio->index < 0) {
- cmn_err(CE_WARN, "!Set id %d not found or no longer "
- "enabled, failing disk queue", hdr->dat.setid);
- kmem_free(aio, sizeof (*aio));
- goto fail;
- }
- if (aio->seq == RDC_NOSEQ) {
- kmem_free(aio, sizeof (*aio));
- fail = 0;
- goto fail;
- }
- if (aio->handle == NULL)
- nullblocks += aio->len;
-
- rdc_add_iohdr(hdr, grp);
- hdr = NULL; /* don't accidentally free on break or fail */
- rdc_netqueue_insert(aio, netq);
-
- /* no more buffer, skip the below logic */
- if ((bufoff + FBA_NUM(sizeof (*hdr))) >= endobuf) {
- break;
- }
-
- fpos = bufoff - buf->sb_pos;
- vecp = buf->sb_vec;
- for (; fpos >= FBA_NUM(vecp->sv_len); vecp++)
- fpos -= FBA_NUM(vecp->sv_len);
- vlen = vecp->sv_len - FBA_SIZE(fpos);
- vaddr = vecp->sv_addr + FBA_SIZE(fpos);
- /* abuf = NULL; */
-
- }
-
- /* free extraneous header */
- if (hdr) {
- kmem_free(hdr, sizeof (*hdr));
- hdr = NULL;
- }
-
- /*
- * probably won't happen, but if we didn't goto fail, but
- * we don't contain anything meaningful.. return NULL
- * and let the flusher or the sleep/wakeup routines
- * decide
- */
- if (netq && netq->nitems == 0) {
- kmem_free(netq, sizeof (*netq));
- return (NULL);
- }
-
-#ifdef DEBUG
- buf2qcalls++;
- calc_perbuf(netq->nitems);
-#endif
- if (IS_STATE(urdc, RDC_LOGGING) ||
- nq->qfflags & RDC_QFILLSLEEP) {
- fail = 0;
- goto fail;
- }
-
- mutex_enter(QLOCK(dq));
- INC_QNXTIO(dq, bufcnt);
- mutex_exit(QLOCK(dq));
-
- netq->net_qtail->orig_len = nullblocks; /* overload */
-
- return (netq);
-
-fail:
-
- if (hdr) {
- kmem_free(hdr, sizeof (*hdr));
- }
-
- if (netq) {
- if (netq->nitems > 0) {
- /* the never can happen case ... */
- if ((netq->nitems == 1) &&
- (netq->net_qhead->handle == NULL)) {
- (void) nsc_free_buf(buf);
- *abuf = NULL;
- }
-
- }
- rdc_discard_tmpq(netq);
- }
-
- mutex_enter(QLOCK(dq));
- rdc_dump_iohdrs(dq);
- mutex_exit(QLOCK(dq));
-
- if (fail) { /* real failure, not just state change */
-#ifdef DEBUG
- cmn_err(CE_WARN, "!rdc_diskq_buf2queue: failing disk queue %s",
- urdc->disk_queue);
-#endif
- rdc_fail_diskq(krdc, RDC_NOWAIT, RDC_DOLOG);
- }
-
- return (NULL);
-
-}
-
-/*
- * rdc_diskq_unqueue
- * remove one chunk from the diskq belonging to
- * rdc_k_info[index]
- * updates the head and tail pointers in the disk header
- * but does not write. The header should be written on ack
- * flusher should free whatever..
- */
-rdc_aio_t *
-rdc_diskq_unqueue(int index)
-{
- int rc, rc1, rc2;
- nsc_off_t qhead;
- int nullhandle = 0;
- io_hdr *iohdr;
- rdc_aio_t *aio = NULL;
- nsc_buf_t *buf = NULL;
- nsc_buf_t *abuf = NULL;
- rdc_group_t *group = NULL;
- disk_queue *q = NULL;
- rdc_k_info_t *krdc = &rdc_k_info[index];
- rdc_u_info_t *urdc = &rdc_u_info[index];
-
- group = krdc->group;
- q = &group->diskq;
-
- if (group->diskqfd == NULL) /* we've been disabled */
- return (NULL);
-
- aio = kmem_zalloc(sizeof (*aio), KM_NOSLEEP);
- if (!aio) {
- return (NULL);
- }
-
- iohdr = kmem_zalloc(sizeof (*iohdr), KM_NOSLEEP);
- if (!iohdr) {
- kmem_free(aio, sizeof (*aio));
- return (NULL);
- }
-
- mutex_enter(QLOCK(q));
- rdc_set_qbusy(q); /* make sure no one disables the queue */
- mutex_exit(QLOCK(q));
-
- DTRACE_PROBE(rdc_diskq_unq_rsrv);
-
- if (_rdc_rsrv_diskq(group)) {
- cmn_err(CE_WARN, "!rdc_unqueue: %s reserve failed",
- urdc->disk_queue);
- goto fail;
- }
-
- mutex_enter(QHEADLOCK(q));
- mutex_enter(QLOCK(q));
-
- if (IS_STATE(urdc, RDC_DISKQ_FAILED) || IS_STATE(urdc, RDC_LOGGING)) {
- rdc_clr_qbusy(q);
- mutex_exit(QLOCK(q));
- mutex_exit(QHEADLOCK(q));
- kmem_free(aio, sizeof (*aio));
- kmem_free(iohdr, sizeof (*iohdr));
- return (NULL);
- }
-
- if (QNXTIOSHLDWRAP(q)) {
-#ifdef DEBUG_DISKQWRAP
- cmn_err(CE_NOTE, "!wrapping Q nxtio: " QDISPLAY(q));
-#endif
- /*LINTED*/
- WRAPQNXTIO(q);
- }
-
- /* read the metainfo at q->nxt_io first */
- if (QNXTIO(q) == QTAIL(q)) { /* empty */
-
- _rdc_rlse_diskq(group);
- if (q->lastio->handle)
- (void) nsc_free_buf(q->lastio->handle);
- bzero(&(*q->lastio), sizeof (*q->lastio));
-
- mutex_exit(QHEADLOCK(q));
- rdc_clr_qbusy(q);
- mutex_exit(QLOCK(q));
- kmem_free(aio, sizeof (*aio));
- kmem_free(iohdr, sizeof (*iohdr));
- return (NULL);
- }
-
- qhead = QNXTIO(q);
-
- /*
- * have to drop the lock here, sigh. Cannot block incoming io
- * we have to wait until after this read to find out how
- * much to increment QNXTIO. Might as well grab the seq then too
- */
-
- while ((qhead == LASTQTAIL(q)) && (IS_QSTATE(q, QTAILBUSY))) {
- mutex_exit(QLOCK(q));
-#ifdef DEBUG_DISKQ
- cmn_err(CE_NOTE, "!Qtail busy delay lastqtail: %d", qhead);
-#endif
- delay(5);
- mutex_enter(QLOCK(q));
- }
- mutex_exit(QLOCK(q));
-
- DTRACE_PROBE(rdc_diskq_iohdr_read_start);
-
- rc = rdc_ns_io(group->diskqfd, NSC_READ, qhead,
- (uchar_t *)iohdr, FBA_SIZE(1));
-
- DTRACE_PROBE(rdc_diskq_iohdr_read_end);
-
- if (!RDC_SUCCESS(rc) || !rdc_iohdr_ok(iohdr)) {
- cmn_err(CE_WARN, "!unable to retrieve i/o data from queue %s"
- " at offset %" NSC_SZFMT " rc %d", urdc->disk_queue,
- qhead, rc);
-#ifdef DEBUG_DISKQ
- cmn_err(CE_WARN, "!qinfo: " QDISPLAY(q));
-#endif
- mutex_exit(QHEADLOCK(q));
- goto fail;
- }
-
-/* XXX process buffer here, creating rdc_aio_t's */
-
- mutex_enter(QLOCK(q));
- /* update the next pointer */
- if (iohdr->dat.flag == RDC_NULL_BUF) {
- INC_QNXTIO(q, FBA_LEN(sizeof (io_hdr)));
- nullhandle = 1;
- } else {
- INC_QNXTIO(q, (FBA_LEN(sizeof (io_hdr)) + iohdr->dat.len));
- }
-
- aio->seq = group->seq++;
- if (group->seq < aio->seq)
- group->seq = RDC_NEWSEQ + 1;
-
- mutex_exit(QLOCK(q));
- mutex_exit(QHEADLOCK(q));
-
-#ifdef DEBUG_FLUSHER_UBERNOISE
- p = &iohdr->dat;
- cmn_err(CE_NOTE, "!unqueued iohdr from %d pos: %d len: %d flag: %d "
- "iostatus: %d setid: %d time: %d", qhead, p->pos, p->len,
- p->flag, p->iostatus, p->setid, p->time);
-#endif
-
- if (nullhandle) /* nothing to get from queue */
- goto nullbuf;
-
- /* now that we know how much to get (iohdr.dat.len), get it */
- DTRACE_PROBE(rdc_diskq_unq_allocbuf1_start);
-
- rc = nsc_alloc_buf(group->diskqfd, qhead + 1, iohdr->dat.len,
- NSC_NOCACHE | NSC_READ, &buf);
-
- DTRACE_PROBE(rdc_diskq_unq_allocbuf1_end);
-
- /* and get somewhere to keep it for a bit */
- DTRACE_PROBE(rdc_diskq_unq_allocbuf2_start);
-
- rc1 = nsc_alloc_abuf(qhead + 1, iohdr->dat.len, 0, &abuf);
-
- DTRACE_PROBE(rdc_diskq_unq_allocbuf2_end);
-
- if (!RDC_SUCCESS(rc) || !RDC_SUCCESS(rc1)) { /* uh-oh */
- cmn_err(CE_WARN, "!disk queue %s read failure",
- urdc->disk_queue);
- goto fail;
- }
-
- /* move it on over... */
- rc2 = nsc_copy(buf, abuf, qhead + 1, qhead + 1, iohdr->dat.len);
-
- if (!RDC_SUCCESS(rc2)) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!nsc_copy failed for diskq unqueue");
-#endif
- goto fail;
- }
-
- /* let go of the real buf, we've got the abuf */
- (void) nsc_free_buf(buf);
- buf = NULL;
-
- aio->handle = abuf;
- /* Hack in the original sb_pos */
- aio->handle->sb_pos = iohdr->dat.hpos;
-
- /* skip the RDC_HANDLE_LIMITS check */
- abuf->sb_user |= RDC_DISKQUE;
-
-nullbuf:
- if (nullhandle) {
- aio->handle = NULL;
- }
-
- /* set up the rest of the aio values, seq set above ... */
- aio->pos = iohdr->dat.pos;
- aio->qpos = iohdr->dat.qpos;
- aio->len = iohdr->dat.len;
- aio->flag = iohdr->dat.flag;
- aio->index = rdc_setid2idx(iohdr->dat.setid);
- if (aio->index < 0) { /* uh-oh */
-#ifdef DEBUG
- cmn_err(CE_WARN, "!rdc_diskq_unqueue: index < 0");
-#endif
- goto fail;
- }
-
-
-#ifdef DEBUG_FLUSHER_UBERNOISE_STAMP
- h = &q->disk_hdr.h;
- cmn_err(CE_NOTE, "!stamping diskq header:\n"
- "magic: %x\nstate: %d\nhead_offset: %d\n"
- "tail_offset: %d\ndisk_size: %d\nnitems: %d\nblocks: %d\n",
- h->magic, h->state, h->head_offset, h->tail_offset,
- h->disk_size, h->nitems, h->blocks);
-#endif
-
- _rdc_rlse_diskq(group);
-
- mutex_enter(QLOCK(q));
- rdc_clr_qbusy(q);
- mutex_exit(QLOCK(q));
-
- DTRACE_PROBE(rdc_diskq_unq_rlse);
-
- iohdr->dat.iostatus = aio->seq;
- rdc_add_iohdr(iohdr, group);
-
-#ifdef DEBUG_FLUSHER_UBERNOISE
- if (!nullhandle) {
- cmn_err(CE_NOTE, "!UNQUEUING, %p"
- " contents: %c%c%c%c%c pos: %d len: %d",
- (void *)aio->handle,
- aio->handle->sb_vec[0].sv_addr[0],
- aio->handle->sb_vec[0].sv_addr[1],
- aio->handle->sb_vec[0].sv_addr[2],
- aio->handle->sb_vec[0].sv_addr[3],
- aio->handle->sb_vec[0].sv_addr[4],
- aio->handle->sb_pos, aio->handle->sb_len);
- } else {
- cmn_err(CE_NOTE, "!UNQUEUING, NULL " QDISPLAY(q));
- }
- cmn_err(CE_NOTE, "!qinfo: " QDISPLAY(q));
-#endif
-
- return (aio);
-
-fail:
- if (aio)
- kmem_free(aio, sizeof (*aio));
- if (iohdr)
- kmem_free(iohdr, sizeof (*iohdr));
- if (buf)
- (void) nsc_free_buf(buf);
- if (abuf)
- (void) nsc_free_buf(abuf);
-
- _rdc_rlse_diskq(group);
-#ifdef DEBUG
- cmn_err(CE_WARN, "!diskq_unqueue: failing diskq");
-#endif
- mutex_enter(QLOCK(q));
- rdc_clr_qbusy(q);
- mutex_exit(QLOCK(q));
-
- rdc_fail_diskq(krdc, RDC_NOWAIT, RDC_DOLOG);
-
- return (NULL);
-}
-
-int
-rdc_diskq_inuse(rdc_set_t *set, char *diskq)
-{
- rdc_u_info_t *urdc;
- char *group;
- int index;
-
- group = set->group_name;
-
- ASSERT(MUTEX_HELD(&rdc_conf_lock));
-
- if ((rdc_lookup_bitmap(diskq) >= 0) ||
- (rdc_lookup_configured(diskq) >= 0)) {
- return (1);
- }
- for (index = 0; index < rdc_max_sets; index++) {
- urdc = &rdc_u_info[index];
-
- if (!IS_ENABLED(urdc))
- continue;
-
- /* same diskq different group */
- if ((strcmp(urdc->disk_queue, diskq) == 0) &&
- (urdc->group_name[0] == '\0' ||
- strcmp(urdc->group_name, group))) {
- return (1);
- }
- }
- /* last, but not least, lets see if someone is getting really funky */
- if ((strcmp(set->disk_queue, set->primary.file) == 0) ||
- (strcmp(set->disk_queue, set->primary.bitmap) == 0)) {
- return (1);
- }
-
- return (0);
-
-}
-
-#ifdef DEBUG
-int maxlen = 0;
-int avelen = 0;
-int totalen = 0;
-int lencalls = 0;
-
-void
-update_lenstats(int len)
-{
- if (lencalls == 0) {
- lencalls = 1;
- avelen = 0;
- maxlen = 0;
- totalen = 0;
- }
-
- if (len > maxlen)
- maxlen = len;
- totalen += len;
- avelen = totalen / lencalls;
-}
-#endif
-
-/*
- * rdc_calc_len()
- * returns the size of the diskq that can be read for dequeuing
- * always <= RDC_MAX_DISKQREAD
- */
-int
-rdc_calc_len(rdc_k_info_t *krdc, disk_queue *dq)
-{
- nsc_size_t len = 0;
-
- ASSERT(MUTEX_HELD(QLOCK(dq)));
-
- /* ---H-----N-----T--- */
- if (QNXTIO(dq) < QTAIL(dq)) {
-
- len = min(RDC_MAX_DISKQREAD, QTAIL(dq) - QNXTIO(dq));
-
- /* ---T-----H-----N--- */
- } else if (QNXTIO(dq) > QTAIL(dq)) {
- if (QWRAP(dq)) {
- len = min(RDC_MAX_DISKQREAD, QWRAP(dq) - QNXTIO(dq));
- } else { /* should never happen */
- len = min(RDC_MAX_DISKQREAD, QSIZE(dq) - QNXTIO(dq));
- }
- } else if (QNXTIO(dq) == QTAIL(dq)) {
- if (QWRAP(dq) && !IS_QSTATE(dq, QNXTIOWRAPD))
- len = min(RDC_MAX_DISKQREAD, QWRAP(dq) - QNXTIO(dq));
- }
-
- len = min(len, krdc->maxfbas);
-
-#ifdef DEBUG
- lencalls++;
- update_lenstats(len);
-#endif
-
- return ((int)len);
-}
-
-/*
- * lie a little if we can, so we don't get tied up in
- * _nsc_wait_dbuf() on the next read. sb_len MUST be
- * restored before nsc_free_buf() however, or we will
- * be looking at memory leak city..
- * so update the entire queue with the info as well
- * and the one that ends up freeing it, can fix the len
- * IMPORTANT: This assumes that we are not cached, in
- * 3.2 caching was turned off for data volumes, if that
- * changes, then this must too
- */
-void
-rdc_trim_buf(nsc_buf_t *buf, net_queue *q)
-{
- rdc_aio_t *p;
- int len;
-
- if (buf == NULL || q == NULL)
- return;
-
- if (q && (buf->sb_len >
- (q->blocks + q->nitems - q->net_qtail->orig_len))) {
- len = buf->sb_len;
- buf->sb_len = (q->blocks + q->nitems - q->net_qtail->orig_len);
- }
-
- p = q->net_qhead;
- do {
- p->orig_len = len;
- p = p->next;
-
- } while (p);
-
-}
-
-/*
- * rdc_read_diskq_buf()
- * read a large as possible chunk of the diskq into a nsc_buf_t
- * and convert it to a net_queue of rdc_aio_t's to be appended
- * to the group's netqueue
- */
-net_queue *
-rdc_read_diskq_buf(int index)
-{
- nsc_buf_t *buf = NULL;
- net_queue *tmpnq = NULL;
- disk_queue *dq = NULL;
- rdc_k_info_t *krdc = &rdc_k_info[index];
- rdc_u_info_t *urdc = &rdc_u_info[index];
- rdc_group_t *group = krdc->group;
- net_queue *nq = &group->ra_queue;
- int len = 0;
- int rc;
- int fail = 0;
- int offset = 0;
-
- if (group == NULL || group->diskqfd == NULL) {
- DTRACE_PROBE(rdc_read_diskq_buf_bail1);
- return (NULL);
- }
-
- dq = &group->diskq;
-
- mutex_enter(QLOCK(dq));
- rdc_set_qbusy(dq); /* prevent disables on the queue */
- mutex_exit(QLOCK(dq));
-
- if (_rdc_rsrv_diskq(group)) {
- cmn_err(CE_WARN, "!rdc_readdiskqbuf: %s reserve failed",
- urdc->disk_queue);
- mutex_enter(QLOCK(dq));
- rdc_clr_qbusy(dq); /* prevent disables on the queue */
- mutex_exit(QLOCK(dq));
- return (NULL);
- }
-
- mutex_enter(QHEADLOCK(dq));
- mutex_enter(QLOCK(dq));
-
- if (IS_STATE(urdc, RDC_DISKQ_FAILED) ||
- IS_STATE(urdc, RDC_LOGGING) ||
- (nq->qfflags & RDC_QFILLSLEEP)) {
- mutex_exit(QLOCK(dq));
- mutex_exit(QHEADLOCK(dq));
- DTRACE_PROBE(rdc_read_diskq_buf_bail2);
- goto done;
- }
-
- /*
- * real corner case here, we need to let the flusher wrap first.
- * we've gotten too far ahead, so just delay and try again
- */
- if (IS_QSTATE(dq, QNXTIOWRAPD) && AUXQWRAP(dq)) {
- mutex_exit(QLOCK(dq));
- mutex_exit(QHEADLOCK(dq));
- goto done;
- }
-
- if (QNXTIOSHLDWRAP(dq)) {
-#ifdef DEBUG_DISKQWRAP
- cmn_err(CE_NOTE, "!wrapping Q nxtio: " QDISPLAY(dq));
-#endif
- /*LINTED*/
- WRAPQNXTIO(dq);
- }
-
- /* read the metainfo at q->nxt_io first */
- if (!QNITEMS(dq)) { /* empty */
-
- if (dq->lastio->handle)
- (void) nsc_free_buf(dq->lastio->handle);
- bzero(&(*dq->lastio), sizeof (*dq->lastio));
- mutex_exit(QLOCK(dq));
- mutex_exit(QHEADLOCK(dq));
- DTRACE_PROBE(rdc_read_diskq_buf_bail3);
- goto done;
- }
-
-
- len = rdc_calc_len(krdc, dq);
-
- if ((len <= 0) || (IS_STATE(urdc, RDC_LOGGING)) ||
- (IS_STATE(urdc, RDC_DISKQ_FAILED)) ||
- (nq->qfflags & RDC_QFILLSLEEP)) {
- mutex_exit(QLOCK(dq));
- mutex_exit(QHEADLOCK(dq));
- /*
- * a write could be trying to get on the queue, or if
- * the queue is really really small, a complete image
- * of it could be on the net queue waiting for flush.
- * the latter being a fairly stupid scenario and a gross
- * misconfiguration.. but what the heck, why make the thread
- * thrash around.. just pause a little here.
- */
- if (len <= 0)
- delay(50);
-
- DTRACE_PROBE3(rdc_read_diskq_buf_bail4, int, len,
- int, rdc_get_vflags(urdc), int, nq->qfflags);
-
- goto done;
- }
-
- DTRACE_PROBE2(rdc_calc_len, int, len, int, (int)QNXTIO(dq));
-
-#ifdef DEBUG_FLUSHER_UBERNOISE
- cmn_err(CE_WARN, "!CALC_LEN(%d) h:%d n%d t%d, w%d",
- len, QHEAD(dq), QNXTIO(dq), QTAIL(dq), QWRAP(dq));
- cmn_err(CE_CONT, "!qinfo: " QDISPLAYND(dq));
-#endif
- SET_QCOALBOUNDS(dq, QNXTIO(dq) + len);
-
- while ((LASTQTAIL(dq) > 0) && !QWRAP(dq) &&
- ((QNXTIO(dq) + len) >= LASTQTAIL(dq)) &&
- (IS_QSTATE(dq, QTAILBUSY))) {
- mutex_exit(QLOCK(dq));
-
-#ifdef DEBUG_FLUSHER_UBERNOISE
- cmn_err(CE_NOTE, "!Qtail busy delay nxtio %d len %d "
- "lastqtail: %d", QNXTIO(dq), len, LASTQTAIL(dq));
-#endif
- delay(20);
- mutex_enter(QLOCK(dq));
- }
-
- offset = QNXTIO(dq);
-
- /*
- * one last check to see if we have gone logging, or should.
- * we may have released the mutex above, so check again
- */
- if ((IS_STATE(urdc, RDC_LOGGING)) ||
- (IS_STATE(urdc, RDC_DISKQ_FAILED)) ||
- (nq->qfflags & RDC_QFILLSLEEP)) {
- mutex_exit(QLOCK(dq));
- mutex_exit(QHEADLOCK(dq));
- goto done;
- }
-
- mutex_exit(QLOCK(dq));
- mutex_exit(QHEADLOCK(dq));
-
- DTRACE_PROBE2(rdc_buf2q_preread, int, offset, int, len);
-
- rc = nsc_alloc_buf(group->diskqfd, offset, len,
- NSC_NOCACHE | NSC_READ, &buf);
-
- if (!RDC_SUCCESS(rc)) {
- cmn_err(CE_WARN, "!disk queue %s read failure pos %" NSC_SZFMT
- " len %d", urdc->disk_queue, QNXTIO(dq), len);
- fail++;
- buf = NULL;
- DTRACE_PROBE(rdc_read_diskq_buf_bail5);
- goto done;
- }
-
- DTRACE_PROBE2(rdc_buf2q_postread, int, offset, nsc_size_t, buf->sb_len);
-
- /*
- * convert buf to a net_queue. buf2queue will
- * update the QNXTIO pointer for us, based on
- * the last readable queue item
- */
- tmpnq = rdc_diskq_buf2queue(group, &buf, index);
-
-#ifdef DEBUG_FLUSHER_UBERNOISE
- cmn_err(CE_NOTE, "!QBUF p: %d l: %d p+l: %d users: %d qblocks: %d ",
- "qitems: %d WASTED: %d", buf->sb_pos, buf->sb_len,
- buf->sb_pos+buf->sb_len, buf->sb_user, tmpnq?tmpnq->blocks:-1,
- tmpnq?tmpnq->nitems:-1,
- tmpnq?((buf->sb_len-tmpnq->nitems) - tmpnq->blocks):-1);
-#endif
-
- DTRACE_PROBE3(rdc_buf2que_returned, net_queue *, tmpnq?tmpnq:0,
- uint64_t, tmpnq?tmpnq->nitems:0,
- uint_t, tmpnq?tmpnq->net_qhead->seq:0);
-done:
-
- /* we don't need to retain the buf */
- if (tmpnq == NULL)
- if (buf) {
- (void) nsc_free_buf(buf);
- buf = NULL;
- }
-
- rdc_trim_buf(buf, tmpnq);
-
- mutex_enter(QLOCK(dq));
- rdc_clr_qbusy(dq);
- mutex_exit(QLOCK(dq));
-
- _rdc_rlse_diskq(group);
-
- if (fail) {
- rdc_fail_diskq(krdc, RDC_NOWAIT, RDC_DOLOG);
- tmpnq = NULL;
- }
-
- return (tmpnq);
-}
-
-/*
- * rdc_dequeue()
- * removes the head of the memory queue
- */
-rdc_aio_t *
-rdc_dequeue(rdc_k_info_t *krdc, int *rc)
-{
- net_queue *q = &krdc->group->ra_queue;
- disk_queue *dq = &krdc->group->diskq;
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- rdc_aio_t *aio;
-
- *rc = 0;
-
- if (q == NULL)
- return (NULL);
-
- mutex_enter(&q->net_qlock);
-
- aio = q->net_qhead;
-
- if (aio == NULL) {
-#ifdef DEBUG
- if (q->nitems != 0 || q->blocks != 0 || q->net_qtail != 0) {
- cmn_err(CE_PANIC,
- "rdc_dequeue(1): q %p, q blocks %" NSC_SZFMT
- " , nitems %" NSC_SZFMT ", qhead %p qtail %p",
- (void *) q, q->blocks, q->nitems,
- (void *) aio, (void *) q->net_qtail);
- }
-#endif
-
- mutex_exit(&q->net_qlock);
-
- if ((!IS_STATE(urdc, RDC_LOGGING)) &&
- (!(q->qfflags & RDC_QFILLSLEEP)) &&
- (!IS_STATE(urdc, RDC_SYNCING)) && (QNITEMS(dq) > 0)) {
- *rc = EAGAIN;
- }
-
- goto done;
- }
-
- /* aio remove from q */
-
- q->net_qhead = aio->next;
- aio->next = NULL;
-
- if (q->net_qtail == aio)
- q->net_qtail = q->net_qhead;
-
- q->blocks -= aio->len;
- q->nitems--;
-
-#ifdef DEBUG
- if (q->net_qhead == NULL) {
- if (q->nitems != 0 || q->blocks != 0 || q->net_qtail != 0) {
- cmn_err(CE_PANIC, "rdc_dequeue(2): q %p, q blocks %"
- NSC_SZFMT " nitems %" NSC_SZFMT
- " , qhead %p qtail %p",
- (void *) q, q->blocks, q->nitems,
- (void *) q->net_qhead, (void *) q->net_qtail);
- }
- }
-#endif
- mutex_exit(&q->net_qlock);
-done:
-
- mutex_enter(&q->net_qlock);
-
- if (rdc_qfill_shldwakeup(krdc))
- cv_broadcast(&q->qfcv);
-
- /*
- * clear EAGAIN if
- * logging or q filler thread is sleeping or stopping altogether
- * or if q filler thread is dead already
- * or if syncing, this will return a null aio, with no error code set
- * telling the flusher to die
- */
- if (*rc == EAGAIN) {
- if (IS_STATE(urdc, RDC_LOGGING) ||
- (q->qfflags & (RDC_QFILLSLEEP | RDC_QFILLSTOP)) ||
- (IS_QSTATE(dq, (RDC_QDISABLEPEND | RDC_STOPPINGFLUSH))) ||
- (q->qfill_sleeping == RDC_QFILL_DEAD) ||
- (IS_STATE(urdc, RDC_SYNCING)))
- *rc = 0;
- }
-
- mutex_exit(&q->net_qlock);
-
- return (aio);
-
-}
-
-/*
- * rdc_qfill_shldsleep()
- * returns 1 if the qfilling code should cv_wait() 0 if not.
- * reasons for going into cv_wait();
- * there is nothing in the diskq to flush to mem.
- * the memory queue has gotten too big and needs more flushing attn.
- */
-int
-rdc_qfill_shldsleep(rdc_k_info_t *krdc)
-{
- net_queue *nq = &krdc->group->ra_queue;
- disk_queue *dq = &krdc->group->diskq;
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
-
- ASSERT(MUTEX_HELD(&nq->net_qlock));
-
- if (!RDC_IS_DISKQ(krdc->group))
- return (1);
-
- if (nq->qfflags & RDC_QFILLSLEEP) {
-#ifdef DEBUG_DISKQ_NOISY
- cmn_err(CE_NOTE, "!Sleeping diskq->memq flusher: QFILLSLEEP idx: %d",
- krdc->index);
-#endif
- return (1);
- }
-
- if (IS_STATE(urdc, RDC_LOGGING) || IS_STATE(urdc, RDC_SYNCING)) {
-#ifdef DEBUG_DISKQ_NOISY
- cmn_err(CE_NOTE, "!Sleeping diskq->memq flusher: Sync|Log (0x%x)"
- " idx: %d", rdc_get_vflags(urdc), urdc->index);
-#endif
- return (1);
- }
-
- mutex_enter(QLOCK(dq));
- if ((QNXTIO(dq) == QTAIL(dq)) && !IS_QSTATE(dq, RDC_QFULL)) {
-#ifdef DEBUG_DISKQ_NOISY
- cmn_err(CE_NOTE, "!Sleeping diskq->memq flusher: QEMPTY");
-#endif
- mutex_exit(QLOCK(dq));
- return (1);
- }
- mutex_exit(QLOCK(dq));
-
- if (nq->blocks >= RDC_MAX_QBLOCKS) {
- nq->hwmhit = 1;
- /* stuck flushers ? */
-#ifdef DEBUG_DISKQ_NOISY
- cmn_err(CE_NOTE, "!Sleeping diskq->memq flusher: memq full:"
- " seq: %d seqack %d", krdc->group->seq,
- krdc->group->seqack);
-#endif
- return (1);
- }
-
- return (0);
-}
-
-/*
- * rdc_join_netqueues(a, b)
- * appends queue b to queue a updating all the queue info
- * as it is assumed queue a is the important one,
- * it's mutex must be held. no one can add to queue b
- */
-void
-rdc_join_netqueues(net_queue *q, net_queue *tmpq)
-{
- ASSERT(MUTEX_HELD(&q->net_qlock));
-
- if (q->net_qhead == NULL) { /* empty */
-#ifdef DEBUG
- if (q->blocks != 0 || q->nitems != 0) {
- cmn_err(CE_PANIC, "rdc filler: q %p, qhead 0, "
- " q blocks %" NSC_SZFMT ", nitems %" NSC_SZFMT,
- (void *) q, q->blocks, q->nitems);
- }
-#endif
- q->net_qhead = tmpq->net_qhead;
- q->net_qtail = tmpq->net_qtail;
- q->nitems = tmpq->nitems;
- q->blocks = tmpq->blocks;
- } else {
- q->net_qtail->next = tmpq->net_qhead;
- q->net_qtail = tmpq->net_qtail;
- q->nitems += tmpq->nitems;
- q->blocks += tmpq->blocks;
- }
-
- if (q->nitems > q->nitems_hwm) {
- q->nitems_hwm = q->nitems;
- }
-
- if (q->blocks > q->blocks_hwm) {
- q->blocks_hwm = q->blocks;
- }
-}
-
-/*
- * rdc_qfiller_thr() single thread that moves
- * data from the diskq to a memory queue for
- * the flusher to pick up.
- */
-void
-rdc_qfiller_thr(rdc_k_info_t *krdc)
-{
- rdc_group_t *grp = krdc->group;
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- net_queue *q = &grp->ra_queue;
- net_queue *tmpq = NULL;
- int index = krdc->index;
-
- q->qfill_sleeping = RDC_QFILL_AWAKE;
- while (!(q->qfflags & RDC_QFILLSTOP)) {
- if (!RDC_IS_DISKQ(grp) ||
- IS_STATE(urdc, RDC_LOGGING) ||
- IS_STATE(urdc, RDC_DISKQ_FAILED) ||
- (q->qfflags & RDC_QFILLSLEEP)) {
- goto nulltmpq;
- }
-
- DTRACE_PROBE(qfiller_top);
- tmpq = rdc_read_diskq_buf(index);
-
- if (tmpq == NULL)
- goto nulltmpq;
-
- if ((q->qfflags & RDC_QFILLSLEEP) ||
- IS_STATE(urdc, RDC_LOGGING)) {
- rdc_discard_tmpq(tmpq);
- goto nulltmpq;
- }
-
- mutex_enter(&q->net_qlock);
-
- /* race with log, redundant yet paranoid */
- if ((q->qfflags & RDC_QFILLSLEEP) ||
- IS_STATE(urdc, RDC_LOGGING)) {
- rdc_discard_tmpq(tmpq);
- mutex_exit(&q->net_qlock);
- goto nulltmpq;
- }
-
-
- rdc_join_netqueues(q, tmpq);
- kmem_free(tmpq, sizeof (*tmpq));
- tmpq = NULL;
-
- mutex_exit(&q->net_qlock);
-nulltmpq:
- /*
- * sleep for a while if we can.
- * the enqueuing or flushing code will
- * wake us if if necessary.
- */
- mutex_enter(&q->net_qlock);
- while (rdc_qfill_shldsleep(krdc)) {
- q->qfill_sleeping = RDC_QFILL_ASLEEP;
- DTRACE_PROBE(qfiller_sleep);
- cv_wait(&q->qfcv, &q->net_qlock);
- DTRACE_PROBE(qfiller_wakeup);
- q->qfill_sleeping = RDC_QFILL_AWAKE;
- if (q->qfflags & RDC_QFILLSTOP) {
-#ifdef DEBUG_DISKQ
- cmn_err(CE_NOTE,
- "!rdc_qfiller_thr: recieved kill signal");
-#endif
- mutex_exit(&q->net_qlock);
- goto done;
- }
- }
- mutex_exit(&q->net_qlock);
-
- DTRACE_PROBE(qfiller_bottom);
- }
-done:
- DTRACE_PROBE(qfiller_done);
- q->qfill_sleeping = RDC_QFILL_DEAD; /* the big sleep */
-
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!rdc_qfiller_thr stopping");
-#endif
- q->qfflags &= ~RDC_QFILLSTOP;
-
-}
-
-int
-_rdc_add_diskq(int index, char *diskq)
-{
- rdc_k_info_t *krdc, *kp;
- rdc_u_info_t *urdc, *up;
- rdc_group_t *group;
- int rc;
-
- krdc = &rdc_k_info[index];
- urdc = &rdc_u_info[index];
- group = krdc->group;
-
- if (!diskq || urdc->disk_queue[0]) { /* how'd that happen? */
-#ifdef DEBUG
- cmn_err(CE_WARN, "!NULL diskq in _rdc_add_diskq");
-#endif
- rc = -1;
- goto fail;
- }
-
- /* if the enable fails, this is bzero'ed */
- (void) strncpy(urdc->disk_queue, diskq, NSC_MAXPATH);
- group->flags &= ~RDC_MEMQUE;
- group->flags |= RDC_DISKQUE;
-
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!adding diskq to group %s", urdc->group_name);
-#endif
- mutex_enter(&rdc_conf_lock);
- rc = rdc_enable_diskq(krdc);
- mutex_exit(&rdc_conf_lock);
-
- if (rc == RDC_EQNOADD) {
- goto fail;
- }
-
- RDC_ZERO_BITREF(krdc);
- for (kp = krdc->group_next; kp != krdc; kp = kp->group_next) {
- up = &rdc_u_info[kp->index];
- (void) strncpy(up->disk_queue, diskq, NSC_MAXPATH);
- /* size lives in the diskq structure, already set by enable */
- RDC_ZERO_BITREF(kp);
- }
-
-fail:
- return (rc);
-
-}
-
-/*
- * add a diskq to an existing set/group
- */
-int
-rdc_add_diskq(rdc_config_t *uparms, spcs_s_info_t kstatus)
-{
- char *diskq;
- int rc;
- int index;
- rdc_k_info_t *krdc, *this;
- rdc_u_info_t *urdc;
- rdc_group_t *group;
- nsc_size_t vol_size = 0;
- nsc_size_t req_size = 0;
-
- mutex_enter(&rdc_conf_lock);
- index = rdc_lookup_byname(uparms->rdc_set);
- mutex_exit(&rdc_conf_lock);
- if (index < 0) {
- spcs_s_add(kstatus, RDC_EALREADY, uparms->rdc_set->primary.file,
- uparms->rdc_set->secondary.file);
- rc = RDC_EALREADY;
- goto failed;
- }
- urdc = &rdc_u_info[index];
- krdc = &rdc_k_info[index];
- this = &rdc_k_info[index];
- group = krdc->group;
- diskq = uparms->rdc_set->disk_queue;
-
- if (!IS_ASYNC(urdc)) {
- spcs_s_add(kstatus, RDC_EQWRONGMODE, urdc->primary.intf,
- urdc->primary.file, urdc->secondary.intf,
- urdc->secondary.file);
- rc = RDC_EQNOQUEUE;
- goto failed;
- }
-
- do {
- if (!IS_STATE(urdc, RDC_LOGGING)) {
- spcs_s_add(kstatus, RDC_EQNOTLOGGING,
- uparms->rdc_set->disk_queue);
- rc = RDC_EQNOTLOGGING;
- goto failed;
- }
- /* make sure that we have enough bitmap vol */
- req_size = RDC_BITMAP_FBA + FBA_LEN(krdc->bitmap_size);
- req_size += FBA_LEN(krdc->bitmap_size * BITS_IN_BYTE);
-
- rc = _rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL);
-
- if (!RDC_SUCCESS(rc)) {
- cmn_err(CE_WARN,
- "!rdc_open_diskq: Bitmap reserve failed");
- spcs_s_add(kstatus, RDC_EBITMAP,
- urdc->primary.bitmap);
- rc = RDC_EBITMAP;
- goto failed;
- }
-
- (void) nsc_partsize(krdc->bitmapfd, &vol_size);
-
- _rdc_rlse_devs(krdc, RDC_BMP);
-
- if (vol_size < req_size) {
- spcs_s_add(kstatus, RDC_EBITMAP2SMALL,
- urdc->primary.bitmap);
- rc = RDC_EBITMAP2SMALL;
- goto failed;
- }
-
- krdc = krdc->group_next;
- urdc = &rdc_u_info[krdc->index];
-
- } while (krdc != this);
-
- if (urdc->disk_queue[0] != '\0') {
- spcs_s_add(kstatus, RDC_EQALREADY, urdc->primary.intf,
- urdc->primary.file, urdc->secondary.intf,
- urdc->secondary.file);
- rc = RDC_EQALREADY;
- goto failed;
- }
-
- if (uparms->options & RDC_OPT_SECONDARY) { /* how'd we get here? */
- spcs_s_add(kstatus, RDC_EQWRONGMODE);
- rc = RDC_EQWRONGMODE;
- goto failed;
- }
-
- mutex_enter(&rdc_conf_lock);
- if (rdc_diskq_inuse(uparms->rdc_set, uparms->rdc_set->disk_queue)) {
- spcs_s_add(kstatus, RDC_EDISKQINUSE,
- uparms->rdc_set->disk_queue);
- rc = RDC_EDISKQINUSE;
- mutex_exit(&rdc_conf_lock);
- goto failed;
- }
- mutex_exit(&rdc_conf_lock);
-
- rdc_group_enter(krdc);
- rc = _rdc_add_diskq(urdc->index, diskq);
- if (rc < 0 || rc == RDC_EQNOADD) {
- group->flags &= ~RDC_DISKQUE;
- group->flags |= RDC_MEMQUE;
- spcs_s_add(kstatus, RDC_EQNOADD, uparms->rdc_set->disk_queue);
- rc = RDC_EQNOADD;
- }
- rdc_group_exit(krdc);
-failed:
- return (rc);
-}
-
-int
-_rdc_init_diskq(rdc_k_info_t *krdc)
-{
- rdc_group_t *group = krdc->group;
- disk_queue *q = &group->diskq;
-
- rdc_init_diskq_header(group, &group->diskq.disk_hdr);
- SET_QNXTIO(q, QHEAD(q));
-
- if (rdc_stamp_diskq(krdc, 0, RDC_NOLOG) < 0)
- goto fail;
-
- return (0);
-fail:
- return (-1);
-}
-
-/*
- * inititalize the disk queue. This is a destructive
- * operation that will not check for emptiness of the queue.
- */
-int
-rdc_init_diskq(rdc_config_t *uparms, spcs_s_info_t kstatus)
-{
- int rc = 0;
- int index;
- rdc_k_info_t *krdc, *kp;
- rdc_u_info_t *urdc, *up;
- rdc_set_t *uset;
- rdc_group_t *group;
- disk_queue *qp;
-
- uset = uparms->rdc_set;
-
- mutex_enter(&rdc_conf_lock);
- index = rdc_lookup_byname(uset);
- mutex_exit(&rdc_conf_lock);
- if (index < 0) {
- spcs_s_add(kstatus, RDC_EALREADY, uset->primary.file,
- uset->secondary.file);
- rc = RDC_EALREADY;
- goto fail;
- }
-
- krdc = &rdc_k_info[index];
- urdc = &rdc_u_info[index];
- group = krdc->group;
- qp = &group->diskq;
-
- if (!IS_STATE(urdc, RDC_SYNCING) && !IS_STATE(urdc, RDC_LOGGING)) {
- spcs_s_add(kstatus, RDC_EQUEISREP, urdc->disk_queue);
- rc = RDC_EQUEISREP;
- goto fail;
- }
-
- /*
- * a couple of big "ifs" here. in the first implementation
- * neither of these will be possible. This will come into
- * play when we persist the queue across reboots
- */
- if (!(uparms->options & RDC_OPT_FORCE_QINIT)) {
- if (!QEMPTY(qp)) {
- if (group->rdc_writer) {
- spcs_s_add(kstatus, RDC_EQFLUSHING,
- urdc->disk_queue);
- rc = RDC_EQFLUSHING;
- } else {
- spcs_s_add(kstatus, RDC_EQNOTEMPTY,
- urdc->disk_queue);
- rc = RDC_EQNOTEMPTY;
- }
- goto fail;
- }
- }
-
- mutex_enter(QLOCK(qp));
- if (_rdc_init_diskq(krdc) < 0) {
- mutex_exit(QLOCK(qp));
- goto fail;
- }
- rdc_dump_iohdrs(qp);
-
- rdc_group_enter(krdc);
-
- rdc_clr_flags(urdc, RDC_QUEUING);
- for (kp = krdc->group_next; kp != krdc; kp = kp->group_next) {
- up = &rdc_u_info[kp->index];
- rdc_clr_flags(up, RDC_QUEUING);
- }
- rdc_group_exit(krdc);
-
- mutex_exit(QLOCK(qp));
-
- return (0);
-fail:
- /* generic queue failure */
- if (!rc) {
- spcs_s_add(kstatus, RDC_EQINITFAIL, urdc->disk_queue);
- rc = RDC_EQINITFAIL;
- }
-
- return (rc);
-}
-
-int
-_rdc_kill_diskq(rdc_u_info_t *urdc)
-{
- rdc_k_info_t *krdc = &rdc_k_info[urdc->index];
- rdc_group_t *group = krdc->group;
- disk_queue *q = &group->diskq;
- rdc_u_info_t *up;
- rdc_k_info_t *p;
-
- group->flags |= RDC_DISKQ_KILL;
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!disabling disk queue %s", urdc->disk_queue);
-#endif
-
- mutex_enter(QLOCK(q));
- rdc_init_diskq_header(group, &q->disk_hdr);
- rdc_dump_iohdrs(q);
-
- /*
- * nsc_close the queue and zero out the queue name
- */
- rdc_wait_qbusy(q);
- rdc_close_diskq(group);
- mutex_exit(QLOCK(q));
- SET_QSIZE(q, 0);
- rdc_clr_flags(urdc, RDC_DISKQ_FAILED);
- bzero(urdc->disk_queue, NSC_MAXPATH);
- for (p = krdc->group_next; p != krdc; p = p->group_next) {
- up = &rdc_u_info[p->index];
- rdc_clr_flags(up, RDC_DISKQ_FAILED);
- bzero(up->disk_queue, NSC_MAXPATH);
- }
-
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!_rdc_kill_diskq: enabling memory queue");
-#endif
- group->flags &= ~(RDC_DISKQUE|RDC_DISKQ_KILL);
- group->flags |= RDC_MEMQUE;
- return (0);
-}
-
-/*
- * remove this diskq regardless of whether it is draining or not
- * stops the flusher by invalidating the qdata (ie, instant empty)
- * remove the disk qeueue from the group, leaving the group with a memory
- * queue.
- */
-int
-rdc_kill_diskq(rdc_config_t *uparms, spcs_s_info_t kstatus)
-{
- int rc;
- int index;
- rdc_u_info_t *urdc;
- rdc_k_info_t *krdc;
- rdc_set_t *rdc_set = uparms->rdc_set;
-
- mutex_enter(&rdc_conf_lock);
- index = rdc_lookup_byname(uparms->rdc_set);
- mutex_exit(&rdc_conf_lock);
-
- if (index < 0) {
- spcs_s_add(kstatus, RDC_EALREADY, rdc_set->primary.file,
- rdc_set->secondary.file);
- rc = RDC_EALREADY;
- goto failed;
- }
-
- urdc = &rdc_u_info[index];
- krdc = &rdc_k_info[index];
-
- if (!RDC_IS_DISKQ(krdc->group)) {
- spcs_s_add(kstatus, RDC_EQNOQUEUE, rdc_set->primary.intf,
- rdc_set->primary.file, rdc_set->secondary.intf,
- rdc_set->secondary.file);
- rc = RDC_EQNOQUEUE;
- goto failed;
- }
-
-/*
- * if (!IS_STATE(urdc, RDC_LOGGING)) {
- * spcs_s_add(kstatus, RDC_EQNOTLOGGING,
- * uparms->rdc_set->disk_queue);
- * rc = RDC_EQNOTLOGGING;
- * goto failed;
- * }
- */
- rdc_unintercept_diskq(krdc->group); /* stop protecting queue */
- rdc_group_enter(krdc); /* to prevent further flushing */
- rc = _rdc_kill_diskq(urdc);
- rdc_group_exit(krdc);
-
-failed:
- return (rc);
-}
-
-/*
- * remove a diskq from a group.
- * removal of a diskq from a set, or rather
- * a set from a queue, is done by reconfigging out
- * of the group. This removes the diskq from a whole
- * group and replaces it with a memory based queue
- */
-#define NUM_RETRIES 15 /* Number of retries to wait if no progress */
-int
-rdc_rem_diskq(rdc_config_t *uparms, spcs_s_info_t kstatus)
-{
- int index;
- rdc_u_info_t *urdc;
- rdc_k_info_t *krdc;
- rdc_k_info_t *this;
- volatile rdc_group_t *group;
- volatile disk_queue *diskq;
- int threads, counter;
- long blocks;
-
- mutex_enter(&rdc_conf_lock);
- index = rdc_lookup_byname(uparms->rdc_set);
- mutex_exit(&rdc_conf_lock);
- if (index < 0) {
- spcs_s_add(kstatus, RDC_EALREADY, uparms->rdc_set->primary.file,
- uparms->rdc_set->secondary.file);
- return (RDC_EALREADY);
- }
-
- urdc = &rdc_u_info[index];
- this = &rdc_k_info[index];
- krdc = &rdc_k_info[index];
-
- do {
- if (!IS_STATE(urdc, RDC_LOGGING)) {
- spcs_s_add(kstatus, RDC_EQNOTLOGGING,
- urdc->disk_queue);
- return (RDC_EQNOTLOGGING);
- }
- krdc = krdc->group_next;
- urdc = &rdc_u_info[krdc->index];
-
- } while (krdc != this);
-
- /*
- * If there is no group or diskq configured, we can leave now
- */
- if (!(group = krdc->group) || !(diskq = &group->diskq))
- return (0);
-
-
- /*
- * Wait if not QEMPTY or threads still active
- */
- counter = 0;
- while (!QEMPTY(diskq) || group->rdc_thrnum) {
-
- /*
- * Capture counters to determine if progress is being made
- */
- blocks = QBLOCKS(diskq);
- threads = group->rdc_thrnum;
-
- /*
- * Wait
- */
- delay(HZ);
-
- /*
- * Has the group or disk queue gone away while delayed?
- */
- if (!(group = krdc->group) || !(diskq = &group->diskq))
- return (0);
-
- /*
- * Are we still seeing progress?
- */
- if (blocks == QBLOCKS(diskq) && threads == group->rdc_thrnum) {
- /*
- * No progress see, decrement retry counter
- */
- if (counter++ > NUM_RETRIES) {
- /*
- * No progress seen, increment retry counter
- */
- int rc = group->rdc_thrnum ?
- RDC_EQFLUSHING : RDC_EQNOTEMPTY;
- spcs_s_add(kstatus, rc, urdc->disk_queue);
- return (rc);
- }
- } else {
- /*
- * Reset counter, as we've made progress
- */
- counter = 0;
- }
- }
-
- return (0);
-}
diff --git a/usr/src/uts/common/avs/ns/rdc/rdc_diskq.h b/usr/src/uts/common/avs/ns/rdc/rdc_diskq.h
deleted file mode 100644
index 27b476d293..0000000000
--- a/usr/src/uts/common/avs/ns/rdc/rdc_diskq.h
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _RDC_DISKQ_H
-#define _RDC_DISKQ_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef _KERNEL
-
-#define RDC_DISKQ_HEADER_OFF 0 /* beginning of disk */
-#define RDC_DISKQ_DATA_OFF FBA_LEN(1024) /* beginning of queue */
-
-typedef struct qentry {
- int magic;
- int type; /* special data ? io? bitmap? */
- nsc_off_t pos; /* position it will be in the rdc_aio_t */
- nsc_off_t hpos; /* starting pos of orig nsc_buf_t */
- nsc_off_t qpos; /* where this info is in the queue */
- nsc_size_t len; /* len */
- int flag;
- int iostatus;
- uint32_t setid; /* krdc */
- time_t time;
- void *next;
-} q_data;
-
-typedef union io_dat {
- q_data dat;
- char dummy[512];
-} io_hdr;
-
-#define RDC_IOHDR_MAGIC 0x494F4844 /* IOHD */
-#define RDC_IOHDR_DONE 0xDEADCAFE /* this q entry has been flushed */
-#define RDC_IOHDR_WAITING 0xBEEFCAFE /* this q entry is waiting for ack */
-
-/* type */
-#define RDC_QUEUEIO 0x02
-
-#define RDC_DISKQ_MAGIC 0x44534B51
-#define RDC_DISKQ_VER_ORIG 0x01
-#define RDC_DISKQ_VER_64BIT 0x02
-
-#ifdef NSC_MULTI_TERABYTE
-#define RDC_DISKQ_VERS RDC_DISKQ_VER_64BIT
-#else
-#define RDC_DISKQ_VERS RDC_DISKQ_VER_ORIG
-#endif
-
-typedef struct diskqheader1 {
- int magic;
- int vers;
- int state;
- int head_offset; /* offset of meta-info of head (fbas) */
- int tail_offset; /* addr of next write (fbas) */
- int disk_size; /* allow growing ? (fbas) */
- long nitems; /* items */
- long blocks; /* fbas */
- int qwrap; /* where the tail wrapped */
- int auxqwrap; /* if the tail wraps again, before head wraps once */
- uint_t seq_last; /* last sequence before suspend */
- uint_t ack_last; /* last ack before suspend */
-} diskq_header1;
-
-typedef struct diskqheader2 {
- int magic;
- int vers;
- int state;
- uint64_t head_offset; /* offset of meta-info of head (fbas) */
- uint64_t tail_offset; /* addr of next write (fbas) */
- uint64_t disk_size; /* allow growing ? (fbas) */
- uint64_t nitems; /* items */
- uint64_t blocks; /* fbas */
- uint64_t qwrap; /* where the tail wrapped */
- uint64_t auxqwrap; /* if the tail wraps again, before head wraps once */
- uint_t seq_last; /* last sequence before suspend */
- uint_t ack_last; /* last ack before suspend */
-} diskq_header2;
-
-#ifdef NSC_MULTI_TERABYTE
-typedef diskq_header2 diskq_header;
-#ifdef _LP64
-#define RDC_DQFMT "lu"
-#else
-#define RDC_DQFMT "llu"
-#endif
-#else
-typedef diskq_header1 diskq_header;
-#define RDC_DQFMT "ld"
-#endif
-typedef union headr {
- diskq_header h;
- char dummy[512];
-} dqheader;
-
-/* flags for the state field in the header */
-
-#define RDC_SHUTDOWN_OK 0x01
-#define RDC_SHUTDOWN_BAD 0x02
-#define QNXTIOWRAPD 0x04
-#define QHEADWRAPD 0x08
-#define QTAILBUSY 0x10 /* tell flusher not to grab, incomplete */
-#define RDC_QNOBLOCK 0x10000 /* can also be passed out by status */
-#define RDC_QBADRESUME 0x20 /* don't resume bit ref */
-#define RDC_QFULL 0x40 /* the queue is in a full delay loop */
-#define RDC_STOPPINGFLUSH 0x80
-
-#define RDC_QFILLSTOP 0x01 /* diskq->memq flusher kill switch */
-#define RDC_QFILLSLEEP 0x02 /* explicit diskq->memq flusher sleep */
-
-#define RDC_MAX_DISKQREAD 0x1000 /* max 2 mb q read */
-
-typedef struct diskqueue { /* the incore info about the diskq */
- dqheader disk_hdr; /* info about the queue */
- long nitems_hwm;
- long blocks_hwm;
- long throttle_delay;
- nsc_off_t last_tail; /* pos of the last tail write */
- volatile int inflbls; /* number of inflight blocks */
- volatile int inflitems; /* number of inflight blocks */
-
- kmutex_t disk_qlock; /* protects all things in diskq */
- /* and all things in dqheader */
-
- kmutex_t head_lock;
- kcondvar_t busycv;
- int busycnt;
- nsc_off_t nxt_io; /* flushers head pointer */
- int hdrcnt; /* number of io_hdrs on list */
- nsc_off_t coalesc_bounds; /* don't coalesce below this offset */
- rdc_aio_t *lastio; /* cached copy of the last write on q */
- io_hdr *iohdrs; /* flushed, not ack'd on queue */
- io_hdr *hdr_last; /* tail of iohdr list */
- kcondvar_t qfullcv; /* block, queue is full */
-} disk_queue;
-
-/* diskq macros (gets) */
-
-#define QHEAD(q) q->disk_hdr.h.head_offset
-#define QNXTIO(q) q->nxt_io
-#define QTAIL(q) q->disk_hdr.h.tail_offset
-#define QNITEMS(q) q->disk_hdr.h.nitems
-#define QBLOCKS(q) q->disk_hdr.h.blocks
-#define QSTATE(q) q->disk_hdr.h.state
-#define IS_QSTATE(q, s) (q->disk_hdr.h.state & s)
-#define QSIZE(q) q->disk_hdr.h.disk_size
-#define QMAGIC(q) q->disk_hdr.h.magic
-#define QVERS(q) q->disk_hdr.h.vers
-#define QSEQ(q) q->disk_hdr.h.seq_last
-#define QACK(q) q->disk_hdr.h.ack_last
-#define QEMPTY(q) ((QTAIL(q) == QHEAD(q))&&(!(QNITEMS(q))))
-#define QWRAP(q) q->disk_hdr.h.qwrap
-#define AUXQWRAP(q) q->disk_hdr.h.auxqwrap
-#define LASTQTAIL(q) q->last_tail
-#define QCOALBOUNDS(q) q->coalesc_bounds
-
-/* diskq macros (sets) */
-
-#define INC_QHEAD(q, n) q->disk_hdr.h.head_offset += n
-#define INC_QNXTIO(q, n) q->nxt_io += n
-#define DEC_QNXTIO(q, n) q->nxt_io -= n
-#define DEC_QHEAD(q, n) q->disk_hdr.h.head_offset -= n
-#define INC_QTAIL(q, n) q->disk_hdr.h.tail_offset += n
-#define DEC_QTAIL(q, n) q->disk_hdr.h.tail_offset -= n
-#define INC_QNITEMS(q, n) q->disk_hdr.h.nitems += n
-#define DEC_QNITEMS(q, n) q->disk_hdr.h.nitems -= n
-#define INC_QBLOCKS(q, n) q->disk_hdr.h.blocks += n
-#define DEC_QBLOCKS(q, n) q->disk_hdr.h.blocks -= n
-
-#define SET_QMAGIC(q, n) q->disk_hdr.h.magic = n
-#define SET_QSTATE(q, n) q->disk_hdr.h.state |= n
-#define CLR_QSTATE(q, n) q->disk_hdr.h.state &= ~n
-#define SET_QHEAD(q, n) q->disk_hdr.h.head_offset = n
-#define SET_QNXTIO(q, n) q->nxt_io = n
-#define SET_QHDRCNT(q, n) q->hdrcnt = n
-#define SET_QTAIL(q, n) q->disk_hdr.h.tail_offset = n
-#define SET_LASTQTAIL(q, n) q->last_tail = n
-#define SET_LASTQWRITE(q, w) q->last_qwrite = w
-#define SET_QSIZE(q, n) q->disk_hdr.h.disk_size = n
-#define SET_QNITEMS(q, n) q->disk_hdr.h.nitems = n
-#define SET_QBLOCKS(q, n) q->disk_hdr.h.blocks = n
-
-#define SET_QWRAP(q, n) q->disk_hdr.h.qwrap = n
-#define CLR_QWRAP(q) q->disk_hdr.h.qwrap = 0
-#define SET_AUXQWRAP(q, n) q->disk_hdr.h.auxqwrap = n
-#define CLR_AUXQWRAP(q) q->disk_hdr.h.auxqwrap = 0
-#define SET_QCOALBOUNDS(q, n) q->coalesc_bounds = n
-
-#define WRAPQTAIL(q) \
- do { \
- if (QWRAP(q)) { \
- SET_AUXQWRAP(q, QTAIL(q)); \
- } else { \
- SET_QWRAP(q, QTAIL(q)); \
- } \
- SET_QTAIL(q, RDC_DISKQ_DATA_OFF); \
- } while (0)
-
-#define DO_AUXQWRAP(q) \
- do { \
- SET_QWRAP(q, AUXQWRAP(q)); \
- SET_AUXQWRAP(q, 0); \
- } while (0)
-
-/* these can be wrapped by different threads, avoid the race */
-#define WRAPQHEAD(q) \
- do { \
- if (IS_QSTATE(q, QNXTIOWRAPD)) { \
- if (AUXQWRAP(q)) { \
- DO_AUXQWRAP(q); \
- } else { \
- SET_QWRAP(q, 0); \
- } \
- CLR_QSTATE(q, QNXTIOWRAPD); \
- } else { \
- SET_QSTATE(q, QHEADWRAPD); \
- } \
- SET_QHEAD(q, RDC_DISKQ_DATA_OFF); \
- } while (0)
-
-#define WRAPQNXTIO(q) \
- do { \
- if (IS_QSTATE(q, QHEADWRAPD)) { \
- if (AUXQWRAP(q)) { \
- DO_AUXQWRAP(q); \
- } else { \
- SET_QWRAP(q, 0); \
- } \
- CLR_QSTATE(q, QHEADWRAPD); \
- } else { \
- SET_QSTATE(q, QNXTIOWRAPD); \
- } \
- SET_QNXTIO(q, RDC_DISKQ_DATA_OFF); \
- } while (0)
-
-#define DQEND(q) (QWRAP(q)?QWRAP(q):QSIZE(q))
-
-#define FITSONQ(q, n) \
- (((QBLOCKS(q)+QNITEMS(q)+RDC_DISKQ_DATA_OFF+n) >= \
- (uint64_t)DQEND(q))?0:1)
-
-/* diskq defines/macros (non-specific) */
-
-#define RDC_NOLOG 0x00
-#define RDC_WAIT 0x01
-#define RDC_NOWAIT 0x02
-#define RDC_DOLOG 0x04 /* put the group into logging */
-#define RDC_NOFAIL 0x08 /* don't fail the queue, just init */
-#define RDC_GROUP_LOCKED 0x10 /* trust me, I have the group lock */
-
-#define RDC_WRITTEN 0x10 /* data has been commited to queue */
-#define RDC_LAST 0x20 /* end of dequeued buffer, discard */
-
-/* CSTYLED */
-#define RDC_BETWEEN(a,b,c) (a<b?((c>=a)&&(c<=b)):((a!=b)&&((c<b)||(c>=a))))
-/* CSTYLED */
-
-#define QHEADSHLDWRAP(q) (QWRAP(q) && (QHEAD(q) >= QWRAP(q)))
-#define QNXTIOSHLDWRAP(q) (QWRAP(q) && (QNXTIO(q) >= QWRAP(q)))
-#define QTAILSHLDWRAP(q, size) (QTAIL(q) + size > QSIZE(q))
-#define QCOALESCEOK(q, dec) ((q->lastio->iostatus & RDC_WRITTEN) && \
- ((QTAIL(q) > QNXTIO(q)) ? \
- (((QTAIL(q) - dec) > QNXTIO(q)) && ((QTAIL(q) - dec) > \
- QCOALBOUNDS(q))):\
- (QNXTIOSHLDWRAP(q) && QTAIL(q) > RDC_DISKQ_DATA_OFF)))
-
-#define QLOCK(q) &q->disk_qlock
-#define QTAILLOCK(q) &q->tail_lock
-#define QHEADLOCK(q) &q->head_lock
-
-#define QDISPLAY(q) "qmagic: %x qvers: %d qstate: %x qhead: %" \
- NSC_SZFMT " qnxtio: %" NSC_SZFMT " qtail: %" NSC_SZFMT " qtaillast: %" \
- NSC_SZFMT " qsize: %" NSC_SZFMT " qnitems: %" RDC_DQFMT \
- " qblocks: %" RDC_DQFMT " coalbounds %" NSC_SZFMT, QMAGIC(q), \
- QVERS(q), QSTATE(q), QHEAD(q), QNXTIO(q), QTAIL(q), LASTQTAIL(q), \
- QSIZE(q), QNITEMS(q), QBLOCKS(q), QCOALBOUNDS(q)
-
-#define QDISPLAYND(q) "m: %x v: %d s: %d h: %" NSC_SZFMT " n: %" \
- NSC_SZFMT " t: %" NSC_SZFMT " l: %" NSC_SZFMT " z: %" NSC_SZFMT \
- " i: %" RDC_DQFMT " b: %" RDC_DQFMT " w: %" NSC_SZFMT \
- " a: %" NSC_SZFMT, \
- QMAGIC(q), QVERS(q), QSTATE(q), QHEAD(q), \
- QNXTIO(q), QTAIL(q), LASTQTAIL(q), QSIZE(q), QNITEMS(q), \
- QBLOCKS(q), QWRAP(q), AUXQWRAP(q)
-
-/* Disk queue flusher state */
-#define RDC_QFILL_AWAKE (0)
-#define RDC_QFILL_ASLEEP (1)
-#define RDC_QFILL_DEAD (-1)
-
-/* functions */
-
-int rdc_add_diskq(rdc_config_t *uparms, spcs_s_info_t kstatus);
-int rdc_rem_diskq(rdc_config_t *uparms, spcs_s_info_t kstatus);
-int rdc_kill_diskq(rdc_config_t *uparms, spcs_s_info_t kstatus);
-int rdc_init_diskq(rdc_config_t *uparms, spcs_s_info_t kstatus);
-int rdc_lookup_diskq(char *path);
-int rdc_diskq_inuse(rdc_set_t *set, char *diskq);
-void rdc_dump_iohdrs(disk_queue *q);
-extern void rdc_fixlen(rdc_aio_t *aio);
-
-#endif /* _KERNEL */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _RDC_DISKQ_H */
diff --git a/usr/src/uts/common/avs/ns/rdc/rdc_health.c b/usr/src/uts/common/avs/ns/rdc/rdc_health.c
deleted file mode 100644
index 16bc34242d..0000000000
--- a/usr/src/uts/common/avs/ns/rdc/rdc_health.c
+++ /dev/null
@@ -1,800 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- * Copyright (c) 2016 by Delphix. All rights reserved.
- */
-
-/*
- * RDC interface health monitoring code.
- */
-
-#include <sys/types.h>
-#include <sys/ksynch.h>
-#include <sys/errno.h>
-#include <sys/debug.h>
-#include <sys/cmn_err.h>
-#include <sys/kmem.h>
-
-#include <sys/errno.h>
-
-#ifdef _SunOS_2_6
-/*
- * on 2.6 both dki_lock.h and rpc/types.h define bool_t so we
- * define enum_t here as it is all we need from rpc/types.h
- * anyway and make it look like we included it. Yuck.
- */
-#define _RPC_TYPES_H
-typedef int enum_t;
-#else
-#ifndef DS_DDICT
-#include <rpc/types.h>
-#endif
-#endif /* _SunOS_2_6 */
-
-#include <sys/ddi.h>
-#include <sys/nsc_thread.h>
-#ifdef DS_DDICT
-#include <sys/nsctl/contract.h>
-#endif
-#include <sys/nsctl/nsctl.h>
-
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_k.h>
-#include <sys/unistat/spcs_errors.h>
-
-#include "rdc_io.h"
-#include "rdc_clnt.h"
-
-
-/*
- * Forward declarations.
- */
-
-static void rdc_update_health(rdc_if_t *);
-
-/*
- * Global data.
- */
-
-/*
- * These structures are added when a new host name is introduced to the
- * kernel. They never disappear (but that won't waste much space at all).
- */
-typedef struct rdc_link_down {
- char host[MAX_RDC_HOST_SIZE]; /* The host name of this link */
- int waiting; /* A user is waiting to be woken up */
- int link_down; /* The current state of the link */
- struct rdc_link_down *next; /* Chain */
- kcondvar_t syncd_cv; /* Syncd wakeup */
- kmutex_t syncd_mutex; /* Lock for syncd_cv */
-} rdc_link_down_t;
-static rdc_link_down_t *rdc_link_down = NULL;
-
-int rdc_health_thres = RDC_HEALTH_THRESHOLD;
-rdc_if_t *rdc_if_top;
-
-
-/*
- * IPv6 addresses are represented as 16bit hexadecimal integers
- * separated by colons. Contiguous runs of zeros can be abbreviated by
- * double colons:
- * FF02:0:0:0:0:1:200E:8C6C
- * |
- * v
- * FF02::1:200E:8C6C
- */
-void
-rdc_if_ipv6(const uint16_t *addr, char *buf)
-{
- const int end = 8; /* 8 shorts, 128 bits in an IPv6 address */
- int i;
-
- for (i = 0; i < end; i++) {
- if (i > 0)
- (void) sprintf(buf, "%s:", buf);
-
- if (addr[i] != 0 || i == 0 || i == (end - 1)) {
- /* first, last, or non-zero value */
- (void) sprintf(buf, "%s%x", buf, (int)addr[i]);
- } else {
- if ((i + 1) < end && addr[i + 1] != 0) {
- /* single zero */
- (void) sprintf(buf, "%s%x", buf, (int)addr[i]);
- } else {
- /* skip contiguous zeros */
- while ((i + 1) < end && addr[i + 1] == 0)
- i++;
- }
- }
- }
-}
-
-static void
-rdc_if_xxx(rdc_if_t *ip, char *updown)
-{
- if (strcmp("inet6", ip->srv->ri_knconf->knc_protofmly) == 0) {
- uint16_t *this = (uint16_t *)ip->ifaddr.buf;
- uint16_t *other = (uint16_t *)ip->r_ifaddr.buf;
- char this_str[256], other_str[256];
-
- bzero(this_str, sizeof (this_str));
- bzero(other_str, sizeof (other_str));
- rdc_if_ipv6(&this[4], this_str);
- rdc_if_ipv6(&other[4], other_str);
-
- cmn_err(CE_NOTE, "!SNDR: Interface %s <==> %s : %s",
- this_str, other_str, updown);
- } else {
- uchar_t *this = (uchar_t *)ip->ifaddr.buf;
- uchar_t *other = (uchar_t *)ip->r_ifaddr.buf;
-
- cmn_err(CE_NOTE,
- "!SNDR: Interface %d.%d.%d.%d <==> %d.%d.%d.%d : %s",
- (int)this[4], (int)this[5], (int)this[6], (int)this[7],
- (int)other[4], (int)other[5], (int)other[6], (int)other[7],
- updown);
- }
-}
-
-
-static void
-rdc_if_down(rdc_if_t *ip)
-{
- rdc_if_xxx(ip, "Down");
-}
-
-
-static void
-rdc_if_up(rdc_if_t *ip)
-{
- rdc_if_xxx(ip, "Up");
-}
-
-
-/*
- * Health monitor for a single interface.
- *
- * The secondary sends ping RPCs to the primary.
- * The primary just stores the results and updates its structures.
- */
-static void
-rdc_health_thread(void *arg)
-{
- rdc_if_t *ip = (rdc_if_t *)arg;
- struct rdc_ping ping;
- struct rdc_ping6 ping6;
- struct timeval t;
- int down = 1;
- int ret, err;
- int sec = 0;
- char ifaddr[RDC_MAXADDR];
- char r_ifaddr[RDC_MAXADDR];
- uint16_t *sp;
-
- bcopy(ip->ifaddr.buf, ifaddr, ip->ifaddr.len);
- sp = (uint16_t *)ifaddr;
- *sp = htons(*sp);
- bcopy(ip->r_ifaddr.buf, r_ifaddr, ip->r_ifaddr.len);
- sp = (uint16_t *)r_ifaddr;
- *sp = htons(*sp);
-
- while ((ip->exiting != 1) && (net_exit != ATM_EXIT)) {
- delay(HZ);
-
- /* setup RPC timeout */
-
- t.tv_sec = rdc_rpc_tmout;
- t.tv_usec = 0;
-
- if (ip->issecondary && !ip->no_ping) {
- if (ip->rpc_version < RDC_VERSION7) {
- bcopy(ip->r_ifaddr.buf, ping6.p_ifaddr,
- RDC_MAXADDR);
- /* primary ifaddr */
- bcopy(ip->ifaddr.buf, ping6.s_ifaddr,
- RDC_MAXADDR);
- /* secondary ifaddr */
- err = rdc_clnt_call_any(ip->srv, ip,
- RDCPROC_PING4, xdr_rdc_ping6,
- (char *)&ping6, xdr_int, (char *)&ret, &t);
- } else {
- ping.p_ifaddr.buf = r_ifaddr;
- ping.p_ifaddr.len = ip->r_ifaddr.len;
- ping.p_ifaddr.maxlen = ip->r_ifaddr.len;
- ping.s_ifaddr.buf = ifaddr;
- ping.s_ifaddr.len = ip->ifaddr.len;
- ping.s_ifaddr.maxlen = ip->ifaddr.len;
- err = rdc_clnt_call_any(ip->srv, ip,
- RDCPROC_PING4, xdr_rdc_ping, (char *)&ping,
- xdr_int, (char *)&ret, &t);
- }
-
-
- if (err || ret) {
- /* RPC failed - link is down */
- if (!down && !ip->isprimary) {
- /*
- * don't print messages if also
- * a primary - the primary will
- * take care of it.
- */
- rdc_if_down(ip);
- down = 1;
- }
- rdc_dump_alloc_bufs(ip);
- ip->no_ping = 1;
-
- /*
- * Start back at the max possible version
- * since the remote server could come back
- * on a different protocol version.
- */
- mutex_enter(&rdc_ping_lock);
- ip->rpc_version = RDC_VERS_MAX;
- mutex_exit(&rdc_ping_lock);
- } else {
- if (down && !ip->isprimary) {
- /*
- * was failed, but now ok
- *
- * don't print messages if also
- * a primary - the primary will
- * take care of it.
- */
- rdc_if_up(ip);
- down = 0;
- }
- }
- }
- if (!ip->isprimary && down && ++sec == 5) {
- sec = 0;
- rdc_dump_alloc_bufs(ip);
- }
-
- if (ip->isprimary)
- rdc_update_health(ip);
- }
-
- /* signal that this thread is done */
- ip->exiting = 2;
-}
-
-
-int
-rdc_isactive_if(struct netbuf *addr, struct netbuf *r_addr)
-{
- rdc_if_t *ip;
- int rc = 0;
-
- /* search for existing interface structure */
-
- mutex_enter(&rdc_ping_lock);
- for (ip = rdc_if_top; ip; ip = ip->next) {
- if (ip->exiting != 0)
- continue;
- if (((bcmp(ip->ifaddr.buf, addr->buf, addr->len) == 0) &&
- (bcmp(ip->r_ifaddr.buf, r_addr->buf, r_addr->len) == 0)) ||
- ((bcmp(ip->r_ifaddr.buf, addr->buf, addr->len) == 0) &&
- (bcmp(ip->ifaddr.buf, r_addr->buf, r_addr->len) == 0))) {
- /* found matching interface structure */
- if (ip->isprimary && !ip->if_down) {
- rc = 1;
- } else if (ip->issecondary && !ip->no_ping) {
- rc = 1;
- }
- break;
- }
- }
- mutex_exit(&rdc_ping_lock);
- return (rc);
-}
-
-/*
- * Set the rdc rpc version of the rdc_if_t.
- *
- * Called from incoming rpc calls which start before
- * the health service becomes established.
- */
-void
-rdc_set_if_vers(rdc_u_info_t *urdc, rpcvers_t vers)
-{
- rdc_if_t *ip;
- struct netbuf *addr, *r_addr;
-
- if (rdc_get_vflags(urdc) & RDC_PRIMARY) {
- addr = &(urdc->primary.addr);
- r_addr = &(urdc->secondary.addr);
- } else {
- addr = &(urdc->secondary.addr);
- r_addr = &(urdc->primary.addr);
- }
-
- /* search for existing interface structure */
-
- mutex_enter(&rdc_ping_lock);
- for (ip = rdc_if_top; ip; ip = ip->next) {
- if (ip->exiting != 0)
- continue;
- if (((bcmp(ip->ifaddr.buf, addr->buf, addr->len) == 0) &&
- (bcmp(ip->r_ifaddr.buf, r_addr->buf, r_addr->len) == 0)) ||
- ((bcmp(ip->r_ifaddr.buf, addr->buf, addr->len) == 0) &&
- (bcmp(ip->ifaddr.buf, r_addr->buf, r_addr->len) == 0))) {
- /* found matching interface structure */
- ip->rpc_version = vers;
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!rdc intf %p rpc version set to %u",
- (void *)ip, vers);
-#endif
- break;
- }
- }
- mutex_exit(&rdc_ping_lock);
-}
-
-/*
- * Free all the rdc_link_down structures (only at module unload time)
- */
-void
-rdc_link_down_free()
-{
- rdc_link_down_t *p;
- rdc_link_down_t *q;
-
- if (rdc_link_down == NULL)
- return;
-
- for (p = rdc_link_down->next; p != rdc_link_down; ) {
- q = p;
- p = p->next;
- kmem_free(q, sizeof (*q));
- }
- kmem_free(rdc_link_down, sizeof (*q));
- rdc_link_down = NULL;
-}
-
-
-/*
- * Look up the supplied hostname in the rdc_link_down chain. Add a new
- * entry if it isn't found. Return a pointer to the new or found entry.
- */
-static rdc_link_down_t *
-rdc_lookup_host(char *host)
-{
- rdc_link_down_t *p;
-
- mutex_enter(&rdc_ping_lock);
-
- if (rdc_link_down == NULL) {
- rdc_link_down = kmem_zalloc(sizeof (*rdc_link_down), KM_SLEEP);
- rdc_link_down->next = rdc_link_down;
- }
-
- for (p = rdc_link_down->next; p != rdc_link_down; p = p->next) {
- if (strcmp(host, p->host) == 0) {
- /* Match */
- mutex_exit(&rdc_ping_lock);
- return (p);
- }
- }
-
- /* No match, must create a new entry */
-
- p = kmem_zalloc(sizeof (*p), KM_SLEEP);
- p->link_down = 1;
- p->next = rdc_link_down->next;
- rdc_link_down->next = p;
- (void) strncpy(p->host, host, MAX_RDC_HOST_SIZE);
- mutex_init(&p->syncd_mutex, NULL, MUTEX_DRIVER, NULL);
- cv_init(&p->syncd_cv, NULL, CV_DRIVER, NULL);
-
- mutex_exit(&rdc_ping_lock);
- return (p);
-}
-
-
-/*
- * Handle the RDC_LINK_DOWN ioctl.
- * The user specifies which host they're interested in.
- * This function is woken up when the link to that host goes down.
- */
-
-/* ARGSUSED3 */
-int
-_rdc_link_down(void *arg, int mode, spcs_s_info_t kstatus, int *rvp)
-{
- char host[MAX_RDC_HOST_SIZE];
- rdc_link_down_t *syncdp;
- clock_t timeout = RDC_SYNC_EVENT_TIMEOUT * 2; /* 2 min */
- int rc = 0;
-
- if (ddi_copyin(arg, host, MAX_RDC_HOST_SIZE, mode))
- return (EFAULT);
-
-
- syncdp = rdc_lookup_host(host);
-
- mutex_enter(&syncdp->syncd_mutex);
- if (!syncdp->link_down) {
- syncdp->waiting = 1;
- if (cv_timedwait_sig(&syncdp->syncd_cv, &syncdp->syncd_mutex,
- nsc_lbolt() + timeout) == 0) {
- /* Woken by a signal, not a link down event */
- syncdp->waiting = 0;
- rc = EAGAIN;
- spcs_s_add(kstatus, rc);
- }
-
- }
- mutex_exit(&syncdp->syncd_mutex);
-
- return (rc);
-}
-
-
-/*
- * Add an RDC set to an interface
- *
- * If the interface is new, add it to the list of interfaces.
- */
-rdc_if_t *
-rdc_add_to_if(rdc_srv_t *svp, struct netbuf *addr, struct netbuf *r_addr,
- int primary)
-{
- rdc_if_t *new, *ip;
-
- if ((addr->buf == NULL) || (r_addr->buf == NULL))
- return (NULL);
-
- /* setup a new interface structure */
- new = (rdc_if_t *)kmem_zalloc(sizeof (*new), KM_SLEEP);
- if (!new)
- return (NULL);
-
- dup_rdc_netbuf(addr, &new->ifaddr);
- dup_rdc_netbuf(r_addr, &new->r_ifaddr);
- new->rpc_version = RDC_VERS_MAX;
- new->srv = rdc_create_svinfo(svp->ri_hostname, &svp->ri_addr,
- svp->ri_knconf);
- new->old_pulse = -1;
- new->new_pulse = 0;
-
- if (!new->srv) {
- free_rdc_netbuf(&new->r_ifaddr);
- free_rdc_netbuf(&new->ifaddr);
- kmem_free(new, sizeof (*new));
- return (NULL);
- }
-
- /* search for existing interface structure */
-
- mutex_enter(&rdc_ping_lock);
-
- for (ip = rdc_if_top; ip; ip = ip->next) {
- if ((bcmp(ip->ifaddr.buf, addr->buf, addr->len) == 0) &&
- (bcmp(ip->r_ifaddr.buf, r_addr->buf, r_addr->len) == 0) &&
- ip->exiting == 0) {
- /* found matching interface structure */
- break;
- }
- }
-
- if (!ip) {
- /* add new into the chain */
-
- new->next = rdc_if_top;
- rdc_if_top = new;
- ip = new;
-
- /* start daemon */
-
- ip->last = nsc_time();
- ip->deadness = 1;
- ip->if_down = 1;
-
- if (nsc_create_process(rdc_health_thread, ip, TRUE)) {
- mutex_exit(&rdc_ping_lock);
- return (NULL);
- }
- }
-
- /* mark usage type */
-
- if (primary) {
- ip->isprimary = 1;
- } else {
- ip->issecondary = 1;
- ip->no_ping = 0;
- }
-
- mutex_exit(&rdc_ping_lock);
-
- /* throw away new if it was not used */
-
- if (ip != new) {
- free_rdc_netbuf(&new->r_ifaddr);
- free_rdc_netbuf(&new->ifaddr);
- rdc_destroy_svinfo(new->srv);
- kmem_free(new, sizeof (*new));
- }
-
- return (ip);
-}
-
-
-/*
- * Update an interface following the removal of an RDC set.
- *
- * If there are no more RDC sets using the interface, delete it from
- * the list of interfaces.
- *
- * Either clear krdc->intf, or ensure !IS_CONFIGURED(krdc) before calling this.
- */
-void
-rdc_remove_from_if(rdc_if_t *ip)
-{
- rdc_k_info_t *krdc;
- rdc_u_info_t *urdc;
- rdc_if_t **ipp;
- int pfound = 0;
- int sfound = 0;
- int delete = 1;
- int index;
-
- mutex_enter(&rdc_ping_lock);
-
- /*
- * search for RDC sets using this interface and update
- * the isprimary and issecondary flags.
- */
-
- for (index = 0; index < rdc_max_sets; index++) {
- krdc = &rdc_k_info[index];
- urdc = &rdc_u_info[index];
- if (IS_CONFIGURED(krdc) && krdc->intf == ip) {
- delete = 0;
-
- if (rdc_get_vflags(urdc) & RDC_PRIMARY) {
- pfound = 1;
- } else {
- sfound = 1;
- }
-
- if (pfound && sfound)
- break;
- }
- }
-
- ip->isprimary = pfound;
- ip->issecondary = sfound;
-
- if (!delete || ip->exiting > 0) {
- mutex_exit(&rdc_ping_lock);
- return;
- }
-
- /* mark and wait for daemon to exit */
-
- ip->exiting = 1;
-
- mutex_exit(&rdc_ping_lock);
-
- while (ip->exiting == 1)
- delay(drv_usectohz(10));
-
- mutex_enter(&rdc_ping_lock);
-
- ASSERT(ip->exiting == 2);
-
- /* remove from chain */
-
- for (ipp = &rdc_if_top; *ipp; ipp = &((*ipp)->next)) {
- if (*ipp == ip) {
- *ipp = ip->next;
- break;
- }
- }
-
- mutex_exit(&rdc_ping_lock);
-
- /* free unused interface structure */
-
- free_rdc_netbuf(&ip->r_ifaddr);
- free_rdc_netbuf(&ip->ifaddr);
- rdc_destroy_svinfo(ip->srv);
- kmem_free(ip, sizeof (*ip));
-}
-
-
-/*
- * Check the status of the link to the secondary, and optionally update
- * the primary-side ping variables.
- *
- * For use on a primary only.
- *
- * Returns:
- * TRUE - interface up.
- * FALSE - interface down.
- */
-int
-rdc_check_secondary(rdc_if_t *ip, int update)
-{
- int rc = TRUE;
-
- if (!ip || !ip->isprimary) {
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!rdc_check_secondary: ip %p, isprimary %d, issecondary %d",
- (void *) ip, ip ? ip->isprimary : 0,
- ip ? ip->issecondary : 0);
-#endif
- return (FALSE);
- }
-
- if (!ip->deadness) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!rdc_check_secondary: ip %p, ip->deadness %d",
- (void *) ip, ip->deadness);
-#endif
- return (FALSE);
- }
-
- if (!update) {
- /* quick look */
- return ((ip->deadness > rdc_health_thres) ? FALSE : TRUE);
- }
-
- /* update (slow) with lock */
-
- mutex_enter(&rdc_ping_lock);
-
- if (ip->old_pulse == ip->new_pulse) {
- /*
- * ping has not been received since last update
- * or we have not yet been pinged,
- * the health thread has started only as a
- * local client so far, not so on the other side
- */
-
- if (ip->last != nsc_time()) {
- /* time has passed, so move closer to death */
-
- ip->last = nsc_time();
- ip->deadness++;
-
- if (ip->deadness <= 0) {
- /* avoid the wrap */
- ip->deadness = rdc_health_thres + 1;
- }
- }
-
- if (ip->deadness > rdc_health_thres) {
- rc = FALSE;
- /*
- * Start back at the max possible version
- * since the remote server could come back
- * on a different protocol version.
- */
- ip->rpc_version = RDC_VERS_MAX;
- }
- } else {
- ip->old_pulse = ip->new_pulse;
- }
-
- mutex_exit(&rdc_ping_lock);
- return (rc);
-}
-
-
-/*
- * Update the interface structure with the latest ping info, and
- * perform interface up/down transitions if required.
- *
- * For use on a primary only.
- */
-static void
-rdc_update_health(rdc_if_t *ip)
-{
- rdc_k_info_t *krdc;
- rdc_u_info_t *urdc;
- int index;
- rdc_link_down_t *syncdp;
-
- if (!ip->isprimary) {
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!rdc_update_health: ip %p, isprimary %d, issecondary %d",
- (void *) ip, ip ? ip->isprimary : 0,
- ip ? ip->issecondary : 0);
-#endif
- return;
- }
-
- if (!rdc_check_secondary(ip, TRUE)) {
- /* interface down */
- if (!ip->if_down) {
- rdc_if_down(ip);
- ip->if_down = 1;
-
- /* scan rdc sets and update status */
-
- for (index = 0; index < rdc_max_sets; index++) {
- krdc = &rdc_k_info[index];
- urdc = &rdc_u_info[index];
-
- if (IS_ENABLED(urdc) && (krdc->intf == ip) &&
- (rdc_get_vflags(urdc) & RDC_PRIMARY) &&
- !(rdc_get_vflags(urdc) & RDC_LOGGING)) {
- /* mark down */
-
- rdc_group_enter(krdc);
- /*
- * check for possible race with
- * with delete logic
- */
- if (!IS_ENABLED(urdc)) {
- rdc_group_exit(krdc);
- continue;
- }
- rdc_group_log(krdc, RDC_NOFLUSH |
- RDC_NOREMOTE | RDC_QUEUING,
- "hm detected secondary "
- "interface down");
-
- rdc_group_exit(krdc);
-
- /* dump async queues */
- rdc_dump_queue(index);
- }
- }
-
- /* dump allocated bufs */
- rdc_dump_alloc_bufs(ip);
- }
-
- syncdp = rdc_lookup_host(ip->srv->ri_hostname);
- mutex_enter(&syncdp->syncd_mutex);
- if (syncdp->link_down == 0) {
- /* Link has gone down, notify rdcsyncd daemon */
- syncdp->link_down = 1;
- if (syncdp->waiting) {
- syncdp->waiting = 0;
- cv_signal(&syncdp->syncd_cv);
- }
- }
- mutex_exit(&syncdp->syncd_mutex);
- } else {
- /* interface up */
- if (ip->if_down && ip->isprimary) {
- rdc_if_up(ip);
- ip->if_down = 0;
- }
-
- syncdp = rdc_lookup_host(ip->srv->ri_hostname);
- mutex_enter(&syncdp->syncd_mutex);
- if (syncdp->link_down) {
- /* Link has come back up */
- syncdp->link_down = 0;
- }
- mutex_exit(&syncdp->syncd_mutex);
- }
-}
diff --git a/usr/src/uts/common/avs/ns/rdc/rdc_io.c b/usr/src/uts/common/avs/ns/rdc/rdc_io.c
deleted file mode 100644
index 89949b0b33..0000000000
--- a/usr/src/uts/common/avs/ns/rdc/rdc_io.c
+++ /dev/null
@@ -1,6718 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/ksynch.h>
-#include <sys/cmn_err.h>
-#include <sys/kmem.h>
-#include <sys/conf.h>
-#include <sys/errno.h>
-#include <sys/sysmacros.h>
-
-#ifdef _SunOS_5_6
-/*
- * on 2.6 both dki_lock.h and rpc/types.h define bool_t so we
- * define enum_t here as it is all we need from rpc/types.h
- * anyway and make it look like we included it. Yuck.
- */
-#define _RPC_TYPES_H
-typedef int enum_t;
-#else
-#ifndef DS_DDICT
-#include <rpc/types.h>
-#endif
-#endif /* _SunOS_5_6 */
-
-#include <sys/ddi.h>
-
-#include <sys/nsc_thread.h>
-#include <sys/nsctl/nsctl.h>
-
-#include <sys/sdt.h> /* dtrace is S10 or later */
-
-#include "rdc_io.h"
-#include "rdc_bitmap.h"
-#include "rdc_update.h"
-#include "rdc_ioctl.h"
-#include "rdcsrv.h"
-#include "rdc_diskq.h"
-
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_k.h>
-#include <sys/unistat/spcs_errors.h>
-
-volatile int net_exit;
-nsc_size_t MAX_RDC_FBAS;
-
-#ifdef DEBUG
-int RDC_MAX_SYNC_THREADS = 8;
-int rdc_maxthreads_last = 8;
-#endif
-
-kmutex_t rdc_ping_lock; /* Ping lock */
-static kmutex_t net_blk_lock;
-
-/*
- * rdc_conf_lock is used as a global device configuration lock.
- * It is also used by enable/resume and disable/suspend code to ensure that
- * the transition of an rdc set between configured and unconfigured is
- * atomic.
- *
- * krdc->group->lock is used to protect state changes of a configured rdc
- * set (e.g. changes to urdc->flags), such as enabled to disabled and vice
- * versa.
- *
- * rdc_many_lock is also used to protect changes in group membership. A group
- * linked list cannot change while this lock is held. The many list and the
- * multi-hop list are both protected by rdc_many_lock.
- */
-kmutex_t rdc_conf_lock;
-kmutex_t rdc_many_lock; /* Many/multi-list lock */
-
-static kmutex_t rdc_net_hnd_id_lock; /* Network handle id lock */
-int rdc_debug = 0;
-int rdc_debug_sleep = 0;
-
-static int rdc_net_hnd_id = 1;
-
-extern kmutex_t rdc_clnt_lock;
-
-static void rdc_ditemsfree(rdc_net_dataset_t *);
-void rdc_clnt_destroy(void);
-
-rdc_k_info_t *rdc_k_info;
-rdc_u_info_t *rdc_u_info;
-
-unsigned long rdc_async_timeout;
-
-nsc_size_t rdc_maxthres_queue = RDC_MAXTHRES_QUEUE;
-int rdc_max_qitems = RDC_MAX_QITEMS;
-int rdc_asyncthr = RDC_ASYNCTHR;
-static nsc_svc_t *rdc_volume_update;
-static int rdc_prealloc_handle = 1;
-
-extern int _rdc_rsrv_diskq(rdc_group_t *group);
-extern void _rdc_rlse_diskq(rdc_group_t *group);
-
-/*
- * Forward declare all statics that are used before defined
- * to enforce parameter checking
- *
- * Some (if not all) of these could be removed if the code were reordered
- */
-
-static void rdc_volume_update_svc(intptr_t);
-static void halt_sync(rdc_k_info_t *krdc);
-void rdc_kstat_create(int index);
-void rdc_kstat_delete(int index);
-static int rdc_checkforbitmap(int, nsc_off_t);
-static int rdc_installbitmap(int, void *, int, nsc_off_t, int, int *, int);
-static rdc_group_t *rdc_newgroup();
-
-int rdc_enable_diskq(rdc_k_info_t *krdc);
-void rdc_close_diskq(rdc_group_t *group);
-int rdc_suspend_diskq(rdc_k_info_t *krdc);
-int rdc_resume_diskq(rdc_k_info_t *krdc);
-void rdc_init_diskq_header(rdc_group_t *grp, dqheader *header);
-void rdc_fail_diskq(rdc_k_info_t *krdc, int wait, int dolog);
-void rdc_unfail_diskq(rdc_k_info_t *krdc);
-void rdc_unintercept_diskq(rdc_group_t *grp);
-int rdc_stamp_diskq(rdc_k_info_t *krdc, int rsrvd, int flags);
-void rdc_qfiller_thr(rdc_k_info_t *krdc);
-
-nstset_t *_rdc_ioset;
-nstset_t *_rdc_flset;
-
-/*
- * RDC threadset tunables
- */
-int rdc_threads = 64; /* default number of threads */
-int rdc_threads_inc = 8; /* increment for changing the size of the set */
-
-/*
- * Private threadset manipulation variables
- */
-static int rdc_threads_hysteresis = 2;
- /* hysteresis for threadset resizing */
-static int rdc_sets_active; /* number of sets currently enabled */
-
-#ifdef DEBUG
-kmutex_t rdc_cntlock;
-#endif
-
-/*
- * rdc_thread_deconfigure - rdc is being deconfigured, stop any
- * thread activity.
- *
- * Inherently single-threaded by the Solaris module unloading code.
- */
-static void
-rdc_thread_deconfigure(void)
-{
- nst_destroy(_rdc_ioset);
- _rdc_ioset = NULL;
-
- nst_destroy(_rdc_flset);
- _rdc_flset = NULL;
-
- nst_destroy(sync_info.rdc_syncset);
- sync_info.rdc_syncset = NULL;
-}
-
-/*
- * rdc_thread_configure - rdc is being configured, initialize the
- * threads we need for flushing aync volumes.
- *
- * Must be called with rdc_conf_lock held.
- */
-static int
-rdc_thread_configure(void)
-{
- ASSERT(MUTEX_HELD(&rdc_conf_lock));
-
- if ((_rdc_ioset = nst_init("rdc_thr", rdc_threads)) == NULL)
- return (EINVAL);
-
- if ((_rdc_flset = nst_init("rdc_flushthr", 2)) == NULL)
- return (EINVAL);
-
- if ((sync_info.rdc_syncset =
- nst_init("rdc_syncthr", RDC_MAX_SYNC_THREADS)) == NULL)
- return (EINVAL);
-
- return (0);
-}
-
-
-/*
- * rdc_thread_tune - called to tune the size of the rdc threadset.
- *
- * Called from the config code when an rdc_set has been enabled or disabled.
- * 'sets' is the increment to the number of active rdc_sets.
- *
- * Must be called with rdc_conf_lock held.
- */
-static void
-rdc_thread_tune(int sets)
-{
- int incr = (sets > 0) ? 1 : -1;
- int change = 0;
- int nthreads;
-
- ASSERT(MUTEX_HELD(&rdc_conf_lock));
-
- if (sets < 0)
- sets = -sets;
-
- while (sets--) {
- nthreads = nst_nthread(_rdc_ioset);
- rdc_sets_active += incr;
-
- if (rdc_sets_active >= nthreads)
- change += nst_add_thread(_rdc_ioset, rdc_threads_inc);
- else if ((rdc_sets_active <
- (nthreads - (rdc_threads_inc + rdc_threads_hysteresis))) &&
- ((nthreads - rdc_threads_inc) >= rdc_threads))
- change -= nst_del_thread(_rdc_ioset, rdc_threads_inc);
- }
-
-#ifdef DEBUG
- if (change) {
- cmn_err(CE_NOTE, "!rdc_thread_tune: "
- "nsets %d, nthreads %d, nthreads change %d",
- rdc_sets_active, nst_nthread(_rdc_ioset), change);
- }
-#endif
-}
-
-
-/*
- * _rdc_unload() - cache is being unloaded,
- * deallocate any dual copy structures allocated during cache
- * loading.
- */
-void
-_rdc_unload(void)
-{
- int i;
- rdc_k_info_t *krdc;
-
- if (rdc_volume_update) {
- (void) nsc_unregister_svc(rdc_volume_update);
- rdc_volume_update = NULL;
- }
-
- rdc_thread_deconfigure();
-
- if (rdc_k_info != NULL) {
- for (i = 0; i < rdc_max_sets; i++) {
- krdc = &rdc_k_info[i];
- mutex_destroy(&krdc->dc_sleep);
- mutex_destroy(&krdc->bmapmutex);
- mutex_destroy(&krdc->kstat_mutex);
- mutex_destroy(&krdc->bmp_kstat_mutex);
- mutex_destroy(&krdc->syncbitmutex);
- cv_destroy(&krdc->busycv);
- cv_destroy(&krdc->closingcv);
- cv_destroy(&krdc->haltcv);
- cv_destroy(&krdc->synccv);
- }
- }
-
- mutex_destroy(&sync_info.lock);
- mutex_destroy(&rdc_ping_lock);
- mutex_destroy(&net_blk_lock);
- mutex_destroy(&rdc_conf_lock);
- mutex_destroy(&rdc_many_lock);
- mutex_destroy(&rdc_net_hnd_id_lock);
- mutex_destroy(&rdc_clnt_lock);
-#ifdef DEBUG
- mutex_destroy(&rdc_cntlock);
-#endif
- net_exit = ATM_EXIT;
-
- if (rdc_k_info != NULL)
- kmem_free(rdc_k_info, sizeof (*rdc_k_info) * rdc_max_sets);
- if (rdc_u_info != NULL)
- kmem_free(rdc_u_info, sizeof (*rdc_u_info) * rdc_max_sets);
- rdc_k_info = NULL;
- rdc_u_info = NULL;
- rdc_max_sets = 0;
-}
-
-
-/*
- * _rdc_load() - rdc is being loaded, Allocate anything
- * that will be needed while the cache is loaded but doesn't really
- * depend on configuration parameters.
- *
- */
-int
-_rdc_load(void)
-{
- int i;
- rdc_k_info_t *krdc;
-
- mutex_init(&rdc_ping_lock, NULL, MUTEX_DRIVER, NULL);
- mutex_init(&net_blk_lock, NULL, MUTEX_DRIVER, NULL);
- mutex_init(&rdc_conf_lock, NULL, MUTEX_DRIVER, NULL);
- mutex_init(&rdc_many_lock, NULL, MUTEX_DRIVER, NULL);
- mutex_init(&rdc_net_hnd_id_lock, NULL, MUTEX_DRIVER, NULL);
- mutex_init(&rdc_clnt_lock, NULL, MUTEX_DRIVER, NULL);
- mutex_init(&sync_info.lock, NULL, MUTEX_DRIVER, NULL);
-
-#ifdef DEBUG
- mutex_init(&rdc_cntlock, NULL, MUTEX_DRIVER, NULL);
-#endif
-
- if ((i = nsc_max_devices()) < rdc_max_sets)
- rdc_max_sets = i;
- /* following case for partial installs that may fail */
- if (!rdc_max_sets)
- rdc_max_sets = 1024;
-
- rdc_k_info = kmem_zalloc(sizeof (*rdc_k_info) * rdc_max_sets, KM_SLEEP);
- if (!rdc_k_info)
- return (ENOMEM);
-
- rdc_u_info = kmem_zalloc(sizeof (*rdc_u_info) * rdc_max_sets, KM_SLEEP);
- if (!rdc_u_info) {
- kmem_free(rdc_k_info, sizeof (*rdc_k_info) * rdc_max_sets);
- return (ENOMEM);
- }
-
- net_exit = ATM_NONE;
- for (i = 0; i < rdc_max_sets; i++) {
- krdc = &rdc_k_info[i];
- bzero(krdc, sizeof (*krdc));
- krdc->index = i;
- mutex_init(&krdc->dc_sleep, NULL, MUTEX_DRIVER, NULL);
- mutex_init(&krdc->bmapmutex, NULL, MUTEX_DRIVER, NULL);
- mutex_init(&krdc->kstat_mutex, NULL, MUTEX_DRIVER, NULL);
- mutex_init(&krdc->bmp_kstat_mutex, NULL, MUTEX_DRIVER, NULL);
- mutex_init(&krdc->syncbitmutex, NULL, MUTEX_DRIVER, NULL);
- cv_init(&krdc->busycv, NULL, CV_DRIVER, NULL);
- cv_init(&krdc->closingcv, NULL, CV_DRIVER, NULL);
- cv_init(&krdc->haltcv, NULL, CV_DRIVER, NULL);
- cv_init(&krdc->synccv, NULL, CV_DRIVER, NULL);
- }
-
- rdc_volume_update = nsc_register_svc("RDCVolumeUpdated",
- rdc_volume_update_svc);
-
- return (0);
-}
-
-static void
-rdc_u_init(rdc_u_info_t *urdc)
-{
- const int index = (int)(urdc - &rdc_u_info[0]);
-
- if (urdc->secondary.addr.maxlen)
- free_rdc_netbuf(&urdc->secondary.addr);
- if (urdc->primary.addr.maxlen)
- free_rdc_netbuf(&urdc->primary.addr);
-
- bzero(urdc, sizeof (rdc_u_info_t));
-
- urdc->index = index;
- urdc->maxqfbas = rdc_maxthres_queue;
- urdc->maxqitems = rdc_max_qitems;
- urdc->asyncthr = rdc_asyncthr;
-}
-
-/*
- * _rdc_configure() - cache is being configured.
- *
- * Initialize dual copy structures
- */
-int
-_rdc_configure(void)
-{
- int index;
- rdc_k_info_t *krdc;
-
- for (index = 0; index < rdc_max_sets; index++) {
- krdc = &rdc_k_info[index];
-
- krdc->remote_index = -1;
- krdc->dcio_bitmap = NULL;
- krdc->bitmap_ref = NULL;
- krdc->bitmap_size = 0;
- krdc->bitmap_write = 0;
- krdc->disk_status = 0;
- krdc->many_next = krdc;
-
- rdc_u_init(&rdc_u_info[index]);
- }
-
- rdc_async_timeout = 120 * HZ; /* Seconds * HZ */
- MAX_RDC_FBAS = FBA_LEN(RDC_MAXDATA);
- if (net_exit != ATM_INIT) {
- net_exit = ATM_INIT;
- return (0);
- }
- return (0);
-}
-
-/*
- * _rdc_deconfigure - rdc is being deconfigured, shut down any
- * dual copy operations and return to an unconfigured state.
- */
-void
-_rdc_deconfigure(void)
-{
- rdc_k_info_t *krdc;
- rdc_u_info_t *urdc;
- int index;
-
- for (index = 0; index < rdc_max_sets; index++) {
- krdc = &rdc_k_info[index];
- urdc = &rdc_u_info[index];
-
- krdc->remote_index = -1;
- krdc->dcio_bitmap = NULL;
- krdc->bitmap_ref = NULL;
- krdc->bitmap_size = 0;
- krdc->bitmap_write = 0;
- krdc->disk_status = 0;
- krdc->many_next = krdc;
-
- if (urdc->primary.addr.maxlen)
- free_rdc_netbuf(&(urdc->primary.addr));
-
- if (urdc->secondary.addr.maxlen)
- free_rdc_netbuf(&(urdc->secondary.addr));
-
- bzero(urdc, sizeof (rdc_u_info_t));
- urdc->index = index;
- }
- net_exit = ATM_EXIT;
- rdc_clnt_destroy();
-
-}
-
-
-/*
- * Lock primitives, containing checks that lock ordering isn't broken
- */
-/*ARGSUSED*/
-void
-rdc_many_enter(rdc_k_info_t *krdc)
-{
- ASSERT(!MUTEX_HELD(&krdc->bmapmutex));
-
- mutex_enter(&rdc_many_lock);
-}
-
-/* ARGSUSED */
-void
-rdc_many_exit(rdc_k_info_t *krdc)
-{
- mutex_exit(&rdc_many_lock);
-}
-
-void
-rdc_group_enter(rdc_k_info_t *krdc)
-{
- ASSERT(!MUTEX_HELD(&rdc_many_lock));
- ASSERT(!MUTEX_HELD(&rdc_conf_lock));
- ASSERT(!MUTEX_HELD(&krdc->bmapmutex));
-
- mutex_enter(&krdc->group->lock);
-}
-
-void
-rdc_group_exit(rdc_k_info_t *krdc)
-{
- mutex_exit(&krdc->group->lock);
-}
-
-/*
- * Suspend and disable operations use this function to wait until it is safe
- * to do continue, without trashing data structures used by other ioctls.
- */
-static void
-wait_busy(rdc_k_info_t *krdc)
-{
- ASSERT(MUTEX_HELD(&rdc_conf_lock));
-
- while (krdc->busy_count > 0)
- cv_wait(&krdc->busycv, &rdc_conf_lock);
-}
-
-
-/*
- * Other ioctls use this function to hold off disable and suspend.
- */
-void
-set_busy(rdc_k_info_t *krdc)
-{
- ASSERT(MUTEX_HELD(&rdc_conf_lock));
-
- wait_busy(krdc);
-
- krdc->busy_count++;
-}
-
-
-/*
- * Other ioctls use this function to allow disable and suspend to continue.
- */
-void
-wakeup_busy(rdc_k_info_t *krdc)
-{
- ASSERT(MUTEX_HELD(&rdc_conf_lock));
-
- if (krdc->busy_count <= 0)
- return;
-
- krdc->busy_count--;
- cv_broadcast(&krdc->busycv);
-}
-
-
-/*
- * Remove the rdc set from its group, and destroy the group if no longer in
- * use.
- */
-static void
-remove_from_group(rdc_k_info_t *krdc)
-{
- rdc_k_info_t *p;
- rdc_group_t *group;
-
- ASSERT(MUTEX_HELD(&rdc_conf_lock));
-
- rdc_many_enter(krdc);
- group = krdc->group;
-
- group->count--;
-
- /*
- * lock queue while looking at thrnum
- */
- mutex_enter(&group->ra_queue.net_qlock);
- if ((group->rdc_thrnum == 0) && (group->count == 0)) {
-
- /*
- * Assure the we've stopped and the flusher thread has not
- * fallen back to sleep
- */
- if (krdc->group->ra_queue.qfill_sleeping != RDC_QFILL_DEAD) {
- group->ra_queue.qfflags |= RDC_QFILLSTOP;
- while (krdc->group->ra_queue.qfflags & RDC_QFILLSTOP) {
- if (krdc->group->ra_queue.qfill_sleeping ==
- RDC_QFILL_ASLEEP)
- cv_broadcast(&group->ra_queue.qfcv);
- mutex_exit(&group->ra_queue.net_qlock);
- delay(2);
- mutex_enter(&group->ra_queue.net_qlock);
- }
- }
- mutex_exit(&group->ra_queue.net_qlock);
-
- mutex_enter(&group->diskqmutex);
- rdc_close_diskq(group);
- mutex_exit(&group->diskqmutex);
- rdc_delgroup(group);
- rdc_many_exit(krdc);
- krdc->group = NULL;
- return;
- }
- mutex_exit(&group->ra_queue.net_qlock);
- /*
- * Always clear the group field.
- * no, you need it set in rdc_flush_memq().
- * to call rdc_group_log()
- * krdc->group = NULL;
- */
-
- /* Take this rdc structure off the group list */
-
- for (p = krdc->group_next; p->group_next != krdc; p = p->group_next)
- ;
- p->group_next = krdc->group_next;
-
- rdc_many_exit(krdc);
-}
-
-
-/*
- * Add the rdc set to its group, setting up a new group if it's the first one.
- */
-static int
-add_to_group(rdc_k_info_t *krdc, int options, int cmd)
-{
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- rdc_u_info_t *utmp;
- rdc_k_info_t *ktmp;
- int index;
- rdc_group_t *group;
- int rc = 0;
- nsthread_t *trc;
-
- ASSERT(MUTEX_HELD(&rdc_conf_lock));
-
- /*
- * Look for matching group name, primary host name and secondary
- * host name.
- */
-
- rdc_many_enter(krdc);
- for (index = 0; index < rdc_max_sets; index++) {
- utmp = &rdc_u_info[index];
- ktmp = &rdc_k_info[index];
-
- if (urdc->group_name[0] == 0)
- break;
-
- if (!IS_CONFIGURED(ktmp))
- continue;
-
- if (strncmp(utmp->group_name, urdc->group_name,
- NSC_MAXPATH) != 0)
- continue;
- if (strncmp(utmp->primary.intf, urdc->primary.intf,
- MAX_RDC_HOST_SIZE) != 0) {
- /* Same group name, different primary interface */
- rdc_many_exit(krdc);
- return (-1);
- }
- if (strncmp(utmp->secondary.intf, urdc->secondary.intf,
- MAX_RDC_HOST_SIZE) != 0) {
- /* Same group name, different secondary interface */
- rdc_many_exit(krdc);
- return (-1);
- }
-
- /* Group already exists, so add this set to the group */
-
- if (((options & RDC_OPT_ASYNC) == 0) &&
- ((ktmp->type_flag & RDC_ASYNCMODE) != 0)) {
- /* Must be same mode as existing group members */
- rdc_many_exit(krdc);
- return (-1);
- }
- if (((options & RDC_OPT_ASYNC) != 0) &&
- ((ktmp->type_flag & RDC_ASYNCMODE) == 0)) {
- /* Must be same mode as existing group members */
- rdc_many_exit(krdc);
- return (-1);
- }
-
- /* cannont reconfigure existing group into new queue this way */
- if ((cmd != RDC_CMD_RESUME) &&
- !RDC_IS_DISKQ(ktmp->group) && urdc->disk_queue[0] != '\0') {
- rdc_many_exit(krdc);
- return (RDC_EQNOADD);
- }
-
- ktmp->group->count++;
- krdc->group = ktmp->group;
- krdc->group_next = ktmp->group_next;
- ktmp->group_next = krdc;
-
- urdc->autosync = utmp->autosync; /* Same as rest */
-
- (void) strncpy(urdc->disk_queue, utmp->disk_queue, NSC_MAXPATH);
-
- rdc_many_exit(krdc);
- return (0);
- }
-
- /* This must be a new group */
- group = rdc_newgroup();
- krdc->group = group;
- krdc->group_next = krdc;
- urdc->autosync = -1; /* Unknown */
-
- /*
- * Tune the thread set by one for each thread created
- */
- rdc_thread_tune(1);
-
- trc = nst_create(_rdc_ioset, rdc_qfiller_thr, (void *)krdc, NST_SLEEP);
- if (trc == NULL) {
- rc = -1;
- cmn_err(CE_NOTE, "!unable to create queue filler daemon");
- goto fail;
- }
-
- if (urdc->disk_queue[0] == '\0') {
- krdc->group->flags |= RDC_MEMQUE;
- } else {
- krdc->group->flags |= RDC_DISKQUE;
-
- /* XXX check here for resume or enable and act accordingly */
-
- if (cmd == RDC_CMD_RESUME) {
- rc = rdc_resume_diskq(krdc);
-
- } else if (cmd == RDC_CMD_ENABLE) {
- rc = rdc_enable_diskq(krdc);
- if ((rc == RDC_EQNOADD) && (cmd != RDC_CMD_ENABLE)) {
- cmn_err(CE_WARN, "!disk queue %s enable failed,"
- " enabling memory queue",
- urdc->disk_queue);
- krdc->group->flags &= ~RDC_DISKQUE;
- krdc->group->flags |= RDC_MEMQUE;
- bzero(urdc->disk_queue, NSC_MAXPATH);
- }
- }
- }
-fail:
- rdc_many_exit(krdc);
- return (rc);
-}
-
-
-/*
- * Move the set to a new group if possible
- */
-static int
-change_group(rdc_k_info_t *krdc, int options)
-{
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- rdc_u_info_t *utmp;
- rdc_k_info_t *ktmp;
- rdc_k_info_t *next;
- char tmpq[NSC_MAXPATH];
- int index;
- int rc = -1;
- rdc_group_t *group, *old_group;
- nsthread_t *trc;
-
- ASSERT(MUTEX_HELD(&rdc_conf_lock));
-
- /*
- * Look for matching group name, primary host name and secondary
- * host name.
- */
-
- bzero(&tmpq, sizeof (tmpq));
- rdc_many_enter(krdc);
-
- old_group = krdc->group;
- next = krdc->group_next;
-
- if (RDC_IS_DISKQ(old_group)) { /* can't keep your own queue */
- (void) strncpy(tmpq, urdc->disk_queue, NSC_MAXPATH);
- bzero(urdc->disk_queue, sizeof (urdc->disk_queue));
- }
- for (index = 0; index < rdc_max_sets; index++) {
- utmp = &rdc_u_info[index];
- ktmp = &rdc_k_info[index];
-
- if (ktmp == krdc)
- continue;
-
- if (urdc->group_name[0] == 0)
- break;
-
- if (!IS_CONFIGURED(ktmp))
- continue;
-
- if (strncmp(utmp->group_name, urdc->group_name,
- NSC_MAXPATH) != 0)
- continue;
- if (strncmp(utmp->primary.intf, urdc->primary.intf,
- MAX_RDC_HOST_SIZE) != 0)
- goto bad;
- if (strncmp(utmp->secondary.intf, urdc->secondary.intf,
- MAX_RDC_HOST_SIZE) != 0)
- goto bad;
-
- /* Group already exists, so add this set to the group */
-
- if (((options & RDC_OPT_ASYNC) == 0) &&
- ((ktmp->type_flag & RDC_ASYNCMODE) != 0)) {
- /* Must be same mode as existing group members */
- goto bad;
- }
- if (((options & RDC_OPT_ASYNC) != 0) &&
- ((ktmp->type_flag & RDC_ASYNCMODE) == 0)) {
- /* Must be same mode as existing group members */
- goto bad;
- }
-
- ktmp->group->count++;
- krdc->group = ktmp->group;
- krdc->group_next = ktmp->group_next;
- ktmp->group_next = krdc;
- bzero(urdc->disk_queue, sizeof (urdc->disk_queue));
- (void) strncpy(urdc->disk_queue, utmp->disk_queue, NSC_MAXPATH);
-
- goto good;
- }
-
- /* This must be a new group */
- group = rdc_newgroup();
- krdc->group = group;
- krdc->group_next = krdc;
-
- trc = nst_create(_rdc_ioset, rdc_qfiller_thr, (void *)krdc, NST_SLEEP);
- if (trc == NULL) {
- rc = -1;
- cmn_err(CE_NOTE, "!unable to create queue filler daemon");
- goto bad;
- }
-
- if (urdc->disk_queue[0] == 0) {
- krdc->group->flags |= RDC_MEMQUE;
- } else {
- krdc->group->flags |= RDC_DISKQUE;
- if ((rc = rdc_enable_diskq(krdc)) < 0)
- goto bad;
- }
-good:
- if (options & RDC_OPT_ASYNC) {
- krdc->type_flag |= RDC_ASYNCMODE;
- rdc_set_flags(urdc, RDC_ASYNC);
- } else {
- krdc->type_flag &= ~RDC_ASYNCMODE;
- rdc_clr_flags(urdc, RDC_ASYNC);
- }
-
- old_group->count--;
- if (!old_group->rdc_writer && old_group->count == 0) {
- /* Group now empty, so destroy */
- if (RDC_IS_DISKQ(old_group)) {
- rdc_unintercept_diskq(old_group);
- mutex_enter(&old_group->diskqmutex);
- rdc_close_diskq(old_group);
- mutex_exit(&old_group->diskqmutex);
- }
-
- mutex_enter(&old_group->ra_queue.net_qlock);
-
- /*
- * Assure the we've stopped and the flusher thread has not
- * fallen back to sleep
- */
- if (old_group->ra_queue.qfill_sleeping != RDC_QFILL_DEAD) {
- old_group->ra_queue.qfflags |= RDC_QFILLSTOP;
- while (old_group->ra_queue.qfflags & RDC_QFILLSTOP) {
- if (old_group->ra_queue.qfill_sleeping ==
- RDC_QFILL_ASLEEP)
- cv_broadcast(&old_group->ra_queue.qfcv);
- mutex_exit(&old_group->ra_queue.net_qlock);
- delay(2);
- mutex_enter(&old_group->ra_queue.net_qlock);
- }
- }
- mutex_exit(&old_group->ra_queue.net_qlock);
-
- rdc_delgroup(old_group);
- rdc_many_exit(krdc);
- return (0);
- }
-
- /* Take this rdc structure off the old group list */
-
- for (ktmp = next; ktmp->group_next != krdc; ktmp = ktmp->group_next)
- ;
- ktmp->group_next = next;
-
- rdc_many_exit(krdc);
- return (0);
-
-bad:
- /* Leave existing group status alone */
- (void) strncpy(urdc->disk_queue, tmpq, NSC_MAXPATH);
- rdc_many_exit(krdc);
- return (rc);
-}
-
-
-/*
- * Set flags for an rdc set, setting the group flags as necessary.
- */
-void
-rdc_set_flags(rdc_u_info_t *urdc, int flags)
-{
- rdc_k_info_t *krdc = &rdc_k_info[urdc->index];
- int vflags, sflags, bflags, ssflags;
-
- DTRACE_PROBE2(rdc_set_flags, int, krdc->index, int, flags);
- vflags = flags & RDC_VFLAGS;
- sflags = flags & RDC_SFLAGS;
- bflags = flags & RDC_BFLAGS;
- ssflags = flags & RDC_SYNC_STATE_FLAGS;
-
- if (vflags) {
- /* normal volume flags */
- ASSERT(MUTEX_HELD(&rdc_conf_lock) ||
- MUTEX_HELD(&krdc->group->lock));
- if (ssflags)
- mutex_enter(&krdc->bmapmutex);
-
- urdc->flags |= vflags;
-
- if (ssflags)
- mutex_exit(&krdc->bmapmutex);
- }
-
- if (sflags) {
- /* Sync state flags that are protected by a different lock */
- ASSERT(MUTEX_HELD(&rdc_many_lock));
- urdc->sync_flags |= sflags;
- }
-
- if (bflags) {
- /* Bmap state flags that are protected by a different lock */
- ASSERT(MUTEX_HELD(&krdc->bmapmutex));
- urdc->bmap_flags |= bflags;
- }
-
-}
-
-
-/*
- * Clear flags for an rdc set, clearing the group flags as necessary.
- */
-void
-rdc_clr_flags(rdc_u_info_t *urdc, int flags)
-{
- rdc_k_info_t *krdc = &rdc_k_info[urdc->index];
- int vflags, sflags, bflags;
-
- DTRACE_PROBE2(rdc_clr_flags, int, krdc->index, int, flags);
- vflags = flags & RDC_VFLAGS;
- sflags = flags & RDC_SFLAGS;
- bflags = flags & RDC_BFLAGS;
-
- if (vflags) {
- /* normal volume flags */
- ASSERT(MUTEX_HELD(&rdc_conf_lock) ||
- MUTEX_HELD(&krdc->group->lock));
- urdc->flags &= ~vflags;
-
- }
-
- if (sflags) {
- /* Sync state flags that are protected by a different lock */
- ASSERT(MUTEX_HELD(&rdc_many_lock));
- urdc->sync_flags &= ~sflags;
- }
-
- if (bflags) {
- /* Bmap state flags that are protected by a different lock */
- ASSERT(MUTEX_HELD(&krdc->bmapmutex));
- urdc->bmap_flags &= ~bflags;
- }
-}
-
-
-/*
- * Get the flags for an rdc set.
- */
-int
-rdc_get_vflags(rdc_u_info_t *urdc)
-{
- return (urdc->flags | urdc->sync_flags | urdc->bmap_flags);
-}
-
-
-/*
- * Initialise flags for an rdc set.
- */
-static void
-rdc_init_flags(rdc_u_info_t *urdc)
-{
- urdc->flags = 0;
- urdc->mflags = 0;
- urdc->sync_flags = 0;
- urdc->bmap_flags = 0;
-}
-
-
-/*
- * Set flags for a many group.
- */
-void
-rdc_set_mflags(rdc_u_info_t *urdc, int flags)
-{
- rdc_k_info_t *krdc = &rdc_k_info[urdc->index];
- rdc_k_info_t *this = krdc;
-
- ASSERT(!(flags & ~RDC_MFLAGS));
-
- if (flags == 0)
- return;
-
- ASSERT(MUTEX_HELD(&rdc_many_lock));
-
- rdc_set_flags(urdc, flags); /* set flags on local urdc */
-
- urdc->mflags |= flags;
- for (krdc = krdc->many_next; krdc != this; krdc = krdc->many_next) {
- urdc = &rdc_u_info[krdc->index];
- if (!IS_ENABLED(urdc))
- continue;
- urdc->mflags |= flags;
- }
-}
-
-
-/*
- * Clear flags for a many group.
- */
-void
-rdc_clr_mflags(rdc_u_info_t *urdc, int flags)
-{
- rdc_k_info_t *krdc = &rdc_k_info[urdc->index];
- rdc_k_info_t *this = krdc;
- rdc_u_info_t *utmp;
-
- ASSERT(!(flags & ~RDC_MFLAGS));
-
- if (flags == 0)
- return;
-
- ASSERT(MUTEX_HELD(&rdc_many_lock));
-
- rdc_clr_flags(urdc, flags); /* clear flags on local urdc */
-
- /*
- * We must maintain the mflags based on the set of flags for
- * all the urdc's that are chained up.
- */
-
- /*
- * First look through all the urdc's and remove bits from
- * the 'flags' variable that are in use elsewhere.
- */
-
- for (krdc = krdc->many_next; krdc != this; krdc = krdc->many_next) {
- utmp = &rdc_u_info[krdc->index];
- if (!IS_ENABLED(utmp))
- continue;
- flags &= ~(rdc_get_vflags(utmp) & RDC_MFLAGS);
- if (flags == 0)
- break;
- }
-
- /*
- * Now clear flags as necessary.
- */
-
- if (flags != 0) {
- urdc->mflags &= ~flags;
- for (krdc = krdc->many_next; krdc != this;
- krdc = krdc->many_next) {
- utmp = &rdc_u_info[krdc->index];
- if (!IS_ENABLED(utmp))
- continue;
- utmp->mflags &= ~flags;
- }
- }
-}
-
-
-int
-rdc_get_mflags(rdc_u_info_t *urdc)
-{
- return (urdc->mflags);
-}
-
-
-void
-rdc_set_flags_log(rdc_u_info_t *urdc, int flags, char *why)
-{
- DTRACE_PROBE2(rdc_set_flags_log, int, urdc->index, int, flags);
-
- rdc_set_flags(urdc, flags);
-
- if (why == NULL)
- return;
-
- if (flags & RDC_LOGGING)
- cmn_err(CE_NOTE, "!sndr: %s:%s entered logging mode: %s",
- urdc->secondary.intf, urdc->secondary.file, why);
- if (flags & RDC_VOL_FAILED)
- cmn_err(CE_NOTE, "!sndr: %s:%s volume failed: %s",
- urdc->secondary.intf, urdc->secondary.file, why);
- if (flags & RDC_BMP_FAILED)
- cmn_err(CE_NOTE, "!sndr: %s:%s bitmap failed: %s",
- urdc->secondary.intf, urdc->secondary.file, why);
-}
-/*
- * rdc_lor(source, dest, len)
- * logically OR memory pointed to by source and dest, copying result into dest.
- */
-void
-rdc_lor(const uchar_t *source, uchar_t *dest, int len)
-{
- int i;
-
- if (source == NULL)
- return;
-
- for (i = 0; i < len; i++)
- *dest++ |= *source++;
-}
-
-
-static int
-check_filesize(int index, spcs_s_info_t kstatus)
-{
- uint64_t remote_size;
- char tmp1[16], tmp2[16];
- rdc_u_info_t *urdc = &rdc_u_info[index];
- int status;
-
- status = rdc_net_getsize(index, &remote_size);
- if (status) {
- (void) spcs_s_inttostring(status, tmp1, sizeof (tmp1), 0);
- spcs_s_add(kstatus, RDC_EGETSIZE, urdc->secondary.intf,
- urdc->secondary.file, tmp1);
- (void) rdc_net_state(index, CCIO_ENABLELOG);
- return (RDC_EGETSIZE);
- }
- if (remote_size < (unsigned long long)urdc->volume_size) {
- (void) spcs_s_inttostring(
- urdc->volume_size, tmp1, sizeof (tmp1), 0);
- /*
- * Cheat, and covert to int, until we have
- * spcs_s_unsignedlonginttostring().
- */
- status = (int)remote_size;
- (void) spcs_s_inttostring(status, tmp2, sizeof (tmp2), 0);
- spcs_s_add(kstatus, RDC_ESIZE, urdc->primary.intf,
- urdc->primary.file, tmp1, urdc->secondary.intf,
- urdc->secondary.file, tmp2);
- (void) rdc_net_state(index, CCIO_ENABLELOG);
- return (RDC_ESIZE);
- }
- return (0);
-}
-
-
-static void
-rdc_volume_update_svc(intptr_t arg)
-{
- rdc_update_t *update = (rdc_update_t *)arg;
- rdc_k_info_t *krdc;
- rdc_k_info_t *this;
- rdc_u_info_t *urdc;
- struct net_bdata6 bd;
- int index;
- int rc;
-
-#ifdef DEBUG_IIUPDATE
- cmn_err(CE_NOTE, "!SNDR received update request for %s",
- update->volume);
-#endif
-
- if ((update->protocol != RDC_SVC_ONRETURN) &&
- (update->protocol != RDC_SVC_VOL_ENABLED)) {
- /* don't understand what the client intends to do */
- update->denied = 1;
- spcs_s_add(update->status, RDC_EVERSION);
- return;
- }
-
- index = rdc_lookup_enabled(update->volume, 0);
- if (index < 0)
- return;
-
- /*
- * warn II that this volume is in use by sndr so
- * II can validate the sizes of the master vs shadow
- * and avoid trouble later down the line with
- * size mis-matches between urdc->volume_size and
- * what is returned from nsc_partsize() which may
- * be the size of the master when replicating the shadow
- */
- if (update->protocol == RDC_SVC_VOL_ENABLED) {
- if (index >= 0)
- update->denied = 1;
- return;
- }
-
- krdc = &rdc_k_info[index];
- urdc = &rdc_u_info[index];
- this = krdc;
-
- do {
- if (!(rdc_get_vflags(urdc) & RDC_LOGGING)) {
-#ifdef DEBUG_IIUPDATE
- cmn_err(CE_NOTE, "!SNDR refused update request for %s",
- update->volume);
-#endif
- update->denied = 1;
- spcs_s_add(update->status, RDC_EMIRRORUP);
- return;
- }
- /* 1->many - all must be logging */
- if (IS_MANY(krdc) && IS_STATE(urdc, RDC_PRIMARY)) {
- rdc_many_enter(krdc);
- for (krdc = krdc->many_next; krdc != this;
- krdc = krdc->many_next) {
- urdc = &rdc_u_info[krdc->index];
- if (!IS_ENABLED(urdc))
- continue;
- break;
- }
- rdc_many_exit(krdc);
- }
- } while (krdc != this);
-
-#ifdef DEBUG_IIUPDATE
- cmn_err(CE_NOTE, "!SNDR allowed update request for %s", update->volume);
-#endif
- urdc = &rdc_u_info[krdc->index];
- do {
-
- bd.size = min(krdc->bitmap_size, (nsc_size_t)update->size);
- bd.data.data_val = (char *)update->bitmap;
- bd.offset = 0;
- bd.cd = index;
-
- if ((rc = RDC_OR_BITMAP(&bd)) != 0) {
- update->denied = 1;
- spcs_s_add(update->status, rc);
- return;
- }
- urdc = &rdc_u_info[index];
- urdc->bits_set = RDC_COUNT_BITMAP(krdc);
- if (IS_MANY(krdc) && IS_STATE(urdc, RDC_PRIMARY)) {
- rdc_many_enter(krdc);
- for (krdc = krdc->many_next; krdc != this;
- krdc = krdc->many_next) {
- index = krdc->index;
- if (!IS_ENABLED(urdc))
- continue;
- break;
- }
- rdc_many_exit(krdc);
- }
- } while (krdc != this);
-
-
- /* II (or something else) has updated us, so no need for a sync */
- if (rdc_get_vflags(urdc) & (RDC_SYNC_NEEDED | RDC_RSYNC_NEEDED)) {
- rdc_many_enter(krdc);
- rdc_clr_flags(urdc, RDC_SYNC_NEEDED | RDC_RSYNC_NEEDED);
- rdc_many_exit(krdc);
- }
-
- if (krdc->bitmap_write > 0)
- (void) rdc_write_bitmap(krdc);
-}
-
-
-/*
- * rdc_check()
- *
- * Return 0 if the set is configured, enabled and the supplied
- * addressing information matches the in-kernel config, otherwise
- * return 1.
- */
-static int
-rdc_check(rdc_k_info_t *krdc, rdc_set_t *rdc_set)
-{
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
-
- ASSERT(MUTEX_HELD(&krdc->group->lock));
-
- if (!IS_ENABLED(urdc))
- return (1);
-
- if (strncmp(urdc->primary.file, rdc_set->primary.file,
- NSC_MAXPATH) != 0) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!rdc_check: primary file mismatch %s vs %s",
- urdc->primary.file, rdc_set->primary.file);
-#endif
- return (1);
- }
-
- if (rdc_set->primary.addr.len != 0 &&
- bcmp(urdc->primary.addr.buf, rdc_set->primary.addr.buf,
- urdc->primary.addr.len) != 0) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!rdc_check: primary address mismatch for %s",
- urdc->primary.file);
-#endif
- return (1);
- }
-
- if (strncmp(urdc->secondary.file, rdc_set->secondary.file,
- NSC_MAXPATH) != 0) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!rdc_check: secondary file mismatch %s vs %s",
- urdc->secondary.file, rdc_set->secondary.file);
-#endif
- return (1);
- }
-
- if (rdc_set->secondary.addr.len != 0 &&
- bcmp(urdc->secondary.addr.buf, rdc_set->secondary.addr.buf,
- urdc->secondary.addr.len) != 0) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!rdc_check: secondary addr mismatch for %s",
- urdc->secondary.file);
-#endif
- return (1);
- }
-
- return (0);
-}
-
-
-/*
- * Lookup enabled sets for a bitmap match
- */
-
-int
-rdc_lookup_bitmap(char *pathname)
-{
- rdc_u_info_t *urdc;
-#ifdef DEBUG
- rdc_k_info_t *krdc;
-#endif
- int index;
-
- for (index = 0; index < rdc_max_sets; index++) {
- urdc = &rdc_u_info[index];
-#ifdef DEBUG
- krdc = &rdc_k_info[index];
-#endif
- ASSERT(krdc->index == index);
- ASSERT(urdc->index == index);
-
- if (!IS_ENABLED(urdc))
- continue;
-
- if (rdc_get_vflags(urdc) & RDC_PRIMARY) {
- if (strncmp(pathname, urdc->primary.bitmap,
- NSC_MAXPATH) == 0)
- return (index);
- } else {
- if (strncmp(pathname, urdc->secondary.bitmap,
- NSC_MAXPATH) == 0)
- return (index);
- }
- }
-
- return (-1);
-}
-
-
-/*
- * Translate a pathname to index into rdc_k_info[].
- * Returns first match that is enabled.
- */
-
-int
-rdc_lookup_enabled(char *pathname, int allow_disabling)
-{
- rdc_u_info_t *urdc;
- rdc_k_info_t *krdc;
- int index;
-
-restart:
- for (index = 0; index < rdc_max_sets; index++) {
- urdc = &rdc_u_info[index];
- krdc = &rdc_k_info[index];
-
- ASSERT(krdc->index == index);
- ASSERT(urdc->index == index);
-
- if (!IS_ENABLED(urdc))
- continue;
-
- if (allow_disabling == 0 && krdc->type_flag & RDC_UNREGISTER)
- continue;
-
- if (rdc_get_vflags(urdc) & RDC_PRIMARY) {
- if (strncmp(pathname, urdc->primary.file,
- NSC_MAXPATH) == 0)
- return (index);
- } else {
- if (strncmp(pathname, urdc->secondary.file,
- NSC_MAXPATH) == 0)
- return (index);
- }
- }
-
- if (allow_disabling == 0) {
- /* None found, or only a disabling one found, so try again */
- allow_disabling = 1;
- goto restart;
- }
-
- return (-1);
-}
-
-
-/*
- * Translate a pathname to index into rdc_k_info[].
- * Returns first match that is configured.
- *
- * Used by enable & resume code.
- * Must be called with rdc_conf_lock held.
- */
-
-int
-rdc_lookup_configured(char *pathname)
-{
- rdc_u_info_t *urdc;
- rdc_k_info_t *krdc;
- int index;
-
- ASSERT(MUTEX_HELD(&rdc_conf_lock));
-
- for (index = 0; index < rdc_max_sets; index++) {
- urdc = &rdc_u_info[index];
- krdc = &rdc_k_info[index];
-
- ASSERT(krdc->index == index);
- ASSERT(urdc->index == index);
-
- if (!IS_CONFIGURED(krdc))
- continue;
-
- if (rdc_get_vflags(urdc) & RDC_PRIMARY) {
- if (strncmp(pathname, urdc->primary.file,
- NSC_MAXPATH) == 0)
- return (index);
- } else {
- if (strncmp(pathname, urdc->secondary.file,
- NSC_MAXPATH) == 0)
- return (index);
- }
- }
-
- return (-1);
-}
-
-
-/*
- * Looks up a configured set with matching secondary interface:volume
- * to check for illegal many-to-one volume configs. To be used during
- * enable and resume processing.
- *
- * Must be called with rdc_conf_lock held.
- */
-
-static int
-rdc_lookup_many2one(rdc_set_t *rdc_set)
-{
- rdc_u_info_t *urdc;
- rdc_k_info_t *krdc;
- int index;
-
- ASSERT(MUTEX_HELD(&rdc_conf_lock));
-
- for (index = 0; index < rdc_max_sets; index++) {
- urdc = &rdc_u_info[index];
- krdc = &rdc_k_info[index];
-
- if (!IS_CONFIGURED(krdc))
- continue;
-
- if (strncmp(urdc->secondary.file,
- rdc_set->secondary.file, NSC_MAXPATH) != 0)
- continue;
- if (strncmp(urdc->secondary.intf,
- rdc_set->secondary.intf, MAX_RDC_HOST_SIZE) != 0)
- continue;
-
- break;
- }
-
- if (index < rdc_max_sets)
- return (index);
- else
- return (-1);
-}
-
-
-/*
- * Looks up an rdc set to check if it is already configured, to be used from
- * functions called from the config ioctl where the interface names can be
- * used for comparison.
- *
- * Must be called with rdc_conf_lock held.
- */
-
-int
-rdc_lookup_byname(rdc_set_t *rdc_set)
-{
- rdc_u_info_t *urdc;
- rdc_k_info_t *krdc;
- int index;
-
- ASSERT(MUTEX_HELD(&rdc_conf_lock));
-
- for (index = 0; index < rdc_max_sets; index++) {
- urdc = &rdc_u_info[index];
- krdc = &rdc_k_info[index];
-
- ASSERT(krdc->index == index);
- ASSERT(urdc->index == index);
-
- if (!IS_CONFIGURED(krdc))
- continue;
-
- if (strncmp(urdc->primary.file, rdc_set->primary.file,
- NSC_MAXPATH) != 0)
- continue;
- if (strncmp(urdc->primary.intf, rdc_set->primary.intf,
- MAX_RDC_HOST_SIZE) != 0)
- continue;
- if (strncmp(urdc->secondary.file, rdc_set->secondary.file,
- NSC_MAXPATH) != 0)
- continue;
- if (strncmp(urdc->secondary.intf, rdc_set->secondary.intf,
- MAX_RDC_HOST_SIZE) != 0)
- continue;
-
- break;
- }
-
- if (index < rdc_max_sets)
- return (index);
- else
- return (-1);
-}
-
-/*
- * Looks up a secondary hostname and device, to be used from
- * functions called from the config ioctl where the interface names can be
- * used for comparison.
- *
- * Must be called with rdc_conf_lock held.
- */
-
-int
-rdc_lookup_byhostdev(char *intf, char *file)
-{
- rdc_u_info_t *urdc;
- rdc_k_info_t *krdc;
- int index;
-
- ASSERT(MUTEX_HELD(&rdc_conf_lock));
-
- for (index = 0; index < rdc_max_sets; index++) {
- urdc = &rdc_u_info[index];
- krdc = &rdc_k_info[index];
-
- ASSERT(krdc->index == index);
- ASSERT(urdc->index == index);
-
- if (!IS_CONFIGURED(krdc))
- continue;
-
- if (strncmp(urdc->secondary.file, file,
- NSC_MAXPATH) != 0)
- continue;
- if (strncmp(urdc->secondary.intf, intf,
- MAX_RDC_HOST_SIZE) != 0)
- continue;
- break;
- }
-
- if (index < rdc_max_sets)
- return (index);
- else
- return (-1);
-}
-
-
-/*
- * Looks up an rdc set to see if it is currently enabled, to be used on the
- * server so that the interface addresses must be used for comparison, as
- * the interface names may differ from those used on the client.
- *
- */
-
-int
-rdc_lookup_byaddr(rdc_set_t *rdc_set)
-{
- rdc_u_info_t *urdc;
-#ifdef DEBUG
- rdc_k_info_t *krdc;
-#endif
- int index;
-
- for (index = 0; index < rdc_max_sets; index++) {
- urdc = &rdc_u_info[index];
-#ifdef DEBUG
- krdc = &rdc_k_info[index];
-#endif
- ASSERT(krdc->index == index);
- ASSERT(urdc->index == index);
-
- if (!IS_ENABLED(urdc))
- continue;
-
- if (strcmp(urdc->primary.file, rdc_set->primary.file) != 0)
- continue;
-
- if (strcmp(urdc->secondary.file, rdc_set->secondary.file) != 0)
- continue;
-
- if (bcmp(urdc->primary.addr.buf, rdc_set->primary.addr.buf,
- urdc->primary.addr.len) != 0) {
- continue;
- }
-
- if (bcmp(urdc->secondary.addr.buf, rdc_set->secondary.addr.buf,
- urdc->secondary.addr.len) != 0) {
- continue;
- }
-
- break;
- }
-
- if (index < rdc_max_sets)
- return (index);
- else
- return (-1);
-}
-
-
-/*
- * Return index of first multihop or 1-to-many
- * Behavior controlled by setting ismany.
- * ismany TRUE (one-to-many)
- * ismany FALSE (multihops)
- *
- */
-static int
-rdc_lookup_multimany(rdc_k_info_t *krdc, const int ismany)
-{
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- rdc_u_info_t *utmp;
- rdc_k_info_t *ktmp;
- char *pathname;
- int index;
- int role;
-
- ASSERT(MUTEX_HELD(&rdc_conf_lock));
- ASSERT(MUTEX_HELD(&rdc_many_lock));
-
- if (rdc_get_vflags(urdc) & RDC_PRIMARY) {
- /* this host is the primary of the krdc set */
- pathname = urdc->primary.file;
- if (ismany) {
- /*
- * 1-many sets are linked by primary :
- * look for matching primary on this host
- */
- role = RDC_PRIMARY;
- } else {
- /*
- * multihop sets link primary to secondary :
- * look for matching secondary on this host
- */
- role = 0;
- }
- } else {
- /* this host is the secondary of the krdc set */
- pathname = urdc->secondary.file;
- if (ismany) {
- /*
- * 1-many sets are linked by primary, so if
- * this host is the secondary of the set this
- * cannot require 1-many linkage.
- */
- return (-1);
- } else {
- /*
- * multihop sets link primary to secondary :
- * look for matching primary on this host
- */
- role = RDC_PRIMARY;
- }
- }
-
- for (index = 0; index < rdc_max_sets; index++) {
- utmp = &rdc_u_info[index];
- ktmp = &rdc_k_info[index];
-
- if (!IS_CONFIGURED(ktmp)) {
- continue;
- }
-
- if (role == RDC_PRIMARY) {
- /*
- * Find a primary that is this host and is not
- * krdc but shares the same data volume as krdc.
- */
- if ((rdc_get_vflags(utmp) & RDC_PRIMARY) &&
- strncmp(utmp->primary.file, pathname,
- NSC_MAXPATH) == 0 && (krdc != ktmp)) {
- break;
- }
- } else {
- /*
- * Find a secondary that is this host and is not
- * krdc but shares the same data volume as krdc.
- */
- if (!(rdc_get_vflags(utmp) & RDC_PRIMARY) &&
- strncmp(utmp->secondary.file, pathname,
- NSC_MAXPATH) == 0 && (krdc != ktmp)) {
- break;
- }
- }
- }
-
- if (index < rdc_max_sets)
- return (index);
- else
- return (-1);
-}
-
-/*
- * Returns secondary match that is configured.
- *
- * Used by enable & resume code.
- * Must be called with rdc_conf_lock held.
- */
-
-static int
-rdc_lookup_secondary(char *pathname)
-{
- rdc_u_info_t *urdc;
- rdc_k_info_t *krdc;
- int index;
-
- ASSERT(MUTEX_HELD(&rdc_conf_lock));
-
- for (index = 0; index < rdc_max_sets; index++) {
- urdc = &rdc_u_info[index];
- krdc = &rdc_k_info[index];
-
- ASSERT(krdc->index == index);
- ASSERT(urdc->index == index);
-
- if (!IS_CONFIGURED(krdc))
- continue;
-
- if (!IS_STATE(urdc, RDC_PRIMARY)) {
- if (strncmp(pathname, urdc->secondary.file,
- NSC_MAXPATH) == 0)
- return (index);
- }
- }
-
- return (-1);
-}
-
-
-static nsc_fd_t *
-rdc_open_direct(rdc_k_info_t *krdc)
-{
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- int rc;
-
- if (krdc->remote_fd == NULL)
- krdc->remote_fd = nsc_open(urdc->direct_file,
- NSC_RDCHR_ID|NSC_DEVICE|NSC_RDWR, 0, 0, &rc);
- return (krdc->remote_fd);
-}
-
-static void
-rdc_close_direct(rdc_k_info_t *krdc)
-{
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
-
- urdc->direct_file[0] = 0;
- if (krdc->remote_fd) {
- if (nsc_close(krdc->remote_fd) == 0) {
- krdc->remote_fd = NULL;
- }
- }
-}
-
-
-#ifdef DEBUG_MANY
-static void
-print_many(rdc_k_info_t *start)
-{
- rdc_k_info_t *p = start;
- rdc_u_info_t *q = &rdc_u_info[p->index];
-
- do {
- cmn_err(CE_CONT, "!krdc %p, %s %s (many_nxt %p multi_nxt %p)\n",
- p, q->primary.file, q->secondary.file, p->many_next,
- p->multi_next);
- delay(10);
- p = p->many_next;
- q = &rdc_u_info[p->index];
- } while (p && p != start);
-}
-#endif /* DEBUG_MANY */
-
-
-static int
-add_to_multi(rdc_k_info_t *krdc)
-{
- rdc_u_info_t *urdc;
- rdc_k_info_t *ktmp;
- rdc_u_info_t *utmp;
- int mindex;
- int domulti;
-
- urdc = &rdc_u_info[krdc->index];
-
- ASSERT(MUTEX_HELD(&rdc_conf_lock));
- ASSERT(MUTEX_HELD(&rdc_many_lock));
-
- /* Now find companion krdc */
- mindex = rdc_lookup_multimany(krdc, FALSE);
-
-#ifdef DEBUG_MANY
- cmn_err(CE_NOTE,
- "!add_to_multi: lookup_multimany: mindex %d prim %s sec %s",
- mindex, urdc->primary.file, urdc->secondary.file);
-#endif
-
- if (mindex >= 0) {
- ktmp = &rdc_k_info[mindex];
- utmp = &rdc_u_info[mindex];
-
- domulti = 1;
-
- if ((rdc_get_vflags(urdc) & RDC_PRIMARY) &&
- ktmp->multi_next != NULL) {
- /*
- * We are adding a new primary to a many
- * group that is the target of a multihop, just
- * ignore it since we are linked in elsewhere.
- */
- domulti = 0;
- }
-
- if (domulti) {
- if (rdc_get_vflags(urdc) & RDC_PRIMARY) {
- /* Is previous leg using direct file I/O? */
- if (utmp->direct_file[0] != 0) {
- /* It is, so cannot proceed */
- return (-1);
- }
- } else {
- /* Is this leg using direct file I/O? */
- if (urdc->direct_file[0] != 0) {
- /* It is, so cannot proceed */
- return (-1);
- }
- }
- krdc->multi_next = ktmp;
- ktmp->multi_next = krdc;
- }
- } else {
- krdc->multi_next = NULL;
-#ifdef DEBUG_MANY
- cmn_err(CE_NOTE, "!add_to_multi: NULL multi_next index %d",
- krdc->index);
-#endif
- }
-
- return (0);
-}
-
-
-/*
- * Add a new set to the circular list of 1-to-many primaries and chain
- * up any multihop as well.
- */
-static int
-add_to_many(rdc_k_info_t *krdc)
-{
- rdc_k_info_t *okrdc;
- int oindex;
-
- ASSERT(MUTEX_HELD(&rdc_conf_lock));
-
- rdc_many_enter(krdc);
-
- if (add_to_multi(krdc) < 0) {
- rdc_many_exit(krdc);
- return (-1);
- }
-
- oindex = rdc_lookup_multimany(krdc, TRUE);
- if (oindex < 0) {
-#ifdef DEBUG_MANY
- print_many(krdc);
-#endif
- rdc_many_exit(krdc);
- return (0);
- }
-
- okrdc = &rdc_k_info[oindex];
-
-#ifdef DEBUG_MANY
- print_many(okrdc);
-#endif
- krdc->many_next = okrdc->many_next;
- okrdc->many_next = krdc;
-
-#ifdef DEBUG_MANY
- print_many(okrdc);
-#endif
- rdc_many_exit(krdc);
- return (0);
-}
-
-
-/*
- * Remove a set from the circular list of 1-to-many primaries.
- */
-static void
-remove_from_many(rdc_k_info_t *old)
-{
- rdc_u_info_t *uold = &rdc_u_info[old->index];
- rdc_k_info_t *p, *q;
-
- ASSERT(MUTEX_HELD(&rdc_conf_lock));
-
- rdc_many_enter(old);
-
-#ifdef DEBUG_MANY
- cmn_err(CE_NOTE, "!rdc: before remove_from_many");
- print_many(old);
-#endif
-
- if (old->many_next == old) {
- /* remove from multihop */
- if ((q = old->multi_next) != NULL) {
- ASSERT(q->multi_next == old);
- q->multi_next = NULL;
- old->multi_next = NULL;
- }
-
- rdc_many_exit(old);
- return;
- }
-
- /* search */
- for (p = old->many_next; p->many_next != old; p = p->many_next)
- ;
-
- p->many_next = old->many_next;
- old->many_next = old;
-
- if ((q = old->multi_next) != NULL) {
- /*
- * old was part of a multihop, so switch multi pointers
- * to someone remaining on the many chain
- */
- ASSERT(p->multi_next == NULL);
-
- q->multi_next = p;
- p->multi_next = q;
- old->multi_next = NULL;
- }
-
-#ifdef DEBUG_MANY
- if (p == old) {
- cmn_err(CE_NOTE, "!rdc: after remove_from_many empty");
- } else {
- cmn_err(CE_NOTE, "!rdc: after remove_from_many");
- print_many(p);
- }
-#endif
-
- rdc_clr_mflags(&rdc_u_info[p->index],
- (rdc_get_vflags(uold) & RDC_MFLAGS));
-
- rdc_many_exit(old);
-}
-
-
-static int
-_rdc_enable(rdc_set_t *rdc_set, int options, spcs_s_info_t kstatus)
-{
- int index;
- char *rhost;
- struct netbuf *addrp;
- rdc_k_info_t *krdc;
- rdc_u_info_t *urdc;
- rdc_srv_t *svp = NULL;
- char *local_file;
- char *local_bitmap;
- char *diskq;
- int rc;
- nsc_size_t maxfbas;
- rdc_group_t *grp;
-
- if ((rdc_set->primary.intf[0] == 0) ||
- (rdc_set->primary.addr.len == 0) ||
- (rdc_set->primary.file[0] == 0) ||
- (rdc_set->primary.bitmap[0] == 0) ||
- (rdc_set->secondary.intf[0] == 0) ||
- (rdc_set->secondary.addr.len == 0) ||
- (rdc_set->secondary.file[0] == 0) ||
- (rdc_set->secondary.bitmap[0] == 0)) {
- spcs_s_add(kstatus, RDC_EEMPTY);
- return (RDC_EEMPTY);
- }
-
- /* Next check there aren't any enabled rdc sets which match. */
-
- mutex_enter(&rdc_conf_lock);
-
- if (rdc_lookup_byname(rdc_set) >= 0) {
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EENABLED, rdc_set->primary.intf,
- rdc_set->primary.file, rdc_set->secondary.intf,
- rdc_set->secondary.file);
- return (RDC_EENABLED);
- }
-
- if (rdc_lookup_many2one(rdc_set) >= 0) {
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EMANY2ONE, rdc_set->primary.intf,
- rdc_set->primary.file, rdc_set->secondary.intf,
- rdc_set->secondary.file);
- return (RDC_EMANY2ONE);
- }
-
- if (rdc_set->netconfig->knc_proto == NULL) {
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_ENETCONFIG);
- return (RDC_ENETCONFIG);
- }
-
- if (rdc_set->primary.addr.len == 0) {
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_ENETBUF, rdc_set->primary.file);
- return (RDC_ENETBUF);
- }
-
- if (rdc_set->secondary.addr.len == 0) {
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_ENETBUF, rdc_set->secondary.file);
- return (RDC_ENETBUF);
- }
-
- /* Check that the local data volume isn't in use as a bitmap */
- if (options & RDC_OPT_PRIMARY)
- local_file = rdc_set->primary.file;
- else
- local_file = rdc_set->secondary.file;
- if (rdc_lookup_bitmap(local_file) >= 0) {
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EVOLINUSE, local_file);
- return (RDC_EVOLINUSE);
- }
-
- /* check that the secondary data volume isn't in use */
- if (!(options & RDC_OPT_PRIMARY)) {
- local_file = rdc_set->secondary.file;
- if (rdc_lookup_secondary(local_file) >= 0) {
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EVOLINUSE, local_file);
- return (RDC_EVOLINUSE);
- }
- }
-
- /* check that the local data vol is not in use as a diskqueue */
- if (options & RDC_OPT_PRIMARY) {
- if (rdc_lookup_diskq(rdc_set->primary.file) >= 0) {
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus,
- RDC_EVOLINUSE, rdc_set->primary.file);
- return (RDC_EVOLINUSE);
- }
- }
-
- /* Check that the bitmap isn't in use as a data volume */
- if (options & RDC_OPT_PRIMARY)
- local_bitmap = rdc_set->primary.bitmap;
- else
- local_bitmap = rdc_set->secondary.bitmap;
- if (rdc_lookup_configured(local_bitmap) >= 0) {
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EBMPINUSE, local_bitmap);
- return (RDC_EBMPINUSE);
- }
-
- /* Check that the bitmap isn't already in use as a bitmap */
- if (rdc_lookup_bitmap(local_bitmap) >= 0) {
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EBMPINUSE, local_bitmap);
- return (RDC_EBMPINUSE);
- }
-
- /* check that the diskq (if here) is not in use */
- diskq = rdc_set->disk_queue;
- if (diskq[0] && rdc_diskq_inuse(rdc_set, diskq)) {
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EDISKQINUSE, diskq);
- return (RDC_EDISKQINUSE);
- }
-
-
- /* Set urdc->volume_size */
- index = rdc_dev_open(rdc_set, options);
- if (index < 0) {
- mutex_exit(&rdc_conf_lock);
- if (options & RDC_OPT_PRIMARY)
- spcs_s_add(kstatus, RDC_EOPEN, rdc_set->primary.intf,
- rdc_set->primary.file);
- else
- spcs_s_add(kstatus, RDC_EOPEN, rdc_set->secondary.intf,
- rdc_set->secondary.file);
- return (RDC_EOPEN);
- }
-
- urdc = &rdc_u_info[index];
- krdc = &rdc_k_info[index];
-
- /* copy relevant parts of rdc_set to urdc field by field */
-
- (void) strncpy(urdc->primary.intf, rdc_set->primary.intf,
- MAX_RDC_HOST_SIZE);
- (void) strncpy(urdc->secondary.intf, rdc_set->secondary.intf,
- MAX_RDC_HOST_SIZE);
-
- (void) strncpy(urdc->group_name, rdc_set->group_name, NSC_MAXPATH);
- (void) strncpy(urdc->disk_queue, rdc_set->disk_queue, NSC_MAXPATH);
-
- dup_rdc_netbuf(&rdc_set->primary.addr, &urdc->primary.addr);
- (void) strncpy(urdc->primary.file, rdc_set->primary.file, NSC_MAXPATH);
- (void) strncpy(urdc->primary.bitmap, rdc_set->primary.bitmap,
- NSC_MAXPATH);
-
- dup_rdc_netbuf(&rdc_set->secondary.addr, &urdc->secondary.addr);
- (void) strncpy(urdc->secondary.file, rdc_set->secondary.file,
- NSC_MAXPATH);
- (void) strncpy(urdc->secondary.bitmap, rdc_set->secondary.bitmap,
- NSC_MAXPATH);
-
- urdc->setid = rdc_set->setid;
-
- /*
- * before we try to add to group, or create one, check out
- * if we are doing the wrong thing with the diskq
- */
-
- if (urdc->disk_queue[0] && (options & RDC_OPT_SYNC)) {
- mutex_exit(&rdc_conf_lock);
- rdc_dev_close(krdc);
- spcs_s_add(kstatus, RDC_EQWRONGMODE);
- return (RDC_EQWRONGMODE);
- }
-
- if ((rc = add_to_group(krdc, options, RDC_CMD_ENABLE)) != 0) {
- mutex_exit(&rdc_conf_lock);
- rdc_dev_close(krdc);
- if (rc == RDC_EQNOADD) {
- spcs_s_add(kstatus, RDC_EQNOADD, rdc_set->disk_queue);
- return (RDC_EQNOADD);
- } else {
- spcs_s_add(kstatus, RDC_EGROUP,
- rdc_set->primary.intf, rdc_set->primary.file,
- rdc_set->secondary.intf, rdc_set->secondary.file,
- rdc_set->group_name);
- return (RDC_EGROUP);
- }
- }
-
- /*
- * maxfbas was set in rdc_dev_open as primary's maxfbas.
- * If diskq's maxfbas is smaller, then use diskq's.
- */
- grp = krdc->group;
- if (grp && RDC_IS_DISKQ(grp) && (grp->diskqfd != 0)) {
- rc = _rdc_rsrv_diskq(grp);
- if (RDC_SUCCESS(rc)) {
- rc = nsc_maxfbas(grp->diskqfd, 0, &maxfbas);
- if (rc == 0) {
-#ifdef DEBUG
- if (krdc->maxfbas != maxfbas)
- cmn_err(CE_NOTE,
- "!_rdc_enable: diskq maxfbas = %"
- NSC_SZFMT ", primary maxfbas = %"
- NSC_SZFMT, maxfbas, krdc->maxfbas);
-#endif
- krdc->maxfbas = min(krdc->maxfbas, maxfbas);
- } else {
- cmn_err(CE_WARN,
- "!_rdc_enable: diskq maxfbas failed (%d)",
- rc);
- }
- _rdc_rlse_diskq(grp);
- } else {
- cmn_err(CE_WARN,
- "!_rdc_enable: diskq reserve failed (%d)", rc);
- }
- }
-
- rdc_init_flags(urdc);
- (void) strncpy(urdc->direct_file, rdc_set->direct_file, NSC_MAXPATH);
- if ((options & RDC_OPT_PRIMARY) && rdc_set->direct_file[0]) {
- if (rdc_open_direct(krdc) == NULL)
- rdc_set_flags(urdc, RDC_FCAL_FAILED);
- }
-
- krdc->many_next = krdc;
-
- ASSERT(krdc->type_flag == 0);
- krdc->type_flag = RDC_CONFIGURED;
-
- if (options & RDC_OPT_PRIMARY)
- rdc_set_flags(urdc, RDC_PRIMARY);
-
- if (options & RDC_OPT_ASYNC)
- krdc->type_flag |= RDC_ASYNCMODE;
-
- set_busy(krdc);
- urdc->syshostid = rdc_set->syshostid;
-
- if (add_to_many(krdc) < 0) {
- mutex_exit(&rdc_conf_lock);
-
- rdc_group_enter(krdc);
-
- spcs_s_add(kstatus, RDC_EMULTI);
- rc = RDC_EMULTI;
- goto fail;
- }
-
- /* Configured but not enabled */
- ASSERT(IS_CONFIGURED(krdc) && !IS_ENABLED(urdc));
-
- mutex_exit(&rdc_conf_lock);
-
- rdc_group_enter(krdc);
-
- /* Configured but not enabled */
- ASSERT(IS_CONFIGURED(krdc) && !IS_ENABLED(urdc));
-
- /*
- * The rdc set is configured but not yet enabled. Other operations must
- * ignore this set until it is enabled.
- */
-
- urdc->sync_pos = 0;
-
- if (rdc_set->maxqfbas > 0)
- urdc->maxqfbas = rdc_set->maxqfbas;
- else
- urdc->maxqfbas = rdc_maxthres_queue;
-
- if (rdc_set->maxqitems > 0)
- urdc->maxqitems = rdc_set->maxqitems;
- else
- urdc->maxqitems = rdc_max_qitems;
-
- if (rdc_set->asyncthr > 0)
- urdc->asyncthr = rdc_set->asyncthr;
- else
- urdc->asyncthr = rdc_asyncthr;
-
- if (urdc->autosync == -1) {
- /* Still unknown */
- if (rdc_set->autosync > 0)
- urdc->autosync = 1;
- else
- urdc->autosync = 0;
- }
-
- urdc->netconfig = rdc_set->netconfig;
-
- if (options & RDC_OPT_PRIMARY) {
- rhost = rdc_set->secondary.intf;
- addrp = &rdc_set->secondary.addr;
- } else {
- rhost = rdc_set->primary.intf;
- addrp = &rdc_set->primary.addr;
- }
-
- if (options & RDC_OPT_ASYNC)
- rdc_set_flags(urdc, RDC_ASYNC);
-
- svp = rdc_create_svinfo(rhost, addrp, urdc->netconfig);
- if (svp == NULL) {
- spcs_s_add(kstatus, ENOMEM);
- rc = ENOMEM;
- goto fail;
- }
- urdc->netconfig = NULL; /* This will be no good soon */
-
- rdc_kstat_create(index);
-
- /* Don't set krdc->intf here */
-
- if (rdc_enable_bitmap(krdc, options & RDC_OPT_SETBMP) < 0)
- goto bmpfail;
-
- RDC_ZERO_BITREF(krdc);
- if (krdc->lsrv == NULL)
- krdc->lsrv = svp;
- else {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!_rdc_enable: krdc->lsrv already set: %p",
- (void *) krdc->lsrv);
-#endif
- rdc_destroy_svinfo(svp);
- }
- svp = NULL;
-
- /* Configured but not enabled */
- ASSERT(IS_CONFIGURED(krdc) && !IS_ENABLED(urdc));
-
- /* And finally */
-
- krdc->remote_index = -1;
- /* Should we set the whole group logging? */
- rdc_set_flags(urdc, RDC_ENABLED | RDC_LOGGING);
-
- rdc_group_exit(krdc);
-
- if (rdc_intercept(krdc) != 0) {
- rdc_group_enter(krdc);
- rdc_clr_flags(urdc, RDC_ENABLED);
- if (options & RDC_OPT_PRIMARY)
- spcs_s_add(kstatus, RDC_EREGISTER, urdc->primary.file);
- else
- spcs_s_add(kstatus, RDC_EREGISTER,
- urdc->secondary.file);
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!nsc_register_path failed %s",
- urdc->primary.file);
-#endif
- rc = RDC_EREGISTER;
- goto bmpfail;
- }
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!SNDR: enabled %s %s", urdc->primary.file,
- urdc->secondary.file);
-#endif
-
- rdc_write_state(urdc);
-
- mutex_enter(&rdc_conf_lock);
- wakeup_busy(krdc);
- mutex_exit(&rdc_conf_lock);
-
- return (0);
-
-bmpfail:
- if (options & RDC_OPT_PRIMARY)
- spcs_s_add(kstatus, RDC_EBITMAP, rdc_set->primary.bitmap);
- else
- spcs_s_add(kstatus, RDC_EBITMAP, rdc_set->secondary.bitmap);
- rc = RDC_EBITMAP;
- if (rdc_get_vflags(urdc) & RDC_ENABLED) {
- rdc_group_exit(krdc);
- (void) rdc_unintercept(krdc);
- rdc_group_enter(krdc);
- }
-
-fail:
- rdc_kstat_delete(index);
- rdc_group_exit(krdc);
- if (krdc->intf) {
- rdc_if_t *ip = krdc->intf;
- mutex_enter(&rdc_conf_lock);
- krdc->intf = NULL;
- rdc_remove_from_if(ip);
- mutex_exit(&rdc_conf_lock);
- }
- rdc_group_enter(krdc);
- /* Configured but not enabled */
- ASSERT(IS_CONFIGURED(krdc) && !IS_ENABLED(urdc));
-
- rdc_dev_close(krdc);
- rdc_close_direct(krdc);
- rdc_destroy_svinfo(svp);
-
- /* Configured but not enabled */
- ASSERT(IS_CONFIGURED(krdc) && !IS_ENABLED(urdc));
-
- rdc_group_exit(krdc);
-
- mutex_enter(&rdc_conf_lock);
-
- /* Configured but not enabled */
- ASSERT(IS_CONFIGURED(krdc) && !IS_ENABLED(urdc));
-
- remove_from_group(krdc);
-
- if (IS_MANY(krdc) || IS_MULTI(krdc))
- remove_from_many(krdc);
-
- rdc_u_init(urdc);
-
- ASSERT(krdc->type_flag & RDC_CONFIGURED);
- krdc->type_flag = 0;
- wakeup_busy(krdc);
-
- mutex_exit(&rdc_conf_lock);
-
- return (rc);
-}
-
-static int
-rdc_enable(rdc_config_t *uparms, spcs_s_info_t kstatus)
-{
- int rc;
- char itmp[10];
-
- if (!(uparms->options & RDC_OPT_SYNC) &&
- !(uparms->options & RDC_OPT_ASYNC)) {
- rc = RDC_EEINVAL;
- (void) spcs_s_inttostring(
- uparms->options, itmp, sizeof (itmp), 1);
- spcs_s_add(kstatus, RDC_EEINVAL, itmp);
- goto done;
- }
-
- if (!(uparms->options & RDC_OPT_PRIMARY) &&
- !(uparms->options & RDC_OPT_SECONDARY)) {
- rc = RDC_EEINVAL;
- (void) spcs_s_inttostring(
- uparms->options, itmp, sizeof (itmp), 1);
- spcs_s_add(kstatus, RDC_EEINVAL, itmp);
- goto done;
- }
-
- if (!(uparms->options & RDC_OPT_SETBMP) &&
- !(uparms->options & RDC_OPT_CLRBMP)) {
- rc = RDC_EEINVAL;
- (void) spcs_s_inttostring(
- uparms->options, itmp, sizeof (itmp), 1);
- spcs_s_add(kstatus, RDC_EEINVAL, itmp);
- goto done;
- }
-
- rc = _rdc_enable(uparms->rdc_set, uparms->options, kstatus);
-done:
- return (rc);
-}
-
-/* ARGSUSED */
-static int
-_rdc_disable(rdc_k_info_t *krdc, rdc_config_t *uap, spcs_s_info_t kstatus)
-{
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- rdc_if_t *ip;
- int index = krdc->index;
- disk_queue *q;
- rdc_set_t *rdc_set = uap->rdc_set;
-
- ASSERT(krdc->group != NULL);
- rdc_group_enter(krdc);
-#ifdef DEBUG
- ASSERT(rdc_check(krdc, rdc_set) == 0);
-#else
- if (((uap->options & RDC_OPT_FORCE_DISABLE) == 0) &&
- rdc_check(krdc, rdc_set)) {
- rdc_group_exit(krdc);
- spcs_s_add(kstatus, RDC_EALREADY, rdc_set->primary.file,
- rdc_set->secondary.file);
- return (RDC_EALREADY);
- }
-#endif
-
- if (rdc_get_vflags(urdc) & RDC_PRIMARY) {
- halt_sync(krdc);
- ASSERT(IS_ENABLED(urdc));
- }
- q = &krdc->group->diskq;
-
- if (IS_ASYNC(urdc) && RDC_IS_DISKQ(krdc->group) &&
- ((!IS_STATE(urdc, RDC_LOGGING)) && (!QEMPTY(q)))) {
- krdc->type_flag &= ~RDC_DISABLEPEND;
- rdc_group_exit(krdc);
- spcs_s_add(kstatus, RDC_EQNOTEMPTY, urdc->disk_queue);
- return (RDC_EQNOTEMPTY);
- }
- rdc_group_exit(krdc);
- (void) rdc_unintercept(krdc);
-
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!SNDR: disabled %s %s", urdc->primary.file,
- urdc->secondary.file);
-#endif
-
- /* Configured but not enabled */
- ASSERT(IS_CONFIGURED(krdc) && !IS_ENABLED(urdc));
-
- /*
- * No new io can come in through the io provider.
- * Wait for the async flusher to finish.
- */
-
- if (IS_ASYNC(urdc) && !RDC_IS_DISKQ(krdc->group)) {
- int tries = 2; /* in case of hopelessly stuck flusher threads */
-#ifdef DEBUG
- net_queue *qp = &krdc->group->ra_queue;
-#endif
- do {
- if (!krdc->group->rdc_writer)
- (void) rdc_writer(krdc->index);
-
- (void) rdc_drain_queue(krdc->index);
-
- } while (krdc->group->rdc_writer && tries--);
-
- /* ok, force it to happen... */
- if (rdc_drain_queue(krdc->index) != 0) {
- do {
- mutex_enter(&krdc->group->ra_queue.net_qlock);
- krdc->group->asyncdis = 1;
- cv_broadcast(&krdc->group->asyncqcv);
- mutex_exit(&krdc->group->ra_queue.net_qlock);
- cmn_err(CE_WARN,
- "!SNDR: async I/O pending and not flushed "
- "for %s during disable",
- urdc->primary.file);
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!nitems: %" NSC_SZFMT " nblocks: %"
- NSC_SZFMT " head: 0x%p tail: 0x%p",
- qp->nitems, qp->blocks,
- (void *)qp->net_qhead,
- (void *)qp->net_qtail);
-#endif
- } while (krdc->group->rdc_thrnum > 0);
- }
- }
-
- mutex_enter(&rdc_conf_lock);
- ip = krdc->intf;
- krdc->intf = 0;
-
- if (ip) {
- rdc_remove_from_if(ip);
- }
-
- mutex_exit(&rdc_conf_lock);
-
- rdc_group_enter(krdc);
-
- /* Configured but not enabled */
- ASSERT(IS_CONFIGURED(krdc) && !IS_ENABLED(urdc));
-
- /* Must not hold group lock during this function */
- rdc_group_exit(krdc);
- while (rdc_dump_alloc_bufs_cd(krdc->index) == EAGAIN)
- delay(2);
- rdc_group_enter(krdc);
-
- (void) rdc_clear_state(krdc);
-
- rdc_free_bitmap(krdc, RDC_CMD_DISABLE);
- rdc_close_bitmap(krdc);
-
- rdc_dev_close(krdc);
- rdc_close_direct(krdc);
-
- /* Configured but not enabled */
- ASSERT(IS_CONFIGURED(krdc) && !IS_ENABLED(urdc));
-
- rdc_group_exit(krdc);
-
- /*
- * we should now unregister the queue, with no conflicting
- * locks held. This is the last(only) member of the group
- */
- if (krdc->group && RDC_IS_DISKQ(krdc->group) &&
- krdc->group->count == 1) { /* stop protecting queue */
- rdc_unintercept_diskq(krdc->group);
- }
-
- mutex_enter(&rdc_conf_lock);
-
- /* Configured but not enabled */
- ASSERT(IS_CONFIGURED(krdc) && !IS_ENABLED(urdc));
-
- wait_busy(krdc);
-
- if (IS_MANY(krdc) || IS_MULTI(krdc))
- remove_from_many(krdc);
-
- remove_from_group(krdc);
-
- krdc->remote_index = -1;
- ASSERT(krdc->type_flag & RDC_CONFIGURED);
- ASSERT(krdc->type_flag & RDC_DISABLEPEND);
- krdc->type_flag = 0;
-#ifdef DEBUG
- if (krdc->dcio_bitmap)
- cmn_err(CE_WARN, "!_rdc_disable: possible mem leak, "
- "dcio_bitmap");
-#endif
- krdc->dcio_bitmap = NULL;
- krdc->bitmap_ref = NULL;
- krdc->bitmap_size = 0;
- krdc->maxfbas = 0;
- krdc->bitmap_write = 0;
- krdc->disk_status = 0;
- rdc_destroy_svinfo(krdc->lsrv);
- krdc->lsrv = NULL;
- krdc->multi_next = NULL;
-
- rdc_u_init(urdc);
-
- mutex_exit(&rdc_conf_lock);
- rdc_kstat_delete(index);
-
- return (0);
-}
-
-static int
-rdc_disable(rdc_config_t *uparms, spcs_s_info_t kstatus)
-{
- rdc_k_info_t *krdc;
- int index;
- int rc;
-
- mutex_enter(&rdc_conf_lock);
-
- index = rdc_lookup_byname(uparms->rdc_set);
- if (index >= 0)
- krdc = &rdc_k_info[index];
- if (index < 0 || (krdc->type_flag & RDC_DISABLEPEND)) {
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EALREADY, uparms->rdc_set->primary.file,
- uparms->rdc_set->secondary.file);
- return (RDC_EALREADY);
- }
-
- krdc->type_flag |= RDC_DISABLEPEND;
- wait_busy(krdc);
- if (krdc->type_flag == 0) {
- /* A resume or enable failed */
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EALREADY, uparms->rdc_set->primary.file,
- uparms->rdc_set->secondary.file);
- return (RDC_EALREADY);
- }
- mutex_exit(&rdc_conf_lock);
-
- rc = _rdc_disable(krdc, uparms, kstatus);
- return (rc);
-}
-
-
-/*
- * Checks whether the state of one of the other sets in the 1-many or
- * multi-hop config should prevent a sync from starting on this one.
- * Return NULL if no just cause or impediment is found, otherwise return
- * a pointer to the offending set.
- */
-static rdc_u_info_t *
-rdc_allow_pri_sync(rdc_u_info_t *urdc, int options)
-{
- rdc_k_info_t *krdc = &rdc_k_info[urdc->index];
- rdc_k_info_t *ktmp;
- rdc_u_info_t *utmp;
- rdc_k_info_t *kmulti = NULL;
-
- ASSERT(rdc_get_vflags(urdc) & RDC_PRIMARY);
-
- rdc_many_enter(krdc);
-
- /*
- * In the reverse sync case we need to check the previous leg of
- * the multi-hop config. The link to that set can be from any of
- * the 1-many list, so as we go through we keep an eye open for it.
- */
- if ((options & RDC_OPT_REVERSE) && (IS_MULTI(krdc))) {
- /* This set links to the first leg */
- ktmp = krdc->multi_next;
- utmp = &rdc_u_info[ktmp->index];
- if (IS_ENABLED(utmp))
- kmulti = ktmp;
- }
-
- if (IS_MANY(krdc)) {
- for (ktmp = krdc->many_next; ktmp != krdc;
- ktmp = ktmp->many_next) {
- utmp = &rdc_u_info[ktmp->index];
-
- if (!IS_ENABLED(utmp))
- continue;
-
- if (options & RDC_OPT_FORWARD) {
- /*
- * Reverse sync needed is bad, as it means a
- * reverse sync in progress or started and
- * didn't complete, so this primary volume
- * is not consistent. So we shouldn't copy
- * it to its secondary.
- */
- if (rdc_get_mflags(utmp) & RDC_RSYNC_NEEDED) {
- rdc_many_exit(krdc);
- return (utmp);
- }
- } else {
- /* Reverse, so see if we need to spot kmulti */
- if ((kmulti == NULL) && (IS_MULTI(ktmp))) {
- /* This set links to the first leg */
- kmulti = ktmp->multi_next;
- if (!IS_ENABLED(
- &rdc_u_info[kmulti->index]))
- kmulti = NULL;
- }
-
- /*
- * Non-logging is bad, as the bitmap will
- * be updated with the bits for this sync.
- */
- if (!(rdc_get_vflags(utmp) & RDC_LOGGING)) {
- rdc_many_exit(krdc);
- return (utmp);
- }
- }
- }
- }
-
- if (kmulti) {
- utmp = &rdc_u_info[kmulti->index];
- ktmp = kmulti; /* In case we decide we do need to use ktmp */
-
- ASSERT(options & RDC_OPT_REVERSE);
-
- if (IS_REPLICATING(utmp)) {
- /*
- * Replicating is bad as data is already flowing to
- * the target of the requested sync operation.
- */
- rdc_many_exit(krdc);
- return (utmp);
- }
-
- if (rdc_get_vflags(utmp) & RDC_SYNCING) {
- /*
- * Forward sync in progress is bad, as data is
- * already flowing to the target of the requested
- * sync operation.
- * Reverse sync in progress is bad, as the primary
- * has already decided which data to copy.
- */
- rdc_many_exit(krdc);
- return (utmp);
- }
-
- /*
- * Clear the "sync needed" flags, as the multi-hop secondary
- * will be updated via this requested sync operation, so does
- * not need to complete its aborted forward sync.
- */
- if (rdc_get_vflags(utmp) & RDC_SYNC_NEEDED)
- rdc_clr_flags(utmp, RDC_SYNC_NEEDED);
- }
-
- if (IS_MANY(krdc) && (options & RDC_OPT_REVERSE)) {
- for (ktmp = krdc->many_next; ktmp != krdc;
- ktmp = ktmp->many_next) {
- utmp = &rdc_u_info[ktmp->index];
- if (!IS_ENABLED(utmp))
- continue;
-
- /*
- * Clear any "reverse sync needed" flags, as the
- * volume will be updated via this requested
- * sync operation, so does not need to complete
- * its aborted reverse sync.
- */
- if (rdc_get_mflags(utmp) & RDC_RSYNC_NEEDED)
- rdc_clr_mflags(utmp, RDC_RSYNC_NEEDED);
- }
- }
-
- rdc_many_exit(krdc);
-
- return (NULL);
-}
-
-static void
-_rdc_sync_wrthr(void *thrinfo)
-{
- rdc_syncthr_t *syncinfo = (rdc_syncthr_t *)thrinfo;
- nsc_buf_t *handle = NULL;
- rdc_k_info_t *krdc = syncinfo->krdc;
- int rc;
- int tries = 0;
-
- DTRACE_PROBE2(rdc_sync_loop_netwrite_start, int, krdc->index,
- nsc_buf_t *, handle);
-
-retry:
- rc = nsc_alloc_buf(RDC_U_FD(krdc), syncinfo->offset, syncinfo->len,
- NSC_READ | NSC_NOCACHE, &handle);
-
- if (!RDC_SUCCESS(rc) || krdc->remote_index < 0) {
- DTRACE_PROBE(rdc_sync_wrthr_alloc_buf_err);
- goto failed;
- }
-
- rdc_group_enter(krdc);
- if ((krdc->disk_status == 1) || (krdc->dcio_bitmap == NULL)) {
- rdc_group_exit(krdc);
- goto failed;
- }
- rdc_group_exit(krdc);
-
- if ((rc = rdc_net_write(krdc->index, krdc->remote_index, handle,
- handle->sb_pos, handle->sb_len, RDC_NOSEQ, RDC_NOQUE, NULL)) > 0) {
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
-
- /*
- * The following is to handle
- * the case where the secondary side
- * has thrown our buffer handle token away in a
- * attempt to preserve its health on restart
- */
- if ((rc == EPROTO) && (tries < 3)) {
- (void) nsc_free_buf(handle);
- handle = NULL;
- tries++;
- delay(HZ >> 2);
- goto retry;
- }
-
- DTRACE_PROBE(rdc_sync_wrthr_remote_write_err);
- cmn_err(CE_WARN, "!rdc_sync_wrthr: remote write failed (%d) "
- "0x%x", rc, rdc_get_vflags(urdc));
-
- goto failed;
- }
- (void) nsc_free_buf(handle);
- handle = NULL;
-
- return;
-failed:
- (void) nsc_free_buf(handle);
- syncinfo->status->offset = syncinfo->offset;
-}
-
-/*
- * see above comments on _rdc_sync_wrthr
- */
-static void
-_rdc_sync_rdthr(void *thrinfo)
-{
- rdc_syncthr_t *syncinfo = (rdc_syncthr_t *)thrinfo;
- nsc_buf_t *handle = NULL;
- rdc_k_info_t *krdc = syncinfo->krdc;
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- int rc;
-
- rc = nsc_alloc_buf(RDC_U_FD(krdc), syncinfo->offset, syncinfo->len,
- NSC_WRITE | NSC_WRTHRU | NSC_NOCACHE, &handle);
-
- if (!RDC_SUCCESS(rc) || krdc->remote_index < 0) {
- goto failed;
- }
- rdc_group_enter(krdc);
- if ((krdc->disk_status == 1) || (krdc->dcio_bitmap == NULL)) {
- rdc_group_exit(krdc);
- goto failed;
- }
- rdc_group_exit(krdc);
-
- rc = rdc_net_read(krdc->index, krdc->remote_index, handle,
- handle->sb_pos, handle->sb_len);
-
- if (!RDC_SUCCESS(rc)) {
- cmn_err(CE_WARN, "!rdc_sync_rdthr: remote read failed(%d)", rc);
- goto failed;
- }
- if (!IS_STATE(urdc, RDC_FULL))
- rdc_set_bitmap_many(krdc, handle->sb_pos, handle->sb_len);
-
- rc = nsc_write(handle, handle->sb_pos, handle->sb_len, 0);
-
- if (!RDC_SUCCESS(rc)) {
- rdc_many_enter(krdc);
- rdc_set_flags_log(urdc, RDC_VOL_FAILED, "nsc_write failed");
- rdc_many_exit(krdc);
- rdc_write_state(urdc);
- goto failed;
- }
-
- (void) nsc_free_buf(handle);
- handle = NULL;
-
- return;
-failed:
- (void) nsc_free_buf(handle);
- syncinfo->status->offset = syncinfo->offset;
-}
-
-/*
- * _rdc_sync_wrthr
- * sync loop write thread
- * if there are avail threads, we have not
- * used up the pipe, so the sync loop will, if
- * possible use these to multithread the write/read
- */
-void
-_rdc_sync_thread(void *thrinfo)
-{
- rdc_syncthr_t *syncinfo = (rdc_syncthr_t *)thrinfo;
- rdc_k_info_t *krdc = syncinfo->krdc;
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- rdc_thrsync_t *sync = &krdc->syncs;
- uint_t bitmask;
- int rc;
-
- rc = _rdc_rsrv_devs(krdc, RDC_RAW, RDC_INTERNAL);
- if (!RDC_SUCCESS(rc))
- goto failed;
-
- if (IS_STATE(urdc, RDC_SLAVE))
- _rdc_sync_rdthr(thrinfo);
- else
- _rdc_sync_wrthr(thrinfo);
-
- _rdc_rlse_devs(krdc, RDC_RAW);
-
- if (krdc->dcio_bitmap == NULL) {
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!_rdc_sync_wrthr: NULL bitmap");
-#else
- /*EMPTY*/
-#endif
- } else if (syncinfo->status->offset < 0) {
-
- RDC_SET_BITMASK(syncinfo->offset, syncinfo->len, &bitmask);
- RDC_CLR_BITMAP(krdc, syncinfo->offset, syncinfo->len, \
- bitmask, RDC_BIT_FORCE);
- }
-
-failed:
- /*
- * done with this, get rid of it.
- * the status is not freed, it should still be a status chain
- * that _rdc_sync() has the head of
- */
- kmem_free(syncinfo, sizeof (*syncinfo));
-
- /*
- * decrement the global sync thread num
- */
- mutex_enter(&sync_info.lock);
- sync_info.active_thr--;
- /* LINTED */
- RDC_AVAIL_THR_TUNE(sync_info);
- mutex_exit(&sync_info.lock);
-
- /*
- * krdc specific stuff
- */
- mutex_enter(&sync->lock);
- sync->complete++;
- cv_broadcast(&sync->cv);
- mutex_exit(&sync->lock);
-}
-
-int
-_rdc_setup_syncthr(rdc_syncthr_t **synthr, nsc_off_t offset,
- nsc_size_t len, rdc_k_info_t *krdc, sync_status_t *stats)
-{
- rdc_syncthr_t *tmp;
- /* alloc here, free in the sync thread */
- tmp =
- (rdc_syncthr_t *)kmem_zalloc(sizeof (rdc_syncthr_t), KM_NOSLEEP);
-
- if (tmp == NULL)
- return (-1);
- tmp->offset = offset;
- tmp->len = len;
- tmp->status = stats;
- tmp->krdc = krdc;
-
- *synthr = tmp;
- return (0);
-}
-
-sync_status_t *
-_rdc_new_sync_status()
-{
- sync_status_t *s;
-
- s = (sync_status_t *)kmem_zalloc(sizeof (*s), KM_NOSLEEP);
- s->offset = -1;
- return (s);
-}
-
-void
-_rdc_free_sync_status(sync_status_t *status)
-{
- sync_status_t *s;
-
- while (status) {
- s = status->next;
- kmem_free(status, sizeof (*status));
- status = s;
- }
-}
-int
-_rdc_sync_status_ok(sync_status_t *status, int *offset)
-{
-#ifdef DEBUG_SYNCSTATUS
- int i = 0;
-#endif
- while (status) {
- if (status->offset >= 0) {
- *offset = status->offset;
- return (-1);
- }
- status = status->next;
-#ifdef DEBUG_SYNCSTATUS
- i++;
-#endif
- }
-#ifdef DEBUGSYNCSTATUS
- cmn_err(CE_NOTE, "!rdc_sync_status_ok: checked %d statuses", i);
-#endif
- return (0);
-}
-
-int mtsync = 1;
-/*
- * _rdc_sync() : rdc sync loop
- *
- */
-static void
-_rdc_sync(rdc_k_info_t *krdc)
-{
- nsc_size_t size = 0;
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- int rtype;
- int sts;
- int reserved = 0;
- nsc_buf_t *alloc_h = NULL;
- nsc_buf_t *handle = NULL;
- nsc_off_t mask;
- nsc_size_t maxbit;
- nsc_size_t len;
- nsc_off_t offset = 0;
- int sync_completed = 0;
- int tries = 0;
- int rc;
- int queuing = 0;
- uint_t bitmask;
- sync_status_t *ss, *sync_status = NULL;
- rdc_thrsync_t *sync = &krdc->syncs;
- rdc_syncthr_t *syncinfo;
- nsthread_t *trc = NULL;
-
- if (IS_STATE(urdc, RDC_QUEUING) && !IS_STATE(urdc, RDC_FULL)) {
- /* flusher is handling the sync in the update case */
- queuing = 1;
- goto sync_done;
- }
-
- /*
- * Main sync/resync loop
- */
- DTRACE_PROBE(rdc_sync_loop_start);
-
- rtype = RDC_RAW;
- sts = _rdc_rsrv_devs(krdc, rtype, RDC_INTERNAL);
-
- DTRACE_PROBE(rdc_sync_loop_rsrv);
-
- if (sts != 0)
- goto failed_noincr;
-
- reserved = 1;
-
- /*
- * pre-allocate a handle if we can - speeds up the sync.
- */
-
- if (rdc_prealloc_handle) {
- alloc_h = nsc_alloc_handle(RDC_U_FD(krdc), NULL, NULL, NULL);
-#ifdef DEBUG
- if (!alloc_h) {
- cmn_err(CE_WARN,
- "!rdc sync: failed to pre-alloc handle");
- }
-#endif
- } else {
- alloc_h = NULL;
- }
-
- ASSERT(urdc->volume_size != 0);
- size = urdc->volume_size;
- mask = ~(LOG_TO_FBA_NUM(1) - 1);
- maxbit = FBA_TO_LOG_NUM(size - 1);
-
- /*
- * as this while loop can also move data, it is counted as a
- * sync loop thread
- */
- rdc_group_enter(krdc);
- rdc_clr_flags(urdc, RDC_LOGGING);
- rdc_set_flags(urdc, RDC_SYNCING);
- krdc->group->synccount++;
- rdc_group_exit(krdc);
- mutex_enter(&sync_info.lock);
- sync_info.active_thr++;
- /* LINTED */
- RDC_AVAIL_THR_TUNE(sync_info);
- mutex_exit(&sync_info.lock);
-
- while (offset < size) {
- rdc_group_enter(krdc);
- ASSERT(krdc->aux_state & RDC_AUXSYNCIP);
- if (krdc->disk_status == 1 || krdc->dcio_bitmap == NULL) {
- rdc_group_exit(krdc);
- if (krdc->disk_status == 1) {
- DTRACE_PROBE(rdc_sync_loop_disk_status_err);
- } else {
- DTRACE_PROBE(rdc_sync_loop_dcio_bitmap_err);
- }
- goto failed; /* halt sync */
- }
- rdc_group_exit(krdc);
-
- if (!(rdc_get_vflags(urdc) & RDC_FULL)) {
- mutex_enter(&krdc->syncbitmutex);
- krdc->syncbitpos = FBA_TO_LOG_NUM(offset);
- len = 0;
-
- /* skip unnecessary chunks */
-
- while (krdc->syncbitpos <= maxbit &&
- !RDC_BIT_ISSET(krdc, krdc->syncbitpos)) {
- offset += LOG_TO_FBA_NUM(1);
- krdc->syncbitpos++;
- }
-
- /* check for boundary */
-
- if (offset >= size) {
- mutex_exit(&krdc->syncbitmutex);
- goto sync_done;
- }
-
- /* find maximal length we can transfer */
-
- while (krdc->syncbitpos <= maxbit &&
- RDC_BIT_ISSET(krdc, krdc->syncbitpos)) {
- len += LOG_TO_FBA_NUM(1);
- krdc->syncbitpos++;
- /* we can only read maxfbas anyways */
- if (len >= krdc->maxfbas)
- break;
- }
-
- len = min(len, (size - offset));
-
- } else {
- len = size - offset;
- }
-
- /* truncate to the io provider limit */
- ASSERT(krdc->maxfbas != 0);
- len = min(len, krdc->maxfbas);
-
- if (len > LOG_TO_FBA_NUM(1)) {
- /*
- * If the update is larger than a bitmap chunk,
- * then truncate to a whole number of bitmap
- * chunks.
- *
- * If the update is smaller than a bitmap
- * chunk, this must be the last write.
- */
- len &= mask;
- }
-
- if (!(rdc_get_vflags(urdc) & RDC_FULL)) {
- krdc->syncbitpos = FBA_TO_LOG_NUM(offset + len);
- mutex_exit(&krdc->syncbitmutex);
- }
-
- /*
- * Find out if we can reserve a thread here ...
- * note: skip the mutex for the first check, if the number
- * is up there, why bother even grabbing the mutex to
- * only realize that we can't have a thread anyways
- */
-
- if (mtsync && sync_info.active_thr < RDC_MAX_SYNC_THREADS) {
-
- mutex_enter(&sync_info.lock);
- if (sync_info.avail_thr >= 1) {
- if (sync_status == NULL) {
- ss = sync_status =
- _rdc_new_sync_status();
- } else {
- ss = ss->next = _rdc_new_sync_status();
- }
- if (ss == NULL) {
- mutex_exit(&sync_info.lock);
-#ifdef DEBUG
- cmn_err(CE_WARN, "!rdc_sync: can't "
- "allocate status for mt sync");
-#endif
- goto retry;
- }
- /*
- * syncinfo protected by sync_info lock but
- * not part of the sync_info structure
- * be careful if moving
- */
- if (_rdc_setup_syncthr(&syncinfo,
- offset, len, krdc, ss) < 0) {
- _rdc_free_sync_status(ss);
- }
-
- trc = nst_create(sync_info.rdc_syncset,
- _rdc_sync_thread, syncinfo, NST_SLEEP);
-
- if (trc == NULL) {
- mutex_exit(&sync_info.lock);
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!rdc_sync: unable to "
- "mt sync");
-#endif
- _rdc_free_sync_status(ss);
- kmem_free(syncinfo, sizeof (*syncinfo));
- syncinfo = NULL;
- goto retry;
- } else {
- mutex_enter(&sync->lock);
- sync->threads++;
- mutex_exit(&sync->lock);
- }
-
- sync_info.active_thr++;
- /* LINTED */
- RDC_AVAIL_THR_TUNE(sync_info);
-
- mutex_exit(&sync_info.lock);
- goto threaded;
- }
- mutex_exit(&sync_info.lock);
- }
-retry:
- handle = alloc_h;
- DTRACE_PROBE(rdc_sync_loop_allocbuf_start);
- if (rdc_get_vflags(urdc) & RDC_SLAVE)
- sts = nsc_alloc_buf(RDC_U_FD(krdc), offset, len,
- NSC_WRITE | NSC_WRTHRU | NSC_NOCACHE, &handle);
- else
- sts = nsc_alloc_buf(RDC_U_FD(krdc), offset, len,
- NSC_READ | NSC_NOCACHE, &handle);
-
- DTRACE_PROBE(rdc_sync_loop_allocbuf_end);
- if (sts > 0) {
- if (handle && handle != alloc_h) {
- (void) nsc_free_buf(handle);
- }
-
- handle = NULL;
- DTRACE_PROBE(rdc_sync_loop_allocbuf_err);
- goto failed;
- }
-
- if (rdc_get_vflags(urdc) & RDC_SLAVE) {
- /* overwrite buffer with remote data */
- sts = rdc_net_read(krdc->index, krdc->remote_index,
- handle, handle->sb_pos, handle->sb_len);
-
- if (!RDC_SUCCESS(sts)) {
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!rdc sync: remote read failed (%d)", sts);
-#endif
- DTRACE_PROBE(rdc_sync_loop_remote_read_err);
- goto failed;
- }
- if (!(rdc_get_vflags(urdc) & RDC_FULL))
- rdc_set_bitmap_many(krdc, handle->sb_pos,
- handle->sb_len);
-
- /* commit locally */
-
- sts = nsc_write(handle, handle->sb_pos,
- handle->sb_len, 0);
-
- if (!RDC_SUCCESS(sts)) {
- /* reverse sync needed already set */
- rdc_many_enter(krdc);
- rdc_set_flags_log(urdc, RDC_VOL_FAILED,
- "write failed during sync");
- rdc_many_exit(krdc);
- rdc_write_state(urdc);
- DTRACE_PROBE(rdc_sync_loop_nsc_write_err);
- goto failed;
- }
- } else {
- /* send local data to remote */
- DTRACE_PROBE2(rdc_sync_loop_netwrite_start,
- int, krdc->index, nsc_buf_t *, handle);
-
- if ((sts = rdc_net_write(krdc->index,
- krdc->remote_index, handle, handle->sb_pos,
- handle->sb_len, RDC_NOSEQ, RDC_NOQUE, NULL)) > 0) {
-
- /*
- * The following is to handle
- * the case where the secondary side
- * has thrown our buffer handle token away in a
- * attempt to preserve its health on restart
- */
- if ((sts == EPROTO) && (tries < 3)) {
- (void) nsc_free_buf(handle);
- handle = NULL;
- tries++;
- delay(HZ >> 2);
- goto retry;
- }
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!rdc sync: remote write failed (%d) 0x%x",
- sts, rdc_get_vflags(urdc));
-#endif
- DTRACE_PROBE(rdc_sync_loop_netwrite_err);
- goto failed;
- }
- DTRACE_PROBE(rdc_sync_loop_netwrite_end);
- }
-
- (void) nsc_free_buf(handle);
- handle = NULL;
-
- if (krdc->dcio_bitmap == NULL) {
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!_rdc_sync: NULL bitmap");
-#else
- ;
- /*EMPTY*/
-#endif
- } else {
-
- RDC_SET_BITMASK(offset, len, &bitmask);
- RDC_CLR_BITMAP(krdc, offset, len, bitmask, \
- RDC_BIT_FORCE);
- ASSERT(!IS_ASYNC(urdc));
- }
-
- /*
- * Only release/reserve if someone is waiting
- */
- if (krdc->devices->id_release || nsc_waiting(RDC_U_FD(krdc))) {
- DTRACE_PROBE(rdc_sync_loop_rlse_start);
- if (alloc_h) {
- (void) nsc_free_handle(alloc_h);
- alloc_h = NULL;
- }
-
- _rdc_rlse_devs(krdc, rtype);
- reserved = 0;
- delay(2);
-
- rtype = RDC_RAW;
- sts = _rdc_rsrv_devs(krdc, rtype, RDC_INTERNAL);
- if (sts != 0) {
- handle = NULL;
- DTRACE_PROBE(rdc_sync_loop_rdc_rsrv_err);
- goto failed;
- }
-
- reserved = 1;
-
- if (rdc_prealloc_handle) {
- alloc_h = nsc_alloc_handle(RDC_U_FD(krdc),
- NULL, NULL, NULL);
-#ifdef DEBUG
- if (!alloc_h) {
- cmn_err(CE_WARN, "!rdc_sync: "
- "failed to pre-alloc handle");
- }
-#endif
- }
- DTRACE_PROBE(rdc_sync_loop_rlse_end);
- }
-threaded:
- offset += len;
- urdc->sync_pos = offset;
- }
-
-sync_done:
- sync_completed = 1;
-
-failed:
- krdc->group->synccount--;
-failed_noincr:
- mutex_enter(&sync->lock);
- while (sync->complete != sync->threads) {
- cv_wait(&sync->cv, &sync->lock);
- }
- sync->complete = 0;
- sync->threads = 0;
- mutex_exit(&sync->lock);
-
- /*
- * if sync_completed is 0 here,
- * we know that the main sync thread failed anyway
- * so just free the statuses and fail
- */
- if (sync_completed && (_rdc_sync_status_ok(sync_status, &rc) < 0)) {
- urdc->sync_pos = rc;
- sync_completed = 0; /* at least 1 thread failed */
- }
-
- _rdc_free_sync_status(sync_status);
-
- /*
- * we didn't increment, we didn't even sync,
- * so don't dec sync_info.active_thr
- */
- if (!queuing) {
- mutex_enter(&sync_info.lock);
- sync_info.active_thr--;
- /* LINTED */
- RDC_AVAIL_THR_TUNE(sync_info);
- mutex_exit(&sync_info.lock);
- }
-
- if (handle) {
- (void) nsc_free_buf(handle);
- }
-
- if (alloc_h) {
- (void) nsc_free_handle(alloc_h);
- }
-
- if (reserved) {
- _rdc_rlse_devs(krdc, rtype);
- }
-
-notstarted:
- rdc_group_enter(krdc);
- ASSERT(krdc->aux_state & RDC_AUXSYNCIP);
- if (IS_STATE(urdc, RDC_QUEUING))
- rdc_clr_flags(urdc, RDC_QUEUING);
-
- if (sync_completed) {
- (void) rdc_net_state(krdc->index, CCIO_DONE);
- } else {
- (void) rdc_net_state(krdc->index, CCIO_ENABLELOG);
- }
-
- rdc_clr_flags(urdc, RDC_SYNCING);
- if (rdc_get_vflags(urdc) & RDC_SLAVE) {
- rdc_many_enter(krdc);
- rdc_clr_mflags(urdc, RDC_SLAVE);
- rdc_many_exit(krdc);
- }
- if (krdc->type_flag & RDC_ASYNCMODE)
- rdc_set_flags(urdc, RDC_ASYNC);
- if (sync_completed) {
- rdc_many_enter(krdc);
- rdc_clr_mflags(urdc, RDC_RSYNC_NEEDED);
- rdc_many_exit(krdc);
- } else {
- krdc->remote_index = -1;
- rdc_set_flags_log(urdc, RDC_LOGGING, "sync failed to complete");
- }
- rdc_group_exit(krdc);
- rdc_write_state(urdc);
-
- mutex_enter(&net_blk_lock);
- if (sync_completed)
- krdc->sync_done = RDC_COMPLETED;
- else
- krdc->sync_done = RDC_FAILED;
- cv_broadcast(&krdc->synccv);
- mutex_exit(&net_blk_lock);
-
-}
-
-
-static int
-rdc_sync(rdc_config_t *uparms, spcs_s_info_t kstatus)
-{
- rdc_set_t *rdc_set = uparms->rdc_set;
- int options = uparms->options;
- int rc = 0;
- int busy = 0;
- int index;
- rdc_k_info_t *krdc;
- rdc_u_info_t *urdc;
- rdc_k_info_t *kmulti;
- rdc_u_info_t *umulti;
- rdc_group_t *group;
- rdc_srv_t *svp;
- int sm, um, md;
- int sync_completed = 0;
- int thrcount;
-
- mutex_enter(&rdc_conf_lock);
- index = rdc_lookup_byname(rdc_set);
- if (index >= 0)
- krdc = &rdc_k_info[index];
- if (index < 0 || (krdc->type_flag & RDC_DISABLEPEND)) {
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EALREADY, rdc_set->primary.file,
- rdc_set->secondary.file);
- rc = RDC_EALREADY;
- goto notstarted;
- }
-
- urdc = &rdc_u_info[index];
- group = krdc->group;
- set_busy(krdc);
- busy = 1;
- if ((krdc->type_flag == 0) || (krdc->type_flag & RDC_DISABLEPEND)) {
- /* A resume or enable failed or we raced with a teardown */
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EALREADY, rdc_set->primary.file,
- rdc_set->secondary.file);
- rc = RDC_EALREADY;
- goto notstarted;
- }
- mutex_exit(&rdc_conf_lock);
- rdc_group_enter(krdc);
-
- if (!IS_STATE(urdc, RDC_LOGGING)) {
- spcs_s_add(kstatus, RDC_ESETNOTLOGGING, urdc->secondary.intf,
- urdc->secondary.file);
- rc = RDC_ENOTLOGGING;
- goto notstarted_unlock;
- }
-
- if (rdc_check(krdc, rdc_set)) {
- spcs_s_add(kstatus, RDC_EALREADY, rdc_set->primary.file,
- rdc_set->secondary.file);
- rc = RDC_EALREADY;
- goto notstarted_unlock;
- }
-
- if (!(rdc_get_vflags(urdc) & RDC_PRIMARY)) {
- spcs_s_add(kstatus, RDC_ENOTPRIMARY, rdc_set->primary.intf,
- rdc_set->primary.file, rdc_set->secondary.intf,
- rdc_set->secondary.file);
- rc = RDC_ENOTPRIMARY;
- goto notstarted_unlock;
- }
-
- if ((options & RDC_OPT_REVERSE) && (IS_STATE(urdc, RDC_QUEUING))) {
- /*
- * cannot reverse sync when queuing, need to go logging first
- */
- spcs_s_add(kstatus, RDC_EQNORSYNC, rdc_set->primary.intf,
- rdc_set->primary.file, rdc_set->secondary.intf,
- rdc_set->secondary.file);
- rc = RDC_EQNORSYNC;
- goto notstarted_unlock;
- }
-
- svp = krdc->lsrv;
- krdc->intf = rdc_add_to_if(svp, &(urdc->primary.addr),
- &(urdc->secondary.addr), 1);
-
- if (!krdc->intf) {
- spcs_s_add(kstatus, RDC_EADDTOIF, urdc->primary.intf,
- urdc->secondary.intf);
- rc = RDC_EADDTOIF;
- goto notstarted_unlock;
- }
-
- if (urdc->volume_size == 0) {
- /* Implies reserve failed when previous resume was done */
- rdc_get_details(krdc);
- }
- if (urdc->volume_size == 0) {
- spcs_s_add(kstatus, RDC_ENOBMAP);
- rc = RDC_ENOBMAP;
- goto notstarted_unlock;
- }
-
- if (krdc->dcio_bitmap == NULL) {
- if (rdc_resume_bitmap(krdc) < 0) {
- spcs_s_add(kstatus, RDC_ENOBMAP);
- rc = RDC_ENOBMAP;
- goto notstarted_unlock;
- }
- }
-
- if ((rdc_get_vflags(urdc) & RDC_BMP_FAILED) && (krdc->bitmapfd)) {
- if (rdc_reset_bitmap(krdc)) {
- spcs_s_add(kstatus, RDC_EBITMAP);
- rc = RDC_EBITMAP;
- goto notstarted_unlock;
- }
- }
-
- if (IS_MANY(krdc) || IS_MULTI(krdc)) {
- rdc_u_info_t *ubad;
-
- if ((ubad = rdc_allow_pri_sync(urdc, options)) != NULL) {
- spcs_s_add(kstatus, RDC_ESTATE,
- ubad->primary.intf, ubad->primary.file,
- ubad->secondary.intf, ubad->secondary.file);
- rc = RDC_ESTATE;
- goto notstarted_unlock;
- }
- }
-
- /*
- * there is a small window where _rdc_sync is still
- * running, but has cleared the RDC_SYNCING flag.
- * Use aux_state which is only cleared
- * after _rdc_sync had done its 'death' broadcast.
- */
- if (krdc->aux_state & RDC_AUXSYNCIP) {
-#ifdef DEBUG
- if (!rdc_get_vflags(urdc) & RDC_SYNCING) {
- cmn_err(CE_WARN, "!rdc_sync: "
- "RDC_AUXSYNCIP set, SYNCING off");
- }
-#endif
- spcs_s_add(kstatus, RDC_ESYNCING, rdc_set->primary.file);
- rc = RDC_ESYNCING;
- goto notstarted_unlock;
- }
- if (krdc->disk_status == 1) {
- spcs_s_add(kstatus, RDC_ESYNCING, rdc_set->primary.file);
- rc = RDC_ESYNCING;
- goto notstarted_unlock;
- }
-
- if ((options & RDC_OPT_FORWARD) &&
- (rdc_get_mflags(urdc) & RDC_RSYNC_NEEDED)) {
- /* cannot forward sync if a reverse sync is needed */
- spcs_s_add(kstatus, RDC_ERSYNCNEEDED, rdc_set->primary.intf,
- rdc_set->primary.file, rdc_set->secondary.intf,
- rdc_set->secondary.file);
- rc = RDC_ERSYNCNEEDED;
- goto notstarted_unlock;
- }
-
- urdc->sync_pos = 0;
-
- /* Check if the rdc set is accessible on the remote node */
- if (rdc_net_getstate(krdc, &sm, &um, &md, FALSE) < 0) {
- /*
- * Remote end may be inaccessible, or the rdc set is not
- * enabled at the remote end.
- */
- spcs_s_add(kstatus, RDC_ECONNOPEN, urdc->secondary.intf,
- urdc->secondary.file);
- rc = RDC_ECONNOPEN;
- goto notstarted_unlock;
- }
- if (options & RDC_OPT_REVERSE)
- krdc->remote_index = rdc_net_state(index, CCIO_RSYNC);
- else
- krdc->remote_index = rdc_net_state(index, CCIO_SLAVE);
- if (krdc->remote_index < 0) {
- /*
- * Remote note probably not in a valid state to be synced,
- * as the state was fetched OK above.
- */
- spcs_s_add(kstatus, RDC_ERSTATE, urdc->secondary.intf,
- urdc->secondary.file, urdc->primary.intf,
- urdc->primary.file);
- rc = RDC_ERSTATE;
- goto notstarted_unlock;
- }
-
- rc = check_filesize(index, kstatus);
- if (rc != 0) {
- (void) rdc_net_state(krdc->index, CCIO_ENABLELOG);
- goto notstarted_unlock;
- }
-
- krdc->sync_done = 0;
-
- mutex_enter(&krdc->bmapmutex);
- krdc->aux_state |= RDC_AUXSYNCIP;
- mutex_exit(&krdc->bmapmutex);
-
- if (options & RDC_OPT_REVERSE) {
- rdc_many_enter(krdc);
- rdc_set_mflags(urdc, RDC_SLAVE | RDC_RSYNC_NEEDED);
- mutex_enter(&krdc->bmapmutex);
- rdc_clr_flags(urdc, RDC_VOL_FAILED);
- mutex_exit(&krdc->bmapmutex);
- rdc_write_state(urdc);
- /* LINTED */
- if (kmulti = krdc->multi_next) {
- umulti = &rdc_u_info[kmulti->index];
- if (IS_ENABLED(umulti) && (rdc_get_vflags(umulti) &
- (RDC_VOL_FAILED | RDC_SYNC_NEEDED))) {
- rdc_clr_flags(umulti, RDC_SYNC_NEEDED);
- rdc_clr_flags(umulti, RDC_VOL_FAILED);
- rdc_write_state(umulti);
- }
- }
- rdc_many_exit(krdc);
- } else {
- rdc_clr_flags(urdc, RDC_FCAL_FAILED);
- rdc_write_state(urdc);
- }
-
- if (options & RDC_OPT_UPDATE) {
- ASSERT(urdc->volume_size != 0);
- if (rdc_net_getbmap(index,
- BMAP_LOG_BYTES(urdc->volume_size)) > 0) {
- spcs_s_add(kstatus, RDC_ENOBMAP);
- rc = RDC_ENOBMAP;
-
- (void) rdc_net_state(index, CCIO_ENABLELOG);
-
- rdc_clr_flags(urdc, RDC_SYNCING);
- if (options & RDC_OPT_REVERSE) {
- rdc_many_enter(krdc);
- rdc_clr_mflags(urdc, RDC_SLAVE);
- rdc_many_exit(krdc);
- }
- if (krdc->type_flag & RDC_ASYNCMODE)
- rdc_set_flags(urdc, RDC_ASYNC);
- krdc->remote_index = -1;
- rdc_set_flags_log(urdc, RDC_LOGGING,
- "failed to read remote bitmap");
- rdc_write_state(urdc);
- goto failed;
- }
- rdc_clr_flags(urdc, RDC_FULL);
- } else {
- /*
- * This is a full sync (not an update sync), mark the
- * entire bitmap dirty
- */
- (void) RDC_FILL_BITMAP(krdc, FALSE);
-
- rdc_set_flags(urdc, RDC_FULL);
- }
-
- rdc_group_exit(krdc);
-
- /*
- * allow diskq->memq flusher to wake up
- */
- mutex_enter(&krdc->group->ra_queue.net_qlock);
- krdc->group->ra_queue.qfflags &= ~RDC_QFILLSLEEP;
- mutex_exit(&krdc->group->ra_queue.net_qlock);
-
- /*
- * if this is a full sync on a non-diskq set or
- * a diskq set that has failed, clear the async flag
- */
- if (krdc->type_flag & RDC_ASYNCMODE) {
- if ((!(options & RDC_OPT_UPDATE)) ||
- (!RDC_IS_DISKQ(krdc->group)) ||
- (!(IS_STATE(urdc, RDC_QUEUING)))) {
- /* full syncs, or core queue are synchronous */
- rdc_group_enter(krdc);
- rdc_clr_flags(urdc, RDC_ASYNC);
- rdc_group_exit(krdc);
- }
-
- /*
- * if the queue failed because it was full, lets see
- * if we can restart it. After _rdc_sync() is done
- * the modes will switch and we will begin disk
- * queuing again. NOTE: this should only be called
- * once per group, as it clears state for all group
- * members, also clears the async flag for all members
- */
- if (IS_STATE(urdc, RDC_DISKQ_FAILED)) {
- rdc_unfail_diskq(krdc);
- } else {
- /* don't add insult to injury by flushing a dead queue */
-
- /*
- * if we are updating, and a diskq and
- * the async thread isn't active, start
- * it up.
- */
- if ((options & RDC_OPT_UPDATE) &&
- (IS_STATE(urdc, RDC_QUEUING))) {
- rdc_group_enter(krdc);
- rdc_clr_flags(urdc, RDC_SYNCING);
- rdc_group_exit(krdc);
- mutex_enter(&krdc->group->ra_queue.net_qlock);
- if (krdc->group->ra_queue.qfill_sleeping ==
- RDC_QFILL_ASLEEP)
- cv_broadcast(&group->ra_queue.qfcv);
- mutex_exit(&krdc->group->ra_queue.net_qlock);
- thrcount = urdc->asyncthr;
- while ((thrcount-- > 0) &&
- !krdc->group->rdc_writer) {
- (void) rdc_writer(krdc->index);
- }
- }
- }
- }
-
- /*
- * For a reverse sync, merge the current bitmap with all other sets
- * that share this volume.
- */
- if (options & RDC_OPT_REVERSE) {
-retry_many:
- rdc_many_enter(krdc);
- if (IS_MANY(krdc)) {
- rdc_k_info_t *kmany;
- rdc_u_info_t *umany;
-
- for (kmany = krdc->many_next; kmany != krdc;
- kmany = kmany->many_next) {
- umany = &rdc_u_info[kmany->index];
- if (!IS_ENABLED(umany))
- continue;
- ASSERT(umany->flags & RDC_PRIMARY);
-
- if (!mutex_tryenter(&kmany->group->lock)) {
- rdc_many_exit(krdc);
- /* May merge more than once */
- goto retry_many;
- }
- rdc_merge_bitmaps(krdc, kmany);
- mutex_exit(&kmany->group->lock);
- }
- }
- rdc_many_exit(krdc);
-
-retry_multi:
- rdc_many_enter(krdc);
- if (IS_MULTI(krdc)) {
- rdc_k_info_t *kmulti = krdc->multi_next;
- rdc_u_info_t *umulti = &rdc_u_info[kmulti->index];
-
- if (IS_ENABLED(umulti)) {
- ASSERT(!(umulti->flags & RDC_PRIMARY));
-
- if (!mutex_tryenter(&kmulti->group->lock)) {
- rdc_many_exit(krdc);
- goto retry_multi;
- }
- rdc_merge_bitmaps(krdc, kmulti);
- mutex_exit(&kmulti->group->lock);
- }
- }
- rdc_many_exit(krdc);
- }
-
- rdc_group_enter(krdc);
-
- if (krdc->bitmap_write == 0) {
- if (rdc_write_bitmap_fill(krdc) >= 0)
- krdc->bitmap_write = -1;
- }
-
- if (krdc->bitmap_write > 0)
- (void) rdc_write_bitmap(krdc);
-
- urdc->bits_set = RDC_COUNT_BITMAP(krdc);
-
- rdc_group_exit(krdc);
-
- if (options & RDC_OPT_REVERSE) {
- (void) _rdc_sync_event_notify(RDC_SYNC_START,
- urdc->primary.file, urdc->group_name);
- }
-
- /* Now set off the sync itself */
-
- mutex_enter(&net_blk_lock);
- if (nsc_create_process(
- (void (*)(void *))_rdc_sync, (void *)krdc, FALSE)) {
- mutex_exit(&net_blk_lock);
- spcs_s_add(kstatus, RDC_ENOPROC);
- /*
- * We used to just return here,
- * but we need to clear the AUXSYNCIP bit
- * and there is a very small chance that
- * someone may be waiting on the disk_status flag.
- */
- rc = RDC_ENOPROC;
- /*
- * need the group lock held at failed.
- */
- rdc_group_enter(krdc);
- goto failed;
- }
-
- mutex_enter(&rdc_conf_lock);
- wakeup_busy(krdc);
- busy = 0;
- mutex_exit(&rdc_conf_lock);
-
- while (krdc->sync_done == 0)
- cv_wait(&krdc->synccv, &net_blk_lock);
- mutex_exit(&net_blk_lock);
-
- rdc_group_enter(krdc);
-
- if (krdc->sync_done == RDC_FAILED) {
- char siztmp1[16];
- (void) spcs_s_inttostring(
- urdc->sync_pos, siztmp1, sizeof (siztmp1),
- 0);
- spcs_s_add(kstatus, RDC_EFAIL, siztmp1);
- rc = RDC_EFAIL;
- } else
- sync_completed = 1;
-
-failed:
- /*
- * We use this flag now to make halt_sync() wait for
- * us to terminate and let us take the group lock.
- */
- krdc->aux_state &= ~RDC_AUXSYNCIP;
- if (krdc->disk_status == 1) {
- krdc->disk_status = 0;
- cv_broadcast(&krdc->haltcv);
- }
-
-notstarted_unlock:
- rdc_group_exit(krdc);
-
- if (sync_completed && (options & RDC_OPT_REVERSE)) {
- (void) _rdc_sync_event_notify(RDC_SYNC_DONE,
- urdc->primary.file, urdc->group_name);
- }
-
-notstarted:
- if (busy) {
- mutex_enter(&rdc_conf_lock);
- wakeup_busy(krdc);
- mutex_exit(&rdc_conf_lock);
- }
-
- return (rc);
-}
-
-/* ARGSUSED */
-static int
-_rdc_suspend(rdc_k_info_t *krdc, rdc_set_t *rdc_set, spcs_s_info_t kstatus)
-{
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- rdc_if_t *ip;
- int index = krdc->index;
-
- ASSERT(krdc->group != NULL);
- rdc_group_enter(krdc);
-#ifdef DEBUG
- ASSERT(rdc_check(krdc, rdc_set) == 0);
-#else
- if (rdc_check(krdc, rdc_set)) {
- rdc_group_exit(krdc);
- spcs_s_add(kstatus, RDC_EALREADY, rdc_set->primary.file,
- rdc_set->secondary.file);
- return (RDC_EALREADY);
- }
-#endif
-
- if (rdc_get_vflags(urdc) & RDC_PRIMARY) {
- halt_sync(krdc);
- ASSERT(IS_ENABLED(urdc));
- }
-
- rdc_group_exit(krdc);
- (void) rdc_unintercept(krdc);
-
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!SNDR: suspended %s %s", urdc->primary.file,
- urdc->secondary.file);
-#endif
-
- /* Configured but not enabled */
- ASSERT(IS_CONFIGURED(krdc) && !IS_ENABLED(urdc));
-
-
- if (IS_ASYNC(urdc) && !RDC_IS_DISKQ(krdc->group)) {
- int tries = 2; /* in case of possibly stuck flusher threads */
-#ifdef DEBUG
- net_queue *qp = &krdc->group->ra_queue;
-#endif
- do {
- if (!krdc->group->rdc_writer)
- (void) rdc_writer(krdc->index);
-
- (void) rdc_drain_queue(krdc->index);
-
- } while (krdc->group->rdc_writer && tries--);
-
- /* ok, force it to happen... */
- if (rdc_drain_queue(krdc->index) != 0) {
- do {
- mutex_enter(&krdc->group->ra_queue.net_qlock);
- krdc->group->asyncdis = 1;
- cv_broadcast(&krdc->group->asyncqcv);
- mutex_exit(&krdc->group->ra_queue.net_qlock);
- cmn_err(CE_WARN,
- "!SNDR: async I/O pending and not flushed "
- "for %s during suspend",
- urdc->primary.file);
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!nitems: %" NSC_SZFMT " nblocks: %"
- NSC_SZFMT " head: 0x%p tail: 0x%p",
- qp->nitems, qp->blocks,
- (void *)qp->net_qhead,
- (void *)qp->net_qtail);
-#endif
- } while (krdc->group->rdc_thrnum > 0);
- }
- }
-
- mutex_enter(&rdc_conf_lock);
- ip = krdc->intf;
- krdc->intf = 0;
-
- if (ip) {
- rdc_remove_from_if(ip);
- }
-
- mutex_exit(&rdc_conf_lock);
-
- rdc_group_enter(krdc);
-
- /* Configured but not enabled */
- ASSERT(IS_CONFIGURED(krdc) && !IS_ENABLED(urdc));
-
- rdc_group_exit(krdc);
- /* Must not hold group lock during this function */
- while (rdc_dump_alloc_bufs_cd(krdc->index) == EAGAIN)
- delay(2);
- rdc_group_enter(krdc);
-
- /* Don't rdc_clear_state, unlike _rdc_disable */
-
- rdc_free_bitmap(krdc, RDC_CMD_SUSPEND);
- rdc_close_bitmap(krdc);
-
- rdc_dev_close(krdc);
- rdc_close_direct(krdc);
-
- /* Configured but not enabled */
- ASSERT(IS_CONFIGURED(krdc) && !IS_ENABLED(urdc));
-
- rdc_group_exit(krdc);
-
- /*
- * we should now unregister the queue, with no conflicting
- * locks held. This is the last(only) member of the group
- */
- if (krdc->group && RDC_IS_DISKQ(krdc->group) &&
- krdc->group->count == 1) { /* stop protecting queue */
- rdc_unintercept_diskq(krdc->group);
- }
-
- mutex_enter(&rdc_conf_lock);
-
- /* Configured but not enabled */
- ASSERT(IS_CONFIGURED(krdc) && !IS_ENABLED(urdc));
-
- wait_busy(krdc);
-
- if (IS_MANY(krdc) || IS_MULTI(krdc))
- remove_from_many(krdc);
-
- remove_from_group(krdc);
-
- krdc->remote_index = -1;
- ASSERT(krdc->type_flag & RDC_CONFIGURED);
- ASSERT(krdc->type_flag & RDC_DISABLEPEND);
- krdc->type_flag = 0;
-#ifdef DEBUG
- if (krdc->dcio_bitmap)
- cmn_err(CE_WARN, "!_rdc_suspend: possible mem leak, "
- "dcio_bitmap");
-#endif
- krdc->dcio_bitmap = NULL;
- krdc->bitmap_ref = NULL;
- krdc->bitmap_size = 0;
- krdc->maxfbas = 0;
- krdc->bitmap_write = 0;
- krdc->disk_status = 0;
- rdc_destroy_svinfo(krdc->lsrv);
- krdc->lsrv = NULL;
- krdc->multi_next = NULL;
-
- rdc_u_init(urdc);
-
- mutex_exit(&rdc_conf_lock);
- rdc_kstat_delete(index);
- return (0);
-}
-
-static int
-rdc_suspend(rdc_config_t *uparms, spcs_s_info_t kstatus)
-{
- rdc_k_info_t *krdc;
- int index;
- int rc;
-
- mutex_enter(&rdc_conf_lock);
-
- index = rdc_lookup_byname(uparms->rdc_set);
- if (index >= 0)
- krdc = &rdc_k_info[index];
- if (index < 0 || (krdc->type_flag & RDC_DISABLEPEND)) {
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EALREADY, uparms->rdc_set->primary.file,
- uparms->rdc_set->secondary.file);
- return (RDC_EALREADY);
- }
-
- krdc->type_flag |= RDC_DISABLEPEND;
- wait_busy(krdc);
- if (krdc->type_flag == 0) {
- /* A resume or enable failed */
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EALREADY, uparms->rdc_set->primary.file,
- uparms->rdc_set->secondary.file);
- return (RDC_EALREADY);
- }
- mutex_exit(&rdc_conf_lock);
-
- rc = _rdc_suspend(krdc, uparms->rdc_set, kstatus);
- return (rc);
-}
-
-static int
-_rdc_resume(rdc_set_t *rdc_set, int options, spcs_s_info_t kstatus)
-{
- int index;
- char *rhost;
- struct netbuf *addrp;
- rdc_k_info_t *krdc;
- rdc_u_info_t *urdc;
- rdc_srv_t *svp = NULL;
- char *local_file;
- char *local_bitmap;
- int rc, rc1;
- nsc_size_t maxfbas;
- rdc_group_t *grp;
-
- if ((rdc_set->primary.intf[0] == 0) ||
- (rdc_set->primary.addr.len == 0) ||
- (rdc_set->primary.file[0] == 0) ||
- (rdc_set->primary.bitmap[0] == 0) ||
- (rdc_set->secondary.intf[0] == 0) ||
- (rdc_set->secondary.addr.len == 0) ||
- (rdc_set->secondary.file[0] == 0) ||
- (rdc_set->secondary.bitmap[0] == 0)) {
- spcs_s_add(kstatus, RDC_EEMPTY);
- return (RDC_EEMPTY);
- }
-
- /* Next check there aren't any enabled rdc sets which match. */
-
- mutex_enter(&rdc_conf_lock);
-
- if (rdc_lookup_byname(rdc_set) >= 0) {
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EENABLED, rdc_set->primary.intf,
- rdc_set->primary.file, rdc_set->secondary.intf,
- rdc_set->secondary.file);
- return (RDC_EENABLED);
- }
-
- if (rdc_lookup_many2one(rdc_set) >= 0) {
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EMANY2ONE, rdc_set->primary.intf,
- rdc_set->primary.file, rdc_set->secondary.intf,
- rdc_set->secondary.file);
- return (RDC_EMANY2ONE);
- }
-
- if (rdc_set->netconfig->knc_proto == NULL) {
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_ENETCONFIG);
- return (RDC_ENETCONFIG);
- }
-
- if (rdc_set->primary.addr.len == 0) {
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_ENETBUF, rdc_set->primary.file);
- return (RDC_ENETBUF);
- }
-
- if (rdc_set->secondary.addr.len == 0) {
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_ENETBUF, rdc_set->secondary.file);
- return (RDC_ENETBUF);
- }
-
- /* Check that the local data volume isn't in use as a bitmap */
- if (options & RDC_OPT_PRIMARY)
- local_file = rdc_set->primary.file;
- else
- local_file = rdc_set->secondary.file;
- if (rdc_lookup_bitmap(local_file) >= 0) {
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EVOLINUSE, local_file);
- return (RDC_EVOLINUSE);
- }
-
- /* check that the secondary data volume isn't in use */
- if (!(options & RDC_OPT_PRIMARY)) {
- local_file = rdc_set->secondary.file;
- if (rdc_lookup_secondary(local_file) >= 0) {
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EVOLINUSE, local_file);
- return (RDC_EVOLINUSE);
- }
- }
-
- /* Check that the bitmap isn't in use as a data volume */
- if (options & RDC_OPT_PRIMARY)
- local_bitmap = rdc_set->primary.bitmap;
- else
- local_bitmap = rdc_set->secondary.bitmap;
- if (rdc_lookup_configured(local_bitmap) >= 0) {
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EBMPINUSE, local_bitmap);
- return (RDC_EBMPINUSE);
- }
-
- /* Check that the bitmap isn't already in use as a bitmap */
- if (rdc_lookup_bitmap(local_bitmap) >= 0) {
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EBMPINUSE, local_bitmap);
- return (RDC_EBMPINUSE);
- }
-
- /* Set urdc->volume_size */
- index = rdc_dev_open(rdc_set, options);
- if (index < 0) {
- mutex_exit(&rdc_conf_lock);
- if (options & RDC_OPT_PRIMARY)
- spcs_s_add(kstatus, RDC_EOPEN, rdc_set->primary.intf,
- rdc_set->primary.file);
- else
- spcs_s_add(kstatus, RDC_EOPEN, rdc_set->secondary.intf,
- rdc_set->secondary.file);
- return (RDC_EOPEN);
- }
-
- urdc = &rdc_u_info[index];
- krdc = &rdc_k_info[index];
-
- /* copy relevant parts of rdc_set to urdc field by field */
-
- (void) strncpy(urdc->primary.intf, rdc_set->primary.intf,
- MAX_RDC_HOST_SIZE);
- (void) strncpy(urdc->secondary.intf, rdc_set->secondary.intf,
- MAX_RDC_HOST_SIZE);
-
- (void) strncpy(urdc->group_name, rdc_set->group_name, NSC_MAXPATH);
-
- dup_rdc_netbuf(&rdc_set->primary.addr, &urdc->primary.addr);
- (void) strncpy(urdc->primary.file, rdc_set->primary.file, NSC_MAXPATH);
- (void) strncpy(urdc->primary.bitmap, rdc_set->primary.bitmap,
- NSC_MAXPATH);
-
- dup_rdc_netbuf(&rdc_set->secondary.addr, &urdc->secondary.addr);
- (void) strncpy(urdc->secondary.file, rdc_set->secondary.file,
- NSC_MAXPATH);
- (void) strncpy(urdc->secondary.bitmap, rdc_set->secondary.bitmap,
- NSC_MAXPATH);
- (void) strncpy(urdc->disk_queue, rdc_set->disk_queue, NSC_MAXPATH);
- urdc->setid = rdc_set->setid;
-
- if ((options & RDC_OPT_SYNC) && urdc->disk_queue[0]) {
- mutex_exit(&rdc_conf_lock);
- rdc_dev_close(krdc);
- spcs_s_add(kstatus, RDC_EQWRONGMODE);
- return (RDC_EQWRONGMODE);
- }
-
- /*
- * init flags now so that state left by failures in add_to_group()
- * are preserved.
- */
- rdc_init_flags(urdc);
-
- if ((rc1 = add_to_group(krdc, options, RDC_CMD_RESUME)) != 0) {
- if (rc1 == RDC_EQNOADD) { /* something went wrong with queue */
- rdc_fail_diskq(krdc, RDC_WAIT, RDC_NOLOG);
- /* don't return a failure here, continue with resume */
-
- } else { /* some other group add failure */
- mutex_exit(&rdc_conf_lock);
- rdc_dev_close(krdc);
- spcs_s_add(kstatus, RDC_EGROUP,
- rdc_set->primary.intf, rdc_set->primary.file,
- rdc_set->secondary.intf, rdc_set->secondary.file,
- rdc_set->group_name);
- return (RDC_EGROUP);
- }
- }
-
- /*
- * maxfbas was set in rdc_dev_open as primary's maxfbas.
- * If diskq's maxfbas is smaller, then use diskq's.
- */
- grp = krdc->group;
- if (grp && RDC_IS_DISKQ(grp) && (grp->diskqfd != 0)) {
- rc = _rdc_rsrv_diskq(grp);
- if (RDC_SUCCESS(rc)) {
- rc = nsc_maxfbas(grp->diskqfd, 0, &maxfbas);
- if (rc == 0) {
-#ifdef DEBUG
- if (krdc->maxfbas != maxfbas)
- cmn_err(CE_NOTE,
- "!_rdc_resume: diskq maxfbas = %"
- NSC_SZFMT ", primary maxfbas = %"
- NSC_SZFMT, maxfbas, krdc->maxfbas);
-#endif
- krdc->maxfbas = min(krdc->maxfbas,
- maxfbas);
- } else {
- cmn_err(CE_WARN,
- "!_rdc_resume: diskq maxfbas failed (%d)",
- rc);
- }
- _rdc_rlse_diskq(grp);
- } else {
- cmn_err(CE_WARN,
- "!_rdc_resume: diskq reserve failed (%d)", rc);
- }
- }
-
- (void) strncpy(urdc->direct_file, rdc_set->direct_file, NSC_MAXPATH);
- if ((options & RDC_OPT_PRIMARY) && rdc_set->direct_file[0]) {
- if (rdc_open_direct(krdc) == NULL)
- rdc_set_flags(urdc, RDC_FCAL_FAILED);
- }
-
- krdc->many_next = krdc;
-
- ASSERT(krdc->type_flag == 0);
- krdc->type_flag = RDC_CONFIGURED;
-
- if (options & RDC_OPT_PRIMARY)
- rdc_set_flags(urdc, RDC_PRIMARY);
-
- if (options & RDC_OPT_ASYNC)
- krdc->type_flag |= RDC_ASYNCMODE;
-
- set_busy(krdc);
-
- urdc->syshostid = rdc_set->syshostid;
-
- if (add_to_many(krdc) < 0) {
- mutex_exit(&rdc_conf_lock);
-
- rdc_group_enter(krdc);
-
- spcs_s_add(kstatus, RDC_EMULTI);
- rc = RDC_EMULTI;
- goto fail;
- }
-
- /* Configured but not enabled */
- ASSERT(IS_CONFIGURED(krdc) && !IS_ENABLED(urdc));
-
- mutex_exit(&rdc_conf_lock);
-
- if (urdc->volume_size == 0) {
- rdc_many_enter(krdc);
- if (options & RDC_OPT_PRIMARY)
- rdc_set_mflags(urdc, RDC_RSYNC_NEEDED);
- else
- rdc_set_flags(urdc, RDC_SYNC_NEEDED);
- rdc_set_flags(urdc, RDC_VOL_FAILED);
- rdc_many_exit(krdc);
- }
-
- rdc_group_enter(krdc);
-
- /* Configured but not enabled */
- ASSERT(IS_CONFIGURED(krdc) && !IS_ENABLED(urdc));
-
- /*
- * The rdc set is configured but not yet enabled. Other operations must
- * ignore this set until it is enabled.
- */
-
- urdc->sync_pos = 0;
-
- /* Set tunable defaults, we'll pick up tunables from the header later */
-
- urdc->maxqfbas = rdc_maxthres_queue;
- urdc->maxqitems = rdc_max_qitems;
- urdc->autosync = 0;
- urdc->asyncthr = rdc_asyncthr;
-
- urdc->netconfig = rdc_set->netconfig;
-
- if (options & RDC_OPT_PRIMARY) {
- rhost = rdc_set->secondary.intf;
- addrp = &rdc_set->secondary.addr;
- } else {
- rhost = rdc_set->primary.intf;
- addrp = &rdc_set->primary.addr;
- }
-
- if (options & RDC_OPT_ASYNC)
- rdc_set_flags(urdc, RDC_ASYNC);
-
- svp = rdc_create_svinfo(rhost, addrp, urdc->netconfig);
- if (svp == NULL) {
- spcs_s_add(kstatus, ENOMEM);
- rc = ENOMEM;
- goto fail;
- }
-
- urdc->netconfig = NULL; /* This will be no good soon */
-
- /* Don't set krdc->intf here */
- rdc_kstat_create(index);
-
- /* if the bitmap resume isn't clean, it will clear queuing flag */
-
- (void) rdc_resume_bitmap(krdc);
-
- if (RDC_IS_DISKQ(krdc->group)) {
- disk_queue *q = &krdc->group->diskq;
- if ((rc1 == RDC_EQNOADD) ||
- IS_QSTATE(q, RDC_QBADRESUME)) {
- rdc_clr_flags(urdc, RDC_QUEUING);
- RDC_ZERO_BITREF(krdc);
- }
- }
-
- if (krdc->lsrv == NULL)
- krdc->lsrv = svp;
- else {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!_rdc_resume: krdc->lsrv already set: %p",
- (void *) krdc->lsrv);
-#endif
- rdc_destroy_svinfo(svp);
- }
- svp = NULL;
-
- /* Configured but not enabled */
- ASSERT(IS_CONFIGURED(krdc) && !IS_ENABLED(urdc));
-
- /* And finally */
-
- krdc->remote_index = -1;
-
- /* Should we set the whole group logging? */
- rdc_set_flags(urdc, RDC_ENABLED | RDC_LOGGING);
-
- rdc_group_exit(krdc);
-
- if (rdc_intercept(krdc) != 0) {
- rdc_group_enter(krdc);
- rdc_clr_flags(urdc, RDC_ENABLED);
- if (options & RDC_OPT_PRIMARY)
- spcs_s_add(kstatus, RDC_EREGISTER, urdc->primary.file);
- else
- spcs_s_add(kstatus, RDC_EREGISTER,
- urdc->secondary.file);
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!nsc_register_path failed %s",
- urdc->primary.file);
-#endif
- rc = RDC_EREGISTER;
- goto bmpfail;
- }
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!SNDR: resumed %s %s", urdc->primary.file,
- urdc->secondary.file);
-#endif
-
- rdc_write_state(urdc);
-
- mutex_enter(&rdc_conf_lock);
- wakeup_busy(krdc);
- mutex_exit(&rdc_conf_lock);
-
- return (0);
-
-bmpfail:
- if (options & RDC_OPT_PRIMARY)
- spcs_s_add(kstatus, RDC_EBITMAP, urdc->primary.bitmap);
- else
- spcs_s_add(kstatus, RDC_EBITMAP, urdc->secondary.bitmap);
- rc = RDC_EBITMAP;
- if (rdc_get_vflags(urdc) & RDC_ENABLED) {
- rdc_group_exit(krdc);
- (void) rdc_unintercept(krdc);
- rdc_group_enter(krdc);
- }
-
-fail:
- rdc_kstat_delete(index);
- /* Don't unset krdc->intf here, unlike _rdc_enable */
-
- /* Configured but not enabled */
- ASSERT(IS_CONFIGURED(krdc) && !IS_ENABLED(urdc));
-
- rdc_dev_close(krdc);
- rdc_close_direct(krdc);
- rdc_destroy_svinfo(svp);
-
- /* Configured but not enabled */
- ASSERT(IS_CONFIGURED(krdc) && !IS_ENABLED(urdc));
-
- rdc_group_exit(krdc);
-
- mutex_enter(&rdc_conf_lock);
-
- /* Configured but not enabled */
- ASSERT(IS_CONFIGURED(krdc) && !IS_ENABLED(urdc));
-
- remove_from_group(krdc);
-
- if (IS_MANY(krdc) || IS_MULTI(krdc))
- remove_from_many(krdc);
-
- rdc_u_init(urdc);
-
- ASSERT(krdc->type_flag & RDC_CONFIGURED);
- krdc->type_flag = 0;
- wakeup_busy(krdc);
-
- mutex_exit(&rdc_conf_lock);
-
- return (rc);
-}
-
-static int
-rdc_resume(rdc_config_t *uparms, spcs_s_info_t kstatus)
-{
- char itmp[10];
- int rc;
-
- if (!(uparms->options & RDC_OPT_SYNC) &&
- !(uparms->options & RDC_OPT_ASYNC)) {
- (void) spcs_s_inttostring(
- uparms->options, itmp, sizeof (itmp), 1);
- spcs_s_add(kstatus, RDC_EEINVAL, itmp);
- rc = RDC_EEINVAL;
- goto done;
- }
-
- if (!(uparms->options & RDC_OPT_PRIMARY) &&
- !(uparms->options & RDC_OPT_SECONDARY)) {
- (void) spcs_s_inttostring(
- uparms->options, itmp, sizeof (itmp), 1);
- spcs_s_add(kstatus, RDC_EEINVAL, itmp);
- rc = RDC_EEINVAL;
- goto done;
- }
-
- rc = _rdc_resume(uparms->rdc_set, uparms->options, kstatus);
-done:
- return (rc);
-}
-
-/*
- * if rdc_group_log is called because a volume has failed,
- * we must disgard the queue to preserve write ordering.
- * later perhaps, we can keep queuing, but we would have to
- * rewrite the i/o path to acommodate that. currently, if there
- * is a volume failure, the buffers are satisfied remotely and
- * there is no way to satisfy them from the current diskq config
- * phew, if we do that.. it will be difficult
- */
-int
-rdc_can_queue(rdc_k_info_t *krdc)
-{
- rdc_k_info_t *p;
- rdc_u_info_t *q;
-
- for (p = krdc->group_next; ; p = p->group_next) {
- q = &rdc_u_info[p->index];
- if (IS_STATE(q, RDC_VOL_FAILED))
- return (0);
- if (p == krdc)
- break;
- }
- return (1);
-}
-
-/*
- * wait here, until all in flight async i/o's have either
- * finished or failed. Avoid the race with r_net_state()
- * which tells remote end to log.
- */
-void
-rdc_inflwait(rdc_group_t *grp)
-{
- int bail = RDC_CLNT_TMOUT * 2; /* to include retries */
- volatile int *inflitems;
-
- if (RDC_IS_DISKQ(grp))
- inflitems = (&(grp->diskq.inflitems));
- else
- inflitems = (&(grp->ra_queue.inflitems));
-
- while (*inflitems && (--bail > 0))
- delay(HZ);
-}
-
-void
-rdc_group_log(rdc_k_info_t *krdc, int flag, char *why)
-{
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- rdc_k_info_t *p;
- rdc_u_info_t *q;
- int do_group;
- int sm, um, md;
- disk_queue *dq;
-
- void (*flag_op)(rdc_u_info_t *urdc, int flag);
-
- ASSERT(MUTEX_HELD(&krdc->group->lock));
-
- if (!IS_ENABLED(urdc))
- return;
-
- rdc_many_enter(krdc);
-
- if ((flag & RDC_QUEUING) && (!IS_STATE(urdc, RDC_SYNCING)) &&
- (rdc_can_queue(krdc))) {
- flag_op = rdc_set_flags; /* keep queuing, link error */
- flag &= ~RDC_FLUSH;
- } else {
- flag_op = rdc_clr_flags; /* stop queuing, user request */
- }
-
- do_group = 1;
- if (!(rdc_get_vflags(urdc) & RDC_PRIMARY))
- do_group = 0;
- else if ((urdc->group_name[0] == 0) ||
- (rdc_get_vflags(urdc) & RDC_LOGGING) ||
- (rdc_get_vflags(urdc) & RDC_SYNCING))
- do_group = 0;
- if (do_group) {
- for (p = krdc->group_next; p != krdc; p = p->group_next) {
- q = &rdc_u_info[p->index];
- if (!IS_ENABLED(q))
- continue;
- if ((rdc_get_vflags(q) & RDC_LOGGING) ||
- (rdc_get_vflags(q) & RDC_SYNCING)) {
- do_group = 0;
- break;
- }
- }
- }
- if (!do_group && (flag & RDC_FORCE_GROUP))
- do_group = 1;
-
- rdc_many_exit(krdc);
- dq = &krdc->group->diskq;
- if (do_group) {
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!SNDR:Group point-in-time for grp: %s %s:%s",
- urdc->group_name, urdc->primary.intf, urdc->secondary.intf);
-#endif
- DTRACE_PROBE(rdc_diskq_group_PIT);
-
- /* Set group logging at the same PIT under rdc_many_lock */
- rdc_many_enter(krdc);
- rdc_set_flags_log(urdc, RDC_LOGGING, why);
- if (RDC_IS_DISKQ(krdc->group))
- flag_op(urdc, RDC_QUEUING);
- for (p = krdc->group_next; p != krdc; p = p->group_next) {
- q = &rdc_u_info[p->index];
- if (!IS_ENABLED(q))
- continue;
- rdc_set_flags_log(q, RDC_LOGGING,
- "consistency group member following leader");
- if (RDC_IS_DISKQ(p->group))
- flag_op(q, RDC_QUEUING);
- }
-
- rdc_many_exit(krdc);
-
- /*
- * This can cause the async threads to fail,
- * which in turn will call rdc_group_log()
- * again. Release the lock and re-aquire.
- */
- rdc_group_exit(krdc);
-
- while (rdc_dump_alloc_bufs_cd(krdc->index) == EAGAIN)
- delay(2);
- if (!RDC_IS_DISKQ(krdc->group))
- RDC_ZERO_BITREF(krdc);
-
- rdc_inflwait(krdc->group);
-
- /*
- * a little lazy, but neat. recall dump_alloc_bufs to
- * ensure that the queue pointers & seq are reset properly
- * after we have waited for inflight stuff
- */
- while (rdc_dump_alloc_bufs_cd(krdc->index) == EAGAIN)
- delay(2);
-
- rdc_group_enter(krdc);
- if (RDC_IS_DISKQ(krdc->group) && (!(flag & RDC_QUEUING))) {
- /* fail or user request */
- RDC_ZERO_BITREF(krdc);
- mutex_enter(&krdc->group->diskq.disk_qlock);
- rdc_init_diskq_header(krdc->group,
- &krdc->group->diskq.disk_hdr);
- SET_QNXTIO(dq, QHEAD(dq));
- mutex_exit(&krdc->group->diskq.disk_qlock);
- }
-
- if (flag & RDC_ALLREMOTE) {
- /* Tell other node to start logging */
- if (krdc->lsrv && krdc->intf && !krdc->intf->if_down)
- (void) rdc_net_state(krdc->index,
- CCIO_ENABLELOG);
- }
-
- if (flag & (RDC_ALLREMOTE | RDC_OTHERREMOTE)) {
- rdc_many_enter(krdc);
- for (p = krdc->group_next; p != krdc;
- p = p->group_next) {
- if (p->lsrv && krdc->intf &&
- !krdc->intf->if_down) {
- (void) rdc_net_state(p->index,
- CCIO_ENABLELOG);
- }
- }
- rdc_many_exit(krdc);
- }
-
- rdc_write_state(urdc);
- for (p = krdc->group_next; p != krdc; p = p->group_next) {
- q = &rdc_u_info[p->index];
- if (!IS_ENABLED(q))
- continue;
- rdc_write_state(q);
- }
- } else {
- /* No point in time is possible, just deal with single set */
-
- if (rdc_get_vflags(urdc) & RDC_PRIMARY) {
- halt_sync(krdc);
- } else {
- if (rdc_net_getstate(krdc, &sm, &um, &md, TRUE) < 0) {
- rdc_clr_flags(urdc, RDC_SYNCING);
- rdc_set_flags_log(urdc, RDC_LOGGING,
- "failed to read remote state");
-
- rdc_write_state(urdc);
- while (rdc_dump_alloc_bufs_cd(krdc->index)
- == EAGAIN)
- delay(2);
- if ((RDC_IS_DISKQ(krdc->group)) &&
- (!(flag & RDC_QUEUING))) { /* fail! */
- mutex_enter(QLOCK(dq));
- rdc_init_diskq_header(krdc->group,
- &krdc->group->diskq.disk_hdr);
- SET_QNXTIO(dq, QHEAD(dq));
- mutex_exit(QLOCK(dq));
- }
-
- return;
- }
- }
-
- if (rdc_get_vflags(urdc) & RDC_SYNCING)
- return;
-
- if (RDC_IS_DISKQ(krdc->group))
- flag_op(urdc, RDC_QUEUING);
-
- if ((RDC_IS_DISKQ(krdc->group)) &&
- (!(flag & RDC_QUEUING))) { /* fail! */
- RDC_ZERO_BITREF(krdc);
- mutex_enter(QLOCK(dq));
- rdc_init_diskq_header(krdc->group,
- &krdc->group->diskq.disk_hdr);
- SET_QNXTIO(dq, QHEAD(dq));
- mutex_exit(QLOCK(dq));
- }
-
- if (!(rdc_get_vflags(urdc) & RDC_LOGGING)) {
- rdc_set_flags_log(urdc, RDC_LOGGING, why);
-
- rdc_write_state(urdc);
-
- while (rdc_dump_alloc_bufs_cd(krdc->index) == EAGAIN)
- delay(2);
- if (!RDC_IS_DISKQ(krdc->group))
- RDC_ZERO_BITREF(krdc);
-
- rdc_inflwait(krdc->group);
- /*
- * a little lazy, but neat. recall dump_alloc_bufs to
- * ensure that the queue pointers & seq are reset
- * properly after we have waited for inflight stuff
- */
- while (rdc_dump_alloc_bufs_cd(krdc->index) == EAGAIN)
- delay(2);
-
- if (flag & RDC_ALLREMOTE) {
- /* Tell other node to start logging */
- if (krdc->lsrv && krdc->intf &&
- !krdc->intf->if_down) {
- (void) rdc_net_state(krdc->index,
- CCIO_ENABLELOG);
- }
- }
- }
- }
- /*
- * just in case any threads were in flight during log cleanup
- */
- if (RDC_IS_DISKQ(krdc->group)) {
- mutex_enter(QLOCK(dq));
- cv_broadcast(&dq->qfullcv);
- mutex_exit(QLOCK(dq));
- }
-}
-
-static int
-_rdc_log(rdc_k_info_t *krdc, rdc_set_t *rdc_set, spcs_s_info_t kstatus)
-{
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
- rdc_srv_t *svp;
-
- rdc_group_enter(krdc);
- if (rdc_check(krdc, rdc_set)) {
- rdc_group_exit(krdc);
- spcs_s_add(kstatus, RDC_EALREADY, rdc_set->primary.file,
- rdc_set->secondary.file);
- return (RDC_EALREADY);
- }
-
- svp = krdc->lsrv;
- if (rdc_get_vflags(urdc) & RDC_PRIMARY)
- krdc->intf = rdc_add_to_if(svp, &(urdc->primary.addr),
- &(urdc->secondary.addr), 1);
- else
- krdc->intf = rdc_add_to_if(svp, &(urdc->secondary.addr),
- &(urdc->primary.addr), 0);
-
- if (!krdc->intf) {
- rdc_group_exit(krdc);
- spcs_s_add(kstatus, RDC_EADDTOIF, urdc->primary.intf,
- urdc->secondary.intf);
- return (RDC_EADDTOIF);
- }
-
- rdc_group_log(krdc, RDC_FLUSH | RDC_ALLREMOTE, NULL);
-
- if (rdc_get_vflags(urdc) & RDC_SYNCING) {
- rdc_group_exit(krdc);
- spcs_s_add(kstatus, RDC_ESYNCING, urdc->primary.file);
- return (RDC_ESYNCING);
- }
-
- rdc_group_exit(krdc);
-
- return (0);
-}
-
-static int
-rdc_log(rdc_config_t *uparms, spcs_s_info_t kstatus)
-{
- rdc_k_info_t *krdc;
- int rc = 0;
- int index;
-
- mutex_enter(&rdc_conf_lock);
- index = rdc_lookup_byname(uparms->rdc_set);
- if (index >= 0)
- krdc = &rdc_k_info[index];
- if (index < 0 || (krdc->type_flag & RDC_DISABLEPEND)) {
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EALREADY, uparms->rdc_set->primary.file,
- uparms->rdc_set->secondary.file);
- return (RDC_EALREADY);
- }
-
- set_busy(krdc);
- if (krdc->type_flag == 0) {
- /* A resume or enable failed */
- wakeup_busy(krdc);
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EALREADY, uparms->rdc_set->primary.file,
- uparms->rdc_set->secondary.file);
- return (RDC_EALREADY);
- }
- mutex_exit(&rdc_conf_lock);
-
- rc = _rdc_log(krdc, uparms->rdc_set, kstatus);
-
- mutex_enter(&rdc_conf_lock);
- wakeup_busy(krdc);
- mutex_exit(&rdc_conf_lock);
-
- return (rc);
-}
-
-
-static int
-rdc_wait(rdc_config_t *uparms, spcs_s_info_t kstatus)
-{
- rdc_k_info_t *krdc;
- rdc_u_info_t *urdc;
- int index;
- int need_check = 0;
-
- mutex_enter(&rdc_conf_lock);
- index = rdc_lookup_byname(uparms->rdc_set);
- if (index >= 0)
- krdc = &rdc_k_info[index];
- if (index < 0 || (krdc->type_flag & RDC_DISABLEPEND)) {
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EALREADY, uparms->rdc_set->primary.file,
- uparms->rdc_set->secondary.file);
- return (RDC_EALREADY);
- }
-
- urdc = &rdc_u_info[index];
- if (!(rdc_get_vflags(urdc) & RDC_PRIMARY)) {
- mutex_exit(&rdc_conf_lock);
- return (0);
- }
-
- set_busy(krdc);
- if (krdc->type_flag == 0) {
- /* A resume or enable failed */
- wakeup_busy(krdc);
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EALREADY, uparms->rdc_set->primary.file,
- uparms->rdc_set->secondary.file);
- return (RDC_EALREADY);
- }
- mutex_exit(&rdc_conf_lock);
-
- rdc_group_enter(krdc);
- if (rdc_check(krdc, uparms->rdc_set)) {
- rdc_group_exit(krdc);
- mutex_enter(&rdc_conf_lock);
- wakeup_busy(krdc);
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EALREADY, uparms->rdc_set->primary.file,
- uparms->rdc_set->secondary.file);
- return (RDC_EALREADY);
- }
-
- if ((rdc_get_vflags(urdc) & (RDC_SYNCING | RDC_PRIMARY)) !=
- (RDC_SYNCING | RDC_PRIMARY)) {
- rdc_group_exit(krdc);
- mutex_enter(&rdc_conf_lock);
- wakeup_busy(krdc);
- mutex_exit(&rdc_conf_lock);
- return (0);
- }
- if (rdc_get_vflags(urdc) & RDC_SYNCING) {
- need_check = 1;
- }
- rdc_group_exit(krdc);
-
- mutex_enter(&net_blk_lock);
-
- mutex_enter(&rdc_conf_lock);
- wakeup_busy(krdc);
- mutex_exit(&rdc_conf_lock);
-
- (void) cv_wait_sig(&krdc->synccv, &net_blk_lock);
-
- mutex_exit(&net_blk_lock);
- if (need_check) {
- if (krdc->sync_done == RDC_COMPLETED) {
- return (0);
- } else if (krdc->sync_done == RDC_FAILED) {
- return (EIO);
- }
- }
- return (0);
-}
-
-
-static int
-rdc_health(rdc_config_t *uparms, spcs_s_info_t kstatus, int *rvp)
-{
- rdc_k_info_t *krdc;
- rdc_u_info_t *urdc;
- int rc = 0;
- int index;
-
- mutex_enter(&rdc_conf_lock);
- index = rdc_lookup_byname(uparms->rdc_set);
- if (index >= 0)
- krdc = &rdc_k_info[index];
- if (index < 0 || (krdc->type_flag & RDC_DISABLEPEND)) {
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EALREADY, uparms->rdc_set->primary.file,
- uparms->rdc_set->secondary.file);
- return (RDC_EALREADY);
- }
-
- set_busy(krdc);
- if (krdc->type_flag == 0) {
- /* A resume or enable failed */
- wakeup_busy(krdc);
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EALREADY, uparms->rdc_set->primary.file,
- uparms->rdc_set->secondary.file);
- return (RDC_EALREADY);
- }
-
- mutex_exit(&rdc_conf_lock);
-
- rdc_group_enter(krdc);
- if (rdc_check(krdc, uparms->rdc_set)) {
- rdc_group_exit(krdc);
- spcs_s_add(kstatus, RDC_EALREADY, uparms->rdc_set->primary.file,
- uparms->rdc_set->secondary.file);
- rc = RDC_EALREADY;
- goto done;
- }
-
- urdc = &rdc_u_info[index];
- if (rdc_isactive_if(&(urdc->primary.addr), &(urdc->secondary.addr)))
- *rvp = RDC_ACTIVE;
- else
- *rvp = RDC_INACTIVE;
-
- rdc_group_exit(krdc);
-
-done:
- mutex_enter(&rdc_conf_lock);
- wakeup_busy(krdc);
- mutex_exit(&rdc_conf_lock);
-
- return (rc);
-}
-
-
-static int
-rdc_reconfig(rdc_config_t *uparms, spcs_s_info_t kstatus)
-{
- rdc_k_info_t *krdc;
- rdc_u_info_t *urdc;
- int rc = -2;
- int index;
-
- mutex_enter(&rdc_conf_lock);
- index = rdc_lookup_byname(uparms->rdc_set);
- if (index >= 0)
- krdc = &rdc_k_info[index];
- if (index < 0 || (krdc->type_flag & RDC_DISABLEPEND)) {
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EALREADY, uparms->rdc_set->primary.file,
- uparms->rdc_set->secondary.file);
- return (RDC_EALREADY);
- }
-
- urdc = &rdc_u_info[index];
- set_busy(krdc);
- if (krdc->type_flag == 0) {
- /* A resume or enable failed */
- wakeup_busy(krdc);
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EALREADY, uparms->rdc_set->primary.file,
- uparms->rdc_set->secondary.file);
- return (RDC_EALREADY);
- }
-
- mutex_exit(&rdc_conf_lock);
-
- rdc_group_enter(krdc);
- if (rdc_check(krdc, uparms->rdc_set)) {
- rdc_group_exit(krdc);
- spcs_s_add(kstatus, RDC_EALREADY, uparms->rdc_set->primary.file,
- uparms->rdc_set->secondary.file);
- rc = RDC_EALREADY;
- goto done;
- }
- if ((rdc_get_vflags(urdc) & RDC_BMP_FAILED) && (krdc->bitmapfd))
- (void) rdc_reset_bitmap(krdc);
-
- /* Move to a new bitmap if necessary */
- if (strncmp(urdc->primary.bitmap, uparms->rdc_set->primary.bitmap,
- NSC_MAXPATH) != 0) {
- if (rdc_get_vflags(urdc) & RDC_PRIMARY) {
- rc = rdc_move_bitmap(krdc,
- uparms->rdc_set->primary.bitmap);
- } else {
- (void) strncpy(urdc->primary.bitmap,
- uparms->rdc_set->primary.bitmap, NSC_MAXPATH);
- /* simulate a succesful rdc_move_bitmap */
- rc = 0;
- }
- }
- if (strncmp(urdc->secondary.bitmap, uparms->rdc_set->secondary.bitmap,
- NSC_MAXPATH) != 0) {
- if (rdc_get_vflags(urdc) & RDC_PRIMARY) {
- (void) strncpy(urdc->secondary.bitmap,
- uparms->rdc_set->secondary.bitmap, NSC_MAXPATH);
- /* simulate a succesful rdc_move_bitmap */
- rc = 0;
- } else {
- rc = rdc_move_bitmap(krdc,
- uparms->rdc_set->secondary.bitmap);
- }
- }
- if (rc == -1) {
- rdc_group_exit(krdc);
- spcs_s_add(kstatus, RDC_EBMPRECONFIG,
- uparms->rdc_set->secondary.intf,
- uparms->rdc_set->secondary.file);
- rc = RDC_EBMPRECONFIG;
- goto done;
- }
-
- /*
- * At this point we fail any other type of reconfig
- * if not in logging mode and we did not do a bitmap reconfig
- */
-
- if (!(rdc_get_vflags(urdc) & RDC_LOGGING) && rc == -2) {
- /* no other changes possible unless logging */
- rdc_group_exit(krdc);
- spcs_s_add(kstatus, RDC_ENOTLOGGING,
- uparms->rdc_set->primary.intf,
- uparms->rdc_set->primary.file,
- uparms->rdc_set->secondary.intf,
- uparms->rdc_set->secondary.file);
- rc = RDC_ENOTLOGGING;
- goto done;
- }
- rc = 0;
- /* Change direct file if necessary */
- if ((rdc_get_vflags(urdc) & RDC_PRIMARY) &&
- strncmp(urdc->direct_file, uparms->rdc_set->direct_file,
- NSC_MAXPATH)) {
- if (!(rdc_get_vflags(urdc) & RDC_LOGGING)) {
- rdc_group_exit(krdc);
- goto notlogging;
- }
- rdc_close_direct(krdc);
- (void) strncpy(urdc->direct_file, uparms->rdc_set->direct_file,
- NSC_MAXPATH);
-
- if (urdc->direct_file[0]) {
- if (rdc_open_direct(krdc) == NULL)
- rdc_set_flags(urdc, RDC_FCAL_FAILED);
- else
- rdc_clr_flags(urdc, RDC_FCAL_FAILED);
- }
- }
-
- rdc_group_exit(krdc);
-
- /* Change group if necessary */
- if (strncmp(urdc->group_name, uparms->rdc_set->group_name,
- NSC_MAXPATH) != 0) {
- char orig_group[NSC_MAXPATH];
- if (!(rdc_get_vflags(urdc) & RDC_LOGGING))
- goto notlogging;
- mutex_enter(&rdc_conf_lock);
-
- (void) strncpy(orig_group, urdc->group_name, NSC_MAXPATH);
- (void) strncpy(urdc->group_name, uparms->rdc_set->group_name,
- NSC_MAXPATH);
-
- rc = change_group(krdc, uparms->options);
- if (rc == RDC_EQNOADD) {
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EQNOADD,
- uparms->rdc_set->disk_queue);
- goto done;
- } else if (rc < 0) {
- (void) strncpy(urdc->group_name, orig_group,
- NSC_MAXPATH);
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EGROUP,
- urdc->primary.intf, urdc->primary.file,
- urdc->secondary.intf, urdc->secondary.file,
- uparms->rdc_set->group_name);
- rc = RDC_EGROUP;
- goto done;
- }
-
- mutex_exit(&rdc_conf_lock);
-
- if (rc >= 0) {
- if (!(rdc_get_vflags(urdc) & RDC_LOGGING))
- goto notlogging;
- if (uparms->options & RDC_OPT_ASYNC) {
- mutex_enter(&rdc_conf_lock);
- krdc->type_flag |= RDC_ASYNCMODE;
- mutex_exit(&rdc_conf_lock);
- if (uparms->options & RDC_OPT_PRIMARY)
- krdc->bitmap_ref =
- (uchar_t *)kmem_zalloc(
- (krdc->bitmap_size * BITS_IN_BYTE *
- BMAP_REF_PREF_SIZE), KM_SLEEP);
- rdc_group_enter(krdc);
- rdc_set_flags(urdc, RDC_ASYNC);
- rdc_group_exit(krdc);
- } else {
- mutex_enter(&rdc_conf_lock);
- krdc->type_flag &= ~RDC_ASYNCMODE;
- mutex_exit(&rdc_conf_lock);
- rdc_group_enter(krdc);
- rdc_clr_flags(urdc, RDC_ASYNC);
- rdc_group_exit(krdc);
- if (krdc->bitmap_ref) {
- kmem_free(krdc->bitmap_ref,
- (krdc->bitmap_size * BITS_IN_BYTE *
- BMAP_REF_PREF_SIZE));
- krdc->bitmap_ref = NULL;
- }
- }
- }
- } else {
- if ((((uparms->options & RDC_OPT_ASYNC) == 0) &&
- ((krdc->type_flag & RDC_ASYNCMODE) != 0)) ||
- (((uparms->options & RDC_OPT_ASYNC) != 0) &&
- ((krdc->type_flag & RDC_ASYNCMODE) == 0))) {
- if (!(rdc_get_vflags(urdc) & RDC_LOGGING))
- goto notlogging;
-
- if (krdc->group->count > 1) {
- spcs_s_add(kstatus, RDC_EGROUPMODE);
- rc = RDC_EGROUPMODE;
- goto done;
- }
- }
-
- /* Switch sync/async if necessary */
- if (krdc->group->count == 1) {
- /* Only member of group. Can change sync/async */
- if (((uparms->options & RDC_OPT_ASYNC) == 0) &&
- ((krdc->type_flag & RDC_ASYNCMODE) != 0)) {
- if (!(rdc_get_vflags(urdc) & RDC_LOGGING))
- goto notlogging;
- /* switch to sync */
- mutex_enter(&rdc_conf_lock);
- krdc->type_flag &= ~RDC_ASYNCMODE;
- if (RDC_IS_DISKQ(krdc->group)) {
- krdc->group->flags &= ~RDC_DISKQUE;
- krdc->group->flags |= RDC_MEMQUE;
- rdc_unintercept_diskq(krdc->group);
- mutex_enter(&krdc->group->diskqmutex);
- rdc_close_diskq(krdc->group);
- mutex_exit(&krdc->group->diskqmutex);
- bzero(&urdc->disk_queue,
- sizeof (urdc->disk_queue));
- }
- mutex_exit(&rdc_conf_lock);
- rdc_group_enter(krdc);
- rdc_clr_flags(urdc, RDC_ASYNC);
- rdc_group_exit(krdc);
- if (krdc->bitmap_ref) {
- kmem_free(krdc->bitmap_ref,
- (krdc->bitmap_size * BITS_IN_BYTE *
- BMAP_REF_PREF_SIZE));
- krdc->bitmap_ref = NULL;
- }
- } else if (((uparms->options & RDC_OPT_ASYNC) != 0) &&
- ((krdc->type_flag & RDC_ASYNCMODE) == 0)) {
- if (!(rdc_get_vflags(urdc) & RDC_LOGGING))
- goto notlogging;
- /* switch to async */
- mutex_enter(&rdc_conf_lock);
- krdc->type_flag |= RDC_ASYNCMODE;
- mutex_exit(&rdc_conf_lock);
- if (uparms->options & RDC_OPT_PRIMARY)
- krdc->bitmap_ref =
- (uchar_t *)kmem_zalloc(
- (krdc->bitmap_size * BITS_IN_BYTE *
- BMAP_REF_PREF_SIZE), KM_SLEEP);
- rdc_group_enter(krdc);
- rdc_set_flags(urdc, RDC_ASYNC);
- rdc_group_exit(krdc);
- }
- }
- }
- /* Reverse concept of primary and secondary */
- if ((uparms->options & RDC_OPT_REVERSE_ROLE) != 0) {
- rdc_set_t rdc_set;
- struct netbuf paddr, saddr;
-
- mutex_enter(&rdc_conf_lock);
-
- /*
- * Disallow role reversal for advanced configurations
- */
-
- if (IS_MANY(krdc) || IS_MULTI(krdc)) {
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EMASTER, urdc->primary.intf,
- urdc->primary.file, urdc->secondary.intf,
- urdc->secondary.file);
- return (RDC_EMASTER);
- }
- bzero((void *) &rdc_set, sizeof (rdc_set_t));
- dup_rdc_netbuf(&urdc->primary.addr, &saddr);
- dup_rdc_netbuf(&urdc->secondary.addr, &paddr);
- free_rdc_netbuf(&urdc->primary.addr);
- free_rdc_netbuf(&urdc->secondary.addr);
- dup_rdc_netbuf(&saddr, &urdc->secondary.addr);
- dup_rdc_netbuf(&paddr, &urdc->primary.addr);
- free_rdc_netbuf(&paddr);
- free_rdc_netbuf(&saddr);
- /* copy primary parts of urdc to rdc_set field by field */
- (void) strncpy(rdc_set.primary.intf, urdc->primary.intf,
- MAX_RDC_HOST_SIZE);
- (void) strncpy(rdc_set.primary.file, urdc->primary.file,
- NSC_MAXPATH);
- (void) strncpy(rdc_set.primary.bitmap, urdc->primary.bitmap,
- NSC_MAXPATH);
-
- /* Now overwrite urdc primary */
- (void) strncpy(urdc->primary.intf, urdc->secondary.intf,
- MAX_RDC_HOST_SIZE);
- (void) strncpy(urdc->primary.file, urdc->secondary.file,
- NSC_MAXPATH);
- (void) strncpy(urdc->primary.bitmap, urdc->secondary.bitmap,
- NSC_MAXPATH);
-
- /* Now ovwewrite urdc secondary */
- (void) strncpy(urdc->secondary.intf, rdc_set.primary.intf,
- MAX_RDC_HOST_SIZE);
- (void) strncpy(urdc->secondary.file, rdc_set.primary.file,
- NSC_MAXPATH);
- (void) strncpy(urdc->secondary.bitmap, rdc_set.primary.bitmap,
- NSC_MAXPATH);
-
- if (rdc_get_vflags(urdc) & RDC_PRIMARY) {
- rdc_clr_flags(urdc, RDC_PRIMARY);
- if (krdc->intf) {
- krdc->intf->issecondary = 1;
- krdc->intf->isprimary = 0;
- krdc->intf->if_down = 1;
- }
- } else {
- rdc_set_flags(urdc, RDC_PRIMARY);
- if (krdc->intf) {
- krdc->intf->issecondary = 0;
- krdc->intf->isprimary = 1;
- krdc->intf->if_down = 1;
- }
- }
-
- if ((rdc_get_vflags(urdc) & RDC_PRIMARY) &&
- ((krdc->type_flag & RDC_ASYNCMODE) != 0)) {
- if (!krdc->bitmap_ref)
- krdc->bitmap_ref =
- (uchar_t *)kmem_zalloc((krdc->bitmap_size *
- BITS_IN_BYTE * BMAP_REF_PREF_SIZE),
- KM_SLEEP);
- if (krdc->bitmap_ref == NULL) {
- cmn_err(CE_WARN,
- "!rdc_reconfig: bitmap_ref alloc %"
- NSC_SZFMT " failed",
- krdc->bitmap_size * BITS_IN_BYTE *
- BMAP_REF_PREF_SIZE);
- mutex_exit(&rdc_conf_lock);
- return (-1);
- }
- }
-
- if ((rdc_get_vflags(urdc) & RDC_PRIMARY) &&
- (rdc_get_vflags(urdc) & RDC_SYNC_NEEDED)) {
- /* Primary, so reverse sync needed */
- rdc_many_enter(krdc);
- rdc_clr_flags(urdc, RDC_SYNC_NEEDED);
- rdc_set_mflags(urdc, RDC_RSYNC_NEEDED);
- rdc_many_exit(krdc);
- } else if (rdc_get_vflags(urdc) & RDC_RSYNC_NEEDED) {
- /* Secondary, so forward sync needed */
- rdc_many_enter(krdc);
- rdc_clr_flags(urdc, RDC_RSYNC_NEEDED);
- rdc_set_flags(urdc, RDC_SYNC_NEEDED);
- rdc_many_exit(krdc);
- }
-
- /*
- * rewrite bitmap header
- */
- rdc_write_state(urdc);
- mutex_exit(&rdc_conf_lock);
- }
-
-done:
- mutex_enter(&rdc_conf_lock);
- wakeup_busy(krdc);
- mutex_exit(&rdc_conf_lock);
-
- return (rc);
-
-notlogging:
- /* no other changes possible unless logging */
- mutex_enter(&rdc_conf_lock);
- wakeup_busy(krdc);
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_ENOTLOGGING, urdc->primary.intf,
- urdc->primary.file, urdc->secondary.intf,
- urdc->secondary.file);
- return (RDC_ENOTLOGGING);
-}
-
-static int
-rdc_reset(rdc_config_t *uparms, spcs_s_info_t kstatus)
-{
- rdc_k_info_t *krdc;
- rdc_u_info_t *urdc;
- int rc = 0;
- int index;
- int cleared_error = 0;
-
- mutex_enter(&rdc_conf_lock);
- index = rdc_lookup_byname(uparms->rdc_set);
- if (index >= 0)
- krdc = &rdc_k_info[index];
- if (index < 0 || (krdc->type_flag & RDC_DISABLEPEND)) {
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EALREADY, uparms->rdc_set->primary.file,
- uparms->rdc_set->secondary.file);
- return (RDC_EALREADY);
- }
-
- urdc = &rdc_u_info[index];
- set_busy(krdc);
- if (krdc->type_flag == 0) {
- /* A resume or enable failed */
- wakeup_busy(krdc);
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EALREADY, uparms->rdc_set->primary.file,
- uparms->rdc_set->secondary.file);
- return (RDC_EALREADY);
- }
-
- mutex_exit(&rdc_conf_lock);
-
- rdc_group_enter(krdc);
- if (rdc_check(krdc, uparms->rdc_set)) {
- spcs_s_add(kstatus, RDC_EALREADY, uparms->rdc_set->primary.file,
- uparms->rdc_set->secondary.file);
- rc = RDC_EALREADY;
- goto done;
- }
-
- if ((rdc_get_vflags(urdc) & RDC_BMP_FAILED) && (krdc->bitmapfd)) {
- if (rdc_reset_bitmap(krdc) == 0)
- cleared_error++;
- }
-
- /* Fix direct file if necessary */
- if ((rdc_get_vflags(urdc) & RDC_PRIMARY) && urdc->direct_file[0]) {
- if (rdc_open_direct(krdc) == NULL)
- rdc_set_flags(urdc, RDC_FCAL_FAILED);
- else {
- rdc_clr_flags(urdc, RDC_FCAL_FAILED);
- cleared_error++;
- }
- }
-
- if ((rdc_get_vflags(urdc) & RDC_VOL_FAILED)) {
- rdc_many_enter(krdc);
- rdc_clr_flags(urdc, RDC_VOL_FAILED);
- cleared_error++;
- rdc_many_exit(krdc);
- }
-
- if (cleared_error) {
- /* cleared an error so we should be in logging mode */
- rdc_set_flags_log(urdc, RDC_LOGGING, "set reset");
- }
- rdc_group_exit(krdc);
-
- if ((rdc_get_vflags(urdc) & RDC_DISKQ_FAILED))
- rdc_unfail_diskq(krdc);
-
-done:
- mutex_enter(&rdc_conf_lock);
- wakeup_busy(krdc);
- mutex_exit(&rdc_conf_lock);
-
- return (rc);
-}
-
-
-static int
-rdc_tunable(rdc_config_t *uparms, spcs_s_info_t kstatus)
-{
- rdc_k_info_t *krdc;
- rdc_u_info_t *urdc;
- rdc_k_info_t *p;
- rdc_u_info_t *q;
- int rc = 0;
- int index;
-
- mutex_enter(&rdc_conf_lock);
- index = rdc_lookup_byname(uparms->rdc_set);
- if (index >= 0)
- krdc = &rdc_k_info[index];
- if (index < 0 || (krdc->type_flag & RDC_DISABLEPEND)) {
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EALREADY, uparms->rdc_set->primary.file,
- uparms->rdc_set->secondary.file);
- return (RDC_EALREADY);
- }
-
- urdc = &rdc_u_info[index];
- set_busy(krdc);
- if (krdc->type_flag == 0) {
- /* A resume or enable failed */
- wakeup_busy(krdc);
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EALREADY, uparms->rdc_set->primary.file,
- uparms->rdc_set->secondary.file);
- return (RDC_EALREADY);
- }
-
- mutex_exit(&rdc_conf_lock);
-
- rdc_group_enter(krdc);
- if (rdc_check(krdc, uparms->rdc_set)) {
- spcs_s_add(kstatus, RDC_EALREADY, uparms->rdc_set->primary.file,
- uparms->rdc_set->secondary.file);
- rc = RDC_EALREADY;
- goto done;
- }
-
- if (uparms->rdc_set->maxqfbas > 0) {
- urdc->maxqfbas = uparms->rdc_set->maxqfbas;
- rdc_write_state(urdc);
- for (p = krdc->group_next; p != krdc; p = p->group_next) {
- q = &rdc_u_info[p->index];
- q->maxqfbas = urdc->maxqfbas;
- rdc_write_state(q);
- }
- }
-
- if (uparms->rdc_set->maxqitems > 0) {
- urdc->maxqitems = uparms->rdc_set->maxqitems;
- rdc_write_state(urdc);
- for (p = krdc->group_next; p != krdc; p = p->group_next) {
- q = &rdc_u_info[p->index];
- q->maxqitems = urdc->maxqitems;
- rdc_write_state(q);
- }
- }
-
- if (uparms->options & RDC_OPT_SET_QNOBLOCK) {
- disk_queue *que;
-
- if (!RDC_IS_DISKQ(krdc->group)) {
- spcs_s_add(kstatus, RDC_EQNOQUEUE, urdc->primary.intf,
- urdc->primary.file, urdc->secondary.intf,
- urdc->secondary.file);
- rc = RDC_EQNOQUEUE;
- goto done;
- }
-
- que = &krdc->group->diskq;
- mutex_enter(QLOCK(que));
- SET_QSTATE(que, RDC_QNOBLOCK);
- /* queue will fail if this fails */
- (void) rdc_stamp_diskq(krdc, 0, RDC_GROUP_LOCKED);
- mutex_exit(QLOCK(que));
-
- }
-
- if (uparms->options & RDC_OPT_CLR_QNOBLOCK) {
- disk_queue *que;
-
- if (!RDC_IS_DISKQ(krdc->group)) {
- spcs_s_add(kstatus, RDC_EQNOQUEUE, urdc->primary.intf,
- urdc->primary.file, urdc->secondary.intf,
- urdc->secondary.file);
- rc = RDC_EQNOQUEUE;
- goto done;
- }
- que = &krdc->group->diskq;
- mutex_enter(QLOCK(que));
- CLR_QSTATE(que, RDC_QNOBLOCK);
- /* queue will fail if this fails */
- (void) rdc_stamp_diskq(krdc, 0, RDC_GROUP_LOCKED);
- mutex_exit(QLOCK(que));
-
- }
- if (uparms->rdc_set->asyncthr > 0) {
- urdc->asyncthr = uparms->rdc_set->asyncthr;
- rdc_write_state(urdc);
- for (p = krdc->group_next; p != krdc; p = p->group_next) {
- q = &rdc_u_info[p->index];
- q->asyncthr = urdc->asyncthr;
- rdc_write_state(q);
- }
- }
-
- if (uparms->rdc_set->autosync >= 0) {
- if (uparms->rdc_set->autosync == 0)
- urdc->autosync = 0;
- else
- urdc->autosync = 1;
-
- rdc_write_state(urdc);
-
- /* Changed autosync, so update rest of the group */
-
- for (p = krdc->group_next; p != krdc; p = p->group_next) {
- q = &rdc_u_info[p->index];
- q->autosync = urdc->autosync;
- rdc_write_state(q);
- }
- }
-
-done:
- rdc_group_exit(krdc);
-
- mutex_enter(&rdc_conf_lock);
- wakeup_busy(krdc);
- mutex_exit(&rdc_conf_lock);
-
- return (rc);
-}
-
-static int
-rdc_status(void *arg, int mode, rdc_config_t *uparms, spcs_s_info_t kstatus)
-{
- rdc_k_info_t *krdc;
- rdc_u_info_t *urdc;
- disk_queue *dqp;
- int rc = 0;
- int index;
- char *ptr;
- extern int rdc_status_copy32(const void *, void *, size_t, int);
-
- mutex_enter(&rdc_conf_lock);
- index = rdc_lookup_byname(uparms->rdc_set);
- if (index >= 0)
- krdc = &rdc_k_info[index];
- if (index < 0 || (krdc->type_flag & RDC_DISABLEPEND)) {
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EALREADY, uparms->rdc_set->primary.file,
- uparms->rdc_set->secondary.file);
- return (RDC_EALREADY);
- }
-
- set_busy(krdc);
- if (krdc->type_flag == 0) {
- /* A resume or enable failed */
- wakeup_busy(krdc);
- mutex_exit(&rdc_conf_lock);
- spcs_s_add(kstatus, RDC_EALREADY, uparms->rdc_set->primary.file,
- uparms->rdc_set->secondary.file);
- return (RDC_EALREADY);
- }
-
- mutex_exit(&rdc_conf_lock);
-
- rdc_group_enter(krdc);
- if (rdc_check(krdc, uparms->rdc_set)) {
- rdc_group_exit(krdc);
- spcs_s_add(kstatus, RDC_EALREADY, uparms->rdc_set->primary.file,
- uparms->rdc_set->secondary.file);
- rc = RDC_EALREADY;
- goto done;
- }
-
- urdc = &rdc_u_info[index];
-
- /*
- * sneak out qstate in urdc->flags
- * this is harmless because it's value is not used
- * in urdc->flags. the real qstate is kept in
- * group->diskq->disk_hdr.h.state
- */
- if (RDC_IS_DISKQ(krdc->group)) {
- dqp = &krdc->group->diskq;
- if (IS_QSTATE(dqp, RDC_QNOBLOCK))
- urdc->flags |= RDC_QNOBLOCK;
- }
-
- if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
- ptr = (char *)arg + offsetof(struct rdc_config32, rdc_set);
- rc = rdc_status_copy32(urdc, ptr, sizeof (struct rdc_set32),
- mode);
- } else {
- ptr = (char *)arg + offsetof(struct rdc_config, rdc_set);
- rc = ddi_copyout(urdc, ptr, sizeof (struct rdc_set), mode);
- }
- /* clear out qstate from flags */
- urdc->flags &= ~RDC_QNOBLOCK;
-
- if (rc)
- rc = EFAULT;
-
- rdc_group_exit(krdc);
-done:
- mutex_enter(&rdc_conf_lock);
- wakeup_busy(krdc);
- mutex_exit(&rdc_conf_lock);
-
- return (rc);
-}
-
-/*
- * Overwrite the bitmap with one supplied by the
- * user.
- * Copy into all bitmaps that are tracking this volume.
- */
-
-int
-rdc_bitmapset(int op, char *sechost, char *secdev, void *bmapaddr, int bmapsz,
- nsc_off_t off, int mode)
-{
- int rc;
- rdc_k_info_t *krdc;
- int *indexvec;
- int index;
- int indexit;
- kmutex_t **grouplocks;
- int i;
- int groupind;
-
- if (off % FBA_SIZE(1)) {
- /* Must be modulo FBA */
- cmn_err(CE_WARN, "!bitmapset: Offset is not on an FBA "
- "boundary %llu", (unsigned long long)off);
- return (EINVAL);
- }
- if (bmapsz % FBA_SIZE(1)) {
- /* Must be modulo FBA */
- cmn_err(CE_WARN, "!bitmapset: Size is not on an FBA "
- "boundary %d", bmapsz);
- return (EINVAL);
- }
-
- mutex_enter(&rdc_conf_lock);
- index = rdc_lookup_byhostdev(sechost, secdev);
- if (index >= 0) {
- krdc = &rdc_k_info[index];
- }
- if (index < 0 || (krdc->type_flag & RDC_DISABLEPEND)) {
- rc = ENODEV;
- mutex_exit(&rdc_conf_lock);
- return (rc);
- }
- indexvec = kmem_alloc(rdc_max_sets * sizeof (int), KM_SLEEP);
- grouplocks = kmem_alloc(rdc_max_sets * sizeof (kmutex_t *), KM_SLEEP);
-
- /*
- * I now have this set, and I want to take the group
- * lock on it, and all the group locks of all the
- * sets on the many and multi-hop links.
- * I have to take the many lock while traversing the
- * many/multi links.
- * I think I also need to set the busy count on this
- * set, otherwise when I drop the conf_lock, what
- * will stop some other process from coming in and
- * issuing a disable?
- */
- set_busy(krdc);
- mutex_exit(&rdc_conf_lock);
-
-retrylock:
- groupind = 0;
- indexit = 0;
- rdc_many_enter(krdc);
- /*
- * Take this initial sets group lock first.
- */
- if (!mutex_tryenter(&krdc->group->lock)) {
- rdc_many_exit(krdc);
- goto retrylock;
- }
-
- grouplocks[groupind] = &krdc->group->lock;
- groupind++;
-
- rc = rdc_checkforbitmap(index, off + bmapsz);
- if (rc) {
- goto done;
- }
- indexvec[indexit] = index;
- indexit++;
- if (IS_MANY(krdc)) {
- rdc_k_info_t *ktmp;
-
- for (ktmp = krdc->many_next; ktmp != krdc;
- ktmp = ktmp->many_next) {
- /*
- * attempt to take the group lock,
- * if we don't already have it.
- */
- if (ktmp->group == NULL) {
- rc = ENODEV;
- goto done;
- }
- for (i = 0; i < groupind; i++) {
- if (grouplocks[i] == &ktmp->group->lock)
- /* already have the group lock */
- break;
- }
- /*
- * didn't find our lock in our collection,
- * attempt to take group lock.
- */
- if (i >= groupind) {
- if (!mutex_tryenter(&ktmp->group->lock)) {
- for (i = 0; i < groupind; i++) {
- mutex_exit(grouplocks[i]);
- }
- rdc_many_exit(krdc);
- goto retrylock;
- }
- grouplocks[groupind] = &ktmp->group->lock;
- groupind++;
- }
- rc = rdc_checkforbitmap(ktmp->index, off + bmapsz);
- if (rc == 0) {
- indexvec[indexit] = ktmp->index;
- indexit++;
- } else {
- goto done;
- }
- }
- }
- if (IS_MULTI(krdc)) {
- rdc_k_info_t *kmulti = krdc->multi_next;
-
- if (kmulti->group == NULL) {
- rc = ENODEV;
- goto done;
- }
- /*
- * This can't be in our group already.
- */
- if (!mutex_tryenter(&kmulti->group->lock)) {
- for (i = 0; i < groupind; i++) {
- mutex_exit(grouplocks[i]);
- }
- rdc_many_exit(krdc);
- goto retrylock;
- }
- grouplocks[groupind] = &kmulti->group->lock;
- groupind++;
-
- rc = rdc_checkforbitmap(kmulti->index, off + bmapsz);
- if (rc == 0) {
- indexvec[indexit] = kmulti->index;
- indexit++;
- } else {
- goto done;
- }
- }
- rc = rdc_installbitmap(op, bmapaddr, bmapsz, off, mode, indexvec,
- indexit);
-done:
- for (i = 0; i < groupind; i++) {
- mutex_exit(grouplocks[i]);
- }
- rdc_many_exit(krdc);
- mutex_enter(&rdc_conf_lock);
- wakeup_busy(krdc);
- mutex_exit(&rdc_conf_lock);
- kmem_free(indexvec, rdc_max_sets * sizeof (int));
- kmem_free(grouplocks, rdc_max_sets * sizeof (kmutex_t *));
- return (rc);
-}
-
-static int
-rdc_checkforbitmap(int index, nsc_off_t limit)
-{
- rdc_k_info_t *krdc;
- rdc_u_info_t *urdc;
-
- krdc = &rdc_k_info[index];
- urdc = &rdc_u_info[index];
-
- if (!IS_ENABLED(urdc)) {
- return (EIO);
- }
- if (!(rdc_get_vflags(urdc) & RDC_LOGGING)) {
- return (ENXIO);
- }
- if (krdc->dcio_bitmap == NULL) {
- cmn_err(CE_WARN, "!checkforbitmap: No bitmap for set (%s:%s)",
- urdc->secondary.intf, urdc->secondary.file);
- return (ENOENT);
- }
- if (limit > krdc->bitmap_size) {
- cmn_err(CE_WARN, "!checkbitmap: Bitmap exceeded, "
- "incore %" NSC_SZFMT " user supplied %" NSC_SZFMT
- " for set (%s:%s)", krdc->bitmap_size,
- limit, urdc->secondary.intf, urdc->secondary.file);
- return (ENOSPC);
- }
- return (0);
-}
-
-
-
-/*
- * Copy the user supplied bitmap to this set.
- */
-static int
-rdc_installbitmap(int op, void *bmapaddr, int bmapsz,
- nsc_off_t off, int mode, int *vec, int veccnt)
-{
- int rc;
- nsc_off_t sfba;
- nsc_off_t efba;
- nsc_off_t fba;
- void *ormem = NULL;
- int len;
- int left;
- int copied;
- int index;
- rdc_k_info_t *krdc;
- rdc_u_info_t *urdc;
-
- rc = 0;
- ormem = kmem_alloc(RDC_MAXDATA, KM_SLEEP);
- left = bmapsz;
- copied = 0;
- while (left > 0) {
- if (left > RDC_MAXDATA) {
- len = RDC_MAXDATA;
- } else {
- len = left;
- }
- if (ddi_copyin((char *)bmapaddr + copied, ormem,
- len, mode)) {
- cmn_err(CE_WARN, "!installbitmap: Copyin failed");
- rc = EFAULT;
- goto out;
- }
- sfba = FBA_NUM(off + copied);
- efba = FBA_NUM(off + copied + len);
- for (index = 0; index < veccnt; index++) {
- krdc = &rdc_k_info[vec[index]];
- urdc = &rdc_u_info[vec[index]];
-
- mutex_enter(&krdc->bmapmutex);
- if (op == RDC_BITMAPSET) {
- bcopy(ormem, krdc->dcio_bitmap + off + copied,
- len);
- } else {
- rdc_lor(ormem,
- krdc->dcio_bitmap + off + copied, len);
- }
- /*
- * Maybe this should be just done once outside of
- * the the loop? (Less work, but leaves a window
- * where the bits_set doesn't match the bitmap).
- */
- urdc->bits_set = RDC_COUNT_BITMAP(krdc);
- mutex_exit(&krdc->bmapmutex);
- if (krdc->bitmap_write > 0) {
- for (fba = sfba; fba < efba; fba++) {
- if (rc = rdc_write_bitmap_fba(krdc,
- fba)) {
-
- cmn_err(CE_WARN,
- "!installbitmap: "
- "write_bitmap_fba failed "
- "on fba number %" NSC_SZFMT
- " set %s:%s", fba,
- urdc->secondary.intf,
- urdc->secondary.file);
- goto out;
- }
- }
- }
- }
- copied += len;
- left -= len;
- }
-out:
- kmem_free(ormem, RDC_MAXDATA);
- return (rc);
-}
-
-/*
- * _rdc_config
- */
-int
-_rdc_config(void *arg, int mode, spcs_s_info_t kstatus, int *rvp)
-{
- int rc = 0;
- struct netbuf fsvaddr, tsvaddr;
- struct knetconfig *knconf;
- char *p = NULL, *pf = NULL;
- struct rdc_config *uap;
- STRUCT_DECL(knetconfig, knconf_tmp);
- STRUCT_DECL(rdc_config, uparms);
- int enable, disable;
- int cmd;
-
-
- STRUCT_HANDLE(rdc_set, rs);
- STRUCT_HANDLE(rdc_addr, pa);
- STRUCT_HANDLE(rdc_addr, sa);
-
- STRUCT_INIT(uparms, mode);
-
- bzero(STRUCT_BUF(uparms), STRUCT_SIZE(uparms));
- bzero(&fsvaddr, sizeof (fsvaddr));
- bzero(&tsvaddr, sizeof (tsvaddr));
-
- knconf = NULL;
-
- if (ddi_copyin(arg, STRUCT_BUF(uparms), STRUCT_SIZE(uparms), mode)) {
- return (EFAULT);
- }
-
- STRUCT_SET_HANDLE(rs, mode, STRUCT_FGETP(uparms, rdc_set));
- STRUCT_SET_HANDLE(pa, mode, STRUCT_FADDR(rs, primary));
- STRUCT_SET_HANDLE(sa, mode, STRUCT_FADDR(rs, secondary));
- cmd = STRUCT_FGET(uparms, command);
- if (cmd == RDC_CMD_ENABLE || cmd == RDC_CMD_RESUME) {
- fsvaddr.len = STRUCT_FGET(pa, addr.len);
- fsvaddr.maxlen = STRUCT_FGET(pa, addr.maxlen);
- fsvaddr.buf = kmem_zalloc(fsvaddr.len, KM_SLEEP);
-
- if (ddi_copyin(STRUCT_FGETP(pa, addr.buf),
- fsvaddr.buf, fsvaddr.len, mode)) {
- kmem_free(fsvaddr.buf, fsvaddr.len);
-#ifdef DEBUG
- cmn_err(CE_WARN, "!copyin failed primary.addr 2");
-#endif
- return (EFAULT);
- }
-
-
- tsvaddr.len = STRUCT_FGET(sa, addr.len);
- tsvaddr.maxlen = STRUCT_FGET(sa, addr.maxlen);
- tsvaddr.buf = kmem_zalloc(tsvaddr.len, KM_SLEEP);
-
- if (ddi_copyin(STRUCT_FGETP(sa, addr.buf),
- tsvaddr.buf, tsvaddr.len, mode)) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!copyin failed secondary addr");
-#endif
- kmem_free(fsvaddr.buf, fsvaddr.len);
- kmem_free(tsvaddr.buf, tsvaddr.len);
- return (EFAULT);
- }
- } else {
- fsvaddr.len = 0;
- fsvaddr.maxlen = 0;
- fsvaddr.buf = kmem_zalloc(fsvaddr.len, KM_SLEEP);
- tsvaddr.len = 0;
- tsvaddr.maxlen = 0;
- tsvaddr.buf = kmem_zalloc(tsvaddr.len, KM_SLEEP);
- }
-
- if (STRUCT_FGETP(uparms, rdc_set->netconfig) != NULL) {
- STRUCT_INIT(knconf_tmp, mode);
- knconf = kmem_zalloc(sizeof (*knconf), KM_SLEEP);
- if (ddi_copyin(STRUCT_FGETP(uparms, rdc_set->netconfig),
- STRUCT_BUF(knconf_tmp), STRUCT_SIZE(knconf_tmp), mode)) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!copyin failed netconfig");
-#endif
- kmem_free(fsvaddr.buf, fsvaddr.len);
- kmem_free(tsvaddr.buf, tsvaddr.len);
- kmem_free(knconf, sizeof (*knconf));
- return (EFAULT);
- }
-
- knconf->knc_semantics = STRUCT_FGET(knconf_tmp, knc_semantics);
- knconf->knc_protofmly = STRUCT_FGETP(knconf_tmp, knc_protofmly);
- knconf->knc_proto = STRUCT_FGETP(knconf_tmp, knc_proto);
-
-#ifndef _SunOS_5_6
- if ((mode & DATAMODEL_LP64) == 0) {
- knconf->knc_rdev =
- expldev(STRUCT_FGET(knconf_tmp, knc_rdev));
- } else {
-#endif
- knconf->knc_rdev = STRUCT_FGET(knconf_tmp, knc_rdev);
-#ifndef _SunOS_5_6
- }
-#endif
-
- pf = kmem_alloc(KNC_STRSIZE, KM_SLEEP);
- p = kmem_alloc(KNC_STRSIZE, KM_SLEEP);
- rc = ddi_copyin(knconf->knc_protofmly, pf, KNC_STRSIZE, mode);
- if (rc) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!copyin failed parms protofmly");
-#endif
- rc = EFAULT;
- goto out;
- }
- rc = ddi_copyin(knconf->knc_proto, p, KNC_STRSIZE, mode);
- if (rc) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!copyin failed parms proto");
-#endif
- rc = EFAULT;
- goto out;
- }
- knconf->knc_protofmly = pf;
- knconf->knc_proto = p;
- } /* !NULL netconfig */
-
- uap = kmem_alloc(sizeof (*uap), KM_SLEEP);
-
- /* copy relevant parts of rdc_config to uap field by field */
-
- (void) strncpy(uap->rdc_set[0].primary.intf, STRUCT_FGETP(pa, intf),
- MAX_RDC_HOST_SIZE);
- (void) strncpy(uap->rdc_set[0].primary.file, STRUCT_FGETP(pa, file),
- NSC_MAXPATH);
- (void) strncpy(uap->rdc_set[0].primary.bitmap, STRUCT_FGETP(pa, bitmap),
- NSC_MAXPATH);
- uap->rdc_set[0].netconfig = knconf;
- uap->rdc_set[0].flags = STRUCT_FGET(uparms, rdc_set->flags);
- uap->rdc_set[0].index = STRUCT_FGET(uparms, rdc_set->index);
- uap->rdc_set[0].setid = STRUCT_FGET(uparms, rdc_set->setid);
- uap->rdc_set[0].sync_pos = STRUCT_FGET(uparms, rdc_set->sync_pos);
- uap->rdc_set[0].volume_size = STRUCT_FGET(uparms, rdc_set->volume_size);
- uap->rdc_set[0].bits_set = STRUCT_FGET(uparms, rdc_set->bits_set);
- uap->rdc_set[0].autosync = STRUCT_FGET(uparms, rdc_set->autosync);
- uap->rdc_set[0].maxqfbas = STRUCT_FGET(uparms, rdc_set->maxqfbas);
- uap->rdc_set[0].maxqitems = STRUCT_FGET(uparms, rdc_set->maxqitems);
- uap->rdc_set[0].asyncthr = STRUCT_FGET(uparms, rdc_set->asyncthr);
- uap->rdc_set[0].syshostid = STRUCT_FGET(uparms, rdc_set->syshostid);
- uap->rdc_set[0].primary.addr = fsvaddr; /* struct copy */
- uap->rdc_set[0].secondary.addr = tsvaddr; /* struct copy */
-
- (void) strncpy(uap->rdc_set[0].secondary.intf, STRUCT_FGETP(sa, intf),
- MAX_RDC_HOST_SIZE);
- (void) strncpy(uap->rdc_set[0].secondary.file, STRUCT_FGETP(sa, file),
- NSC_MAXPATH);
- (void) strncpy(uap->rdc_set[0].secondary.bitmap,
- STRUCT_FGETP(sa, bitmap), NSC_MAXPATH);
-
- (void) strncpy(uap->rdc_set[0].direct_file,
- STRUCT_FGETP(rs, direct_file), NSC_MAXPATH);
-
- (void) strncpy(uap->rdc_set[0].group_name, STRUCT_FGETP(rs, group_name),
- NSC_MAXPATH);
-
- (void) strncpy(uap->rdc_set[0].disk_queue, STRUCT_FGETP(rs, disk_queue),
- NSC_MAXPATH);
-
- uap->command = STRUCT_FGET(uparms, command);
- uap->options = STRUCT_FGET(uparms, options);
-
- enable = (uap->command == RDC_CMD_ENABLE ||
- uap->command == RDC_CMD_RESUME);
- disable = (uap->command == RDC_CMD_DISABLE ||
- uap->command == RDC_CMD_SUSPEND);
-
- /*
- * Initialise the threadset if it has not already been done.
- *
- * This has to be done now, not in rdcattach(), because
- * rdcattach() can be called before nskernd is running (eg.
- * boot -r) in which case the nst_init() would fail and hence
- * the attach would fail.
- *
- * Threadset creation is locked by the rdc_conf_lock,
- * destruction is inherently single threaded as it is done in
- * _rdc_unload() which must be the last thing performed by
- * rdcdetach().
- */
-
- if (enable && _rdc_ioset == NULL) {
- mutex_enter(&rdc_conf_lock);
-
- if (_rdc_ioset == NULL) {
- rc = rdc_thread_configure();
- }
-
- mutex_exit(&rdc_conf_lock);
-
- if (rc || _rdc_ioset == NULL) {
- spcs_s_add(kstatus, RDC_ENOTHREADS);
- rc = RDC_ENOTHREADS;
- goto outuap;
- }
- }
- switch (uap->command) {
- case RDC_CMD_ENABLE:
- rc = rdc_enable(uap, kstatus);
- break;
- case RDC_CMD_DISABLE:
- rc = rdc_disable(uap, kstatus);
- break;
- case RDC_CMD_COPY:
- rc = rdc_sync(uap, kstatus);
- break;
- case RDC_CMD_LOG:
- rc = rdc_log(uap, kstatus);
- break;
- case RDC_CMD_RECONFIG:
- rc = rdc_reconfig(uap, kstatus);
- break;
- case RDC_CMD_RESUME:
- rc = rdc_resume(uap, kstatus);
- break;
- case RDC_CMD_SUSPEND:
- rc = rdc_suspend(uap, kstatus);
- break;
- case RDC_CMD_TUNABLE:
- rc = rdc_tunable(uap, kstatus);
- break;
- case RDC_CMD_WAIT:
- rc = rdc_wait(uap, kstatus);
- break;
- case RDC_CMD_HEALTH:
- rc = rdc_health(uap, kstatus, rvp);
- break;
- case RDC_CMD_STATUS:
- rc = rdc_status(arg, mode, uap, kstatus);
- break;
- case RDC_CMD_RESET:
- rc = rdc_reset(uap, kstatus);
- break;
- case RDC_CMD_ADDQ:
- rc = rdc_add_diskq(uap, kstatus);
- break;
- case RDC_CMD_REMQ:
- if ((rc = rdc_rem_diskq(uap, kstatus)) != 0)
- break;
- /* FALLTHRU */
- case RDC_CMD_KILLQ:
- rc = rdc_kill_diskq(uap, kstatus);
- break;
- case RDC_CMD_INITQ:
- rc = rdc_init_diskq(uap, kstatus);
- break;
-
- default:
- rc = EINVAL;
- break;
- }
-
- /*
- * Tune the threadset size after a successful rdc_set addition
- * or removal.
- */
- if ((enable || disable) && rc == 0) {
- mutex_enter(&rdc_conf_lock);
- rdc_thread_tune(enable ? 2 : -2);
- mutex_exit(&rdc_conf_lock);
- }
-outuap:
- kmem_free(uap, sizeof (*uap));
-out:
- kmem_free(fsvaddr.buf, fsvaddr.len);
- kmem_free(tsvaddr.buf, tsvaddr.len);
- if (pf)
- kmem_free(pf, KNC_STRSIZE);
- if (p)
- kmem_free(p, KNC_STRSIZE);
- if (knconf)
- kmem_free(knconf, sizeof (*knconf));
- return (rc);
-}
-
-
-/*
- * krdc->group->lock held on entry to halt_sync()
- */
-static void
-halt_sync(rdc_k_info_t *krdc)
-{
- rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
-
- ASSERT(MUTEX_HELD(&krdc->group->lock));
- ASSERT(IS_ENABLED(urdc));
-
- /*
- * If a sync is in progress, halt it
- */
- if ((rdc_get_vflags(urdc) & RDC_PRIMARY) &&
- (krdc->aux_state & RDC_AUXSYNCIP)) {
- krdc->disk_status = 1;
-
- while (krdc->disk_status == 1) {
- if (cv_wait_sig(&krdc->haltcv, &krdc->group->lock) == 0)
- break;
- }
- }
-}
-
-/*
- * return size in blocks
- */
-uint64_t
-mirror_getsize(int index)
-{
- rdc_k_info_t *krdc;
- rdc_u_info_t *urdc;
- int rc, rs;
- nsc_size_t size;
-
- krdc = &rdc_k_info[index];
- urdc = &rdc_u_info[index];
-
- rc = _rdc_rsrv_devs(krdc, RDC_RAW, RDC_INTERNAL);
- rs = nsc_partsize(RDC_U_FD(krdc), &size);
- urdc->volume_size = size;
- if (rc == 0)
- _rdc_rlse_devs(krdc, RDC_RAW);
-
- return (rs == 0 ? urdc->volume_size : 0);
-}
-
-
-/*
- * Create a new dataset for this transfer, and add it to the list
- * of datasets via the net_dataset pointer in the krdc.
- */
-rdc_net_dataset_t *
-rdc_net_add_set(int index)
-{
- rdc_k_info_t *krdc;
- rdc_u_info_t *urdc;
- rdc_net_dataset_t *dset;
-
- if (index >= rdc_max_sets) {
- cmn_err(CE_NOTE, "!rdc_net_add_set: bad index %d", index);
- return (NULL);
- }
- krdc = &rdc_k_info[index];
- urdc = &rdc_u_info[index];
-
- dset = kmem_alloc(sizeof (*dset), KM_NOSLEEP);
- if (dset == NULL) {
- cmn_err(CE_NOTE, "!rdc_net_add_set: kmem_alloc failed");
- return (NULL);
- }
- RDC_DSMEMUSE(sizeof (*dset));
- dset->inuse = 1;
- dset->nitems = 0;
- dset->delpend = 0;
- dset->head = NULL;
- dset->tail = NULL;
- mutex_enter(&krdc->dc_sleep);
-
- if (!IS_ENABLED(urdc)) {
- /* raced with a disable command */
- kmem_free(dset, sizeof (*dset));
- RDC_DSMEMUSE(-sizeof (*dset));
- mutex_exit(&krdc->dc_sleep);
- return (NULL);
- }
- /*
- * Shared the id generator, (and the locks).
- */
- mutex_enter(&rdc_net_hnd_id_lock);
- if (++rdc_net_hnd_id == 0)
- rdc_net_hnd_id = 1;
- dset->id = rdc_net_hnd_id;
- mutex_exit(&rdc_net_hnd_id_lock);
-
-#ifdef DEBUG
- if (krdc->net_dataset != NULL) {
- rdc_net_dataset_t *dset2;
- for (dset2 = krdc->net_dataset; dset2; dset2 = dset2->next) {
- if (dset2->id == dset->id) {
- cmn_err(CE_PANIC,
- "rdc_net_add_set duplicate id %p:%d %p:%d",
- (void *)dset, dset->id,
- (void *)dset2, dset2->id);
- }
- }
- }
-#endif
- dset->next = krdc->net_dataset;
- krdc->net_dataset = dset;
- mutex_exit(&krdc->dc_sleep);
-
- return (dset);
-}
-
-/*
- * fetch the previously added dataset.
- */
-rdc_net_dataset_t *
-rdc_net_get_set(int index, int id)
-{
- rdc_k_info_t *krdc;
- rdc_net_dataset_t *dset;
-
- if (index >= rdc_max_sets) {
- cmn_err(CE_NOTE, "!rdc_net_get_set: bad index %d", index);
- return (NULL);
- }
- krdc = &rdc_k_info[index];
-
- mutex_enter(&krdc->dc_sleep);
-
- dset = krdc->net_dataset;
- while (dset && (dset->id != id))
- dset = dset->next;
-
- if (dset) {
- dset->inuse++;
- }
-
- mutex_exit(&krdc->dc_sleep);
- return (dset);
-}
-
-/*
- * Decrement the inuse counter. Data may be freed.
- */
-void
-rdc_net_put_set(int index, rdc_net_dataset_t *dset)
-{
- rdc_k_info_t *krdc;
-
- if (index >= rdc_max_sets) {
- cmn_err(CE_NOTE, "!rdc_net_put_set: bad index %d", index);
- return;
- }
- krdc = &rdc_k_info[index];
-
- mutex_enter(&krdc->dc_sleep);
- dset->inuse--;
- ASSERT(dset->inuse >= 0);
- if ((dset->inuse == 0) && (dset->delpend)) {
- rdc_net_free_set(krdc, dset);
- }
- mutex_exit(&krdc->dc_sleep);
-}
-
-/*
- * Mark that we are finished with this set. Decrement inuse
- * counter, mark as needing deletion, and
- * remove from linked list.
- */
-void
-rdc_net_del_set(int index, rdc_net_dataset_t *dset)
-{
- rdc_k_info_t *krdc;
-
- if (index >= rdc_max_sets) {
- cmn_err(CE_NOTE, "!rdc_net_del_set: bad index %d", index);
- return;
- }
- krdc = &rdc_k_info[index];
-
- mutex_enter(&krdc->dc_sleep);
- dset->inuse--;
- ASSERT(dset->inuse >= 0);
- dset->delpend = 1;
- if (dset->inuse == 0) {
- rdc_net_free_set(krdc, dset);
- }
- mutex_exit(&krdc->dc_sleep);
-}
-
-/*
- * free all the memory associated with this set, and remove from
- * list.
- * Enters and exits with dc_sleep lock held.
- */
-
-void
-rdc_net_free_set(rdc_k_info_t *krdc, rdc_net_dataset_t *dset)
-{
- rdc_net_dataset_t **dsetp;
-#ifdef DEBUG
- int found = 0;
-#endif
-
- ASSERT(MUTEX_HELD(&krdc->dc_sleep));
- ASSERT(dset);
- for (dsetp = &krdc->net_dataset; *dsetp; dsetp = &((*dsetp)->next)) {
- if (*dsetp == dset) {
- *dsetp = dset->next;
-#ifdef DEBUG
- found = 1;
-#endif
- break;
- }
- }
-
-#ifdef DEBUG
- if (found == 0) {
- cmn_err(CE_WARN, "!rdc_net_free_set: Unable to find "
- "dataset 0x%p in krdc list", (void *)dset);
- }
-#endif
- /*
- * unlinked from list. Free all the data
- */
- rdc_ditemsfree(dset);
- /*
- * free my core.
- */
- kmem_free(dset, sizeof (*dset));
- RDC_DSMEMUSE(-sizeof (*dset));
-}
-
-
-/*
- * Free all the dataitems and the data it points to.
- */
-static void
-rdc_ditemsfree(rdc_net_dataset_t *dset)
-{
- rdc_net_dataitem_t *ditem;
- rdc_net_dataitem_t *nitem;
-
- ditem = dset->head;
-
- while (ditem) {
- nitem = ditem->next;
- kmem_free(ditem->dptr, ditem->mlen);
- RDC_DSMEMUSE(-ditem->mlen);
- dset->nitems--;
- kmem_free(ditem, sizeof (*ditem));
- RDC_DSMEMUSE(-sizeof (*ditem));
- ditem = nitem;
- }
- ASSERT(dset->nitems == 0);
-}
-
-/*
- * allocate and initialize a rdc_aio_t
- */
-rdc_aio_t *
-rdc_aio_tbuf_get(void *n, void *h, int pos, int len, int flag, int index, int s)
-{
- rdc_aio_t *p;
-
- p = kmem_zalloc(sizeof (rdc_aio_t), KM_NOSLEEP);
- if (p == NULL) {
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!_rdcaiotbufget: kmem_alloc failed bp aio");
-#endif
- return (NULL);
- } else {
- p->next = n; /* overload */
- p->handle = h;
- p->pos = pos;
- p->qpos = -1;
- p->len = len;
- p->flag = flag;
- p->index = index;
- p->iostatus = s; /* overload */
- /* set up seq later, in case thr create fails */
- }
- return (p);
-}
-
-/*
- * rdc_aio_buf_get
- * get an aio_buf
- */
-aio_buf_t *
-rdc_aio_buf_get(rdc_buf_t *h, int index)
-{
- aio_buf_t *p;
-
- if (index >= rdc_max_sets) {
- cmn_err(CE_NOTE, "!rdc: rdc_aio_buf_get bad index %x", index);
- return (NULL);
- }
-
- mutex_enter(&h->aio_lock);
-
- p = h->rdc_anon;
- while (p && (p->kindex != index))
- p = p->next;
-
- mutex_exit(&h->aio_lock);
- return (p);
-}
-
-/*
- * rdc_aio_buf_del
- * delete a aio_buf
- */
-void
-rdc_aio_buf_del(rdc_buf_t *h, rdc_k_info_t *krdc)
-{
- aio_buf_t *p, **pp;
-
- mutex_enter(&h->aio_lock);
-
- p = NULL;
- for (pp = &h->rdc_anon; *pp; pp = &((*pp)->next)) {
- if ((*pp)->kindex == krdc->index) {
- p = *pp;
- break;
- }
- }
-
- if (p) {
- *pp = p->next;
- kmem_free(p, sizeof (*p));
- }
- mutex_exit(&h->aio_lock);
-}
-
-/*
- * rdc_aio_buf_add
- * Add a aio_buf.
- */
-aio_buf_t *
-rdc_aio_buf_add(int index, rdc_buf_t *h)
-{
- aio_buf_t *p;
-
- p = kmem_zalloc(sizeof (*p), KM_NOSLEEP);
- if (p == NULL) {
- cmn_err(CE_NOTE, "!rdc_aio_buf_add: kmem_alloc failed");
- return (NULL);
- }
-
- p->rdc_abufp = NULL;
- p->kindex = index;
-
- mutex_enter(&h->aio_lock);
- p->next = h->rdc_anon;
- h->rdc_anon = p;
- mutex_exit(&h->aio_lock);
- return (p);
-}
-
-/*
- * kmemalloc a new group structure and setup the common
- * fields.
- */
-static rdc_group_t *
-rdc_newgroup()
-{
- rdc_group_t *group;
-
- group = kmem_zalloc(sizeof (rdc_group_t), KM_SLEEP);
- group->diskq.lastio = kmem_zalloc(sizeof (rdc_aio_t), KM_SLEEP);
- group->count = 1;
- group->seq = RDC_NEWSEQ;
- group->seqack = RDC_NEWSEQ;
- mutex_init(&group->lock, NULL, MUTEX_DRIVER, NULL);
- mutex_init(&group->ra_queue.net_qlock, NULL, MUTEX_DRIVER, NULL);
- mutex_init(&group->diskqmutex, NULL, MUTEX_DRIVER, NULL);
- mutex_init(&group->diskq.disk_qlock, NULL, MUTEX_DRIVER, NULL);
- mutex_init(&group->diskq.head_lock, NULL, MUTEX_DRIVER, NULL);
- mutex_init(&group->addthrnumlk, NULL, MUTEX_DRIVER, NULL);
- cv_init(&group->unregistercv, NULL, CV_DRIVER, NULL);
- cv_init(&group->asyncqcv, NULL, CV_DRIVER, NULL);
- cv_init(&group->diskq.busycv, NULL, CV_DRIVER, NULL);
- cv_init(&group->diskq.qfullcv, NULL, CV_DRIVER, NULL);
- cv_init(&group->ra_queue.qfcv, NULL, CV_DRIVER, NULL);
- group->ra_queue.qfill_sleeping = RDC_QFILL_DEAD;
- group->diskq.busycnt = 0;
- ASSERT(group->synccount == 0); /* group was kmem_zalloc'ed */
-
- /*
- * add default number of threads to the flusher thread set, plus
- * one extra thread for the disk queue flusher
- */
- if (nst_add_thread(_rdc_flset, 3) != 3)
- cmn_err(CE_NOTE, "!rdc_newgroup: nst_add_thread failed");
-
- return (group);
-}
-
-void
-rdc_delgroup(rdc_group_t *group)
-{
-
- ASSERT(group->asyncstall == 0);
- ASSERT(group->rdc_thrnum == 0);
- ASSERT(group->count == 0);
- ASSERT(MUTEX_HELD(&rdc_many_lock));
-
- mutex_enter(&group->ra_queue.net_qlock);
- rdc_sleepqdiscard(group);
- mutex_exit(&group->ra_queue.net_qlock);
-
- /* try to remove flusher threads that this group added to _rdc_flset */
- if (nst_del_thread(_rdc_flset, group->rdc_addthrnum + 3) !=
- group->rdc_addthrnum + 3)
- cmn_err(CE_NOTE, "!rdc_delgroup: nst_del_thread failed");
-
- mutex_destroy(&group->lock);
- mutex_destroy(&group->ra_queue.net_qlock);
- mutex_destroy(&group->diskqmutex);
- mutex_destroy(&group->diskq.disk_qlock);
- mutex_destroy(&group->diskq.head_lock);
- mutex_destroy(&group->addthrnumlk);
- cv_destroy(&group->unregistercv);
- cv_destroy(&group->asyncqcv);
- cv_destroy(&group->diskq.busycv);
- cv_destroy(&group->diskq.qfullcv);
- cv_destroy(&group->ra_queue.qfcv);
- kmem_free(group->diskq.lastio, sizeof (rdc_aio_t));
- kmem_free(group, sizeof (rdc_group_t));
-}
diff --git a/usr/src/uts/common/avs/ns/rdc/rdc_io.h b/usr/src/uts/common/avs/ns/rdc/rdc_io.h
deleted file mode 100644
index 6acf96686c..0000000000
--- a/usr/src/uts/common/avs/ns/rdc/rdc_io.h
+++ /dev/null
@@ -1,1009 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _RDC_IO_H
-#define _RDC_IO_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-#include <sys/unistat/spcs_s.h>
-#ifdef DS_DDICT
-#define bool_t int
-#endif
-#include <sys/nsctl/rdc_prot.h>
-#include <sys/nsctl/nsctl.h>
-#include <sys/nsctl/rdc_ioctl.h>
-
-/*
- * Definitions for kstats
- */
-#define RDC_MKSTAT_MAXSETS "maxsets"
-#define RDC_MKSTAT_MAXFBAS "maxfbas"
-#define RDC_MKSTAT_RPC_TIMEOUT "rpc_timeout"
-#define RDC_MKSTAT_HEALTH_THRES "health_thres"
-#define RDC_MKSTAT_BITMAP_WRITES "bitmap_writes"
-#define RDC_MKSTAT_CLNT_COTS_CALLS "clnt_cots_calls"
-#define RDC_MKSTAT_CLNT_CLTS_CALLS "clnt_clts_calls"
-#define RDC_MKSTAT_SVC_COTS_CALLS "svc_cots_calls"
-#define RDC_MKSTAT_SVC_CLTS_CALLS "svc_clts_calls"
-#define RDC_MKSTAT_BITMAP_REF_DELAY "bitmap_ref_delay"
-
-#define RDC_IKSTAT_FLAGS "flags"
-#define RDC_IKSTAT_SYNCFLAGS "syncflags"
-#define RDC_IKSTAT_BMPFLAGS "bmpflags"
-#define RDC_IKSTAT_SYNCPOS "syncpos"
-#define RDC_IKSTAT_VOLSIZE "volsize"
-#define RDC_IKSTAT_BITSSET "bitsset"
-#define RDC_IKSTAT_AUTOSYNC "autosync"
-#define RDC_IKSTAT_MAXQFBAS "maxqfbas"
-#define RDC_IKSTAT_MAXQITEMS "maxqitems"
-#define RDC_IKSTAT_FILE "primary_vol"
-#define RDC_IKSTAT_SECFILE "secondary_vol"
-#define RDC_IKSTAT_BITMAP "bitmap"
-#define RDC_IKSTAT_PRIMARY_HOST "primary_host"
-#define RDC_IKSTAT_SECONDARY_HOST "secondary_host"
-#define RDC_IKSTAT_TYPE_FLAG "type_flag"
-#define RDC_IKSTAT_BMP_SIZE "bmp_size"
-#define RDC_IKSTAT_DISK_STATUS "disk_status"
-#define RDC_IKSTAT_IF_DOWN "if_down"
-#define RDC_IKSTAT_IF_RPC_VERSION "if_rpc_version"
-#define RDC_IKSTAT_ASYNC_THROTTLE_DELAY "async_throttle_delay"
-#define RDC_IKSTAT_ASYNC_BLOCK_HWM "async_block_hwm"
-#define RDC_IKSTAT_ASYNC_ITEM_HWM "async_item_hwm"
-#define RDC_IKSTAT_QUEUE_TYPE "async_queue_type"
-#define RDC_IKSTAT_ASYNC_ITEMS "async_queue_items"
-#define RDC_IKSTAT_ASYNC_BLOCKS "async_queue_blocks"
-
-/*
- * Queue types
- */
-#define RDC_DISKQUE 0X01
-#define RDC_MEMQUE 0x02
-#define RDC_NOQUE -1
-
-#define RDC_ACTIVE 0x1
-#define RDC_INACTIVE 0x2
-
-#ifdef _KERNEL
-
-extern nstset_t *_rdc_ioset;
-extern nstset_t *_rdc_flset;
-
-#ifdef DEBUG
-extern int RDC_MAX_SYNC_THREADS;
-extern int rdc_maxthreads_last;
-int num_sync_threads;
-#else
-#define RDC_MAX_SYNC_THREADS 8
-#endif
-#ifdef DEBUG
-#define RDC_AVAIL_THR_TUNE(n) \
- do { \
- if (rdc_maxthreads_last < RDC_MAX_SYNC_THREADS) { \
- (void) nst_add_thread(n.rdc_syncset, \
- RDC_MAX_SYNC_THREADS - rdc_maxthreads_last);\
- } \
- if (rdc_maxthreads_last > RDC_MAX_SYNC_THREADS) { \
- (void) nst_del_thread(n.rdc_syncset, \
- rdc_maxthreads_last - RDC_MAX_SYNC_THREADS); \
- } \
- n.avail_thr = RDC_MAX_SYNC_THREADS - n.active_thr; \
- if (n.avail_thr < 0) { \
- n.avail_thr = 0; \
- } \
- rdc_maxthreads_last = RDC_MAX_SYNC_THREADS; \
- num_sync_threads = nst_nthread(n.rdc_syncset); \
- } while (0);
-#else
-#define RDC_AVAIL_THR_TUNE(n) \
- do { \
- n.avail_thr = RDC_MAX_SYNC_THREADS - n.active_thr; \
- if (n.avail_thr < 0) \
- n.avail_thr = 0; \
- } while (0);
-
-#endif
-
-typedef struct syncloop_info {
- int active_thr;
- int avail_thr; /* should be MAX_RDC_SYNC_THREADS - active */
- kmutex_t lock;
- nstset_t *rdc_syncset;
-} sync_info_t;
-
-sync_info_t sync_info;
-
-/*
- * Static server information
- */
-typedef struct servinfo {
- struct knetconfig *ri_knconf; /* bound TLI fd */
- struct netbuf ri_addr; /* server's address */
- struct sec_data *ri_secdata; /* sec data for rpcsec module */
- char *ri_hostname; /* server's hostname */
- int ri_hostnamelen; /* server's hostname length */
-} rdc_srv_t;
-
-/*
- * Interface structure, including health monitoring.
- */
-typedef struct rdc_if_s {
- struct rdc_if_s *next; /* chain pointer */
- struct netbuf ifaddr;
- struct netbuf r_ifaddr;
- rdc_srv_t *srv; /* servinfo of server end */
- int if_down; /* i/f is down (set on primary) */
- int isprimary; /* this end is a primary */
- int issecondary; /* this end is a secondary */
- rpcvers_t rpc_version; /* RPC protocol version in use */
- int no_ping; /* set on secondary to hold off RPCs */
- int old_pulse; /* previous (current) pulse value */
- int new_pulse; /* new (incoming) pulse value */
- int deadness; /* how close to death are we? */
- volatile int exiting; /* daemon exit flag */
- time_t last; /* time of last ping */
-} rdc_if_t;
-
-
-typedef struct rdc_aio_s {
- struct rdc_aio_s *next;
- nsc_buf_t *handle;
- nsc_buf_t *qhandle;
- nsc_off_t pos;
- nsc_off_t qpos;
- nsc_size_t len;
- nsc_size_t orig_len;
- int flag;
- int iostatus;
- int index;
- uint_t seq; /* sequence on async Q */
-} rdc_aio_t;
-
-/* values for (rdc_aio_t *)->iostatus */
-enum {
- RDC_IO_NONE = 0, /* not used */
- RDC_IO_INIT, /* io started */
- RDC_IO_DONE, /* io done successfully */
- RDC_IO_FAILED, /* io failed */
- RDC_IO_DISCARDED, /* io discarded */
- RDC_IO_CANCELLED /* group_log in progress */
-};
-
-
-#define RDC_MAX_QBLOCKS 16384 /* 8MB temporary q for diskq to flush to */
-#define RDC_LOW_QBLOCKS 13927 /* roughly 85% of queue full */
-#define RDC_HALF_MQUEUE 8192 /* half of the memory queue */
-
-typedef struct netqueue {
- rdc_aio_t *net_qhead;
- rdc_aio_t *net_qtail;
- kmutex_t net_qlock;
- int hwmhit; /* queue full hit? reset after hwm */
- int qfill_sleeping; /* waiting for work? */
- int qfflags; /* diskq/memq flusher flags */
- kcondvar_t qfcv; /* for timed waits */
- volatile nsc_size_t blocks; /* number of FBAs in q */
- volatile uint64_t nitems; /* number of items in q */
- volatile int inflbls; /* number of inflight blocks */
- volatile int inflitems; /* number of inflight items */
- uint64_t nitems_hwm; /* highest items on queue */
- nsc_size_t blocks_hwm; /* highest blocks on queue */
- long throttle_delay; /* Number of times we delayed x 2 */
-} net_queue;
-
-
-/*
- * Bitmap header structures.
- * These must be fixed size in all data models.
- * If we ever support little-endian machines (eg. Intel) we will need
- * to add byte-swapping logic.
- */
-
-typedef struct {
- int32_t magic;
- int32_t serial_mode;
- int32_t use_mirror;
- int32_t mirror_down;
- int32_t sync_needed;
- char bitmapname[NSC_MAXPATH];
- char filename[NSC_MAXPATH];
- int32_t volume_failed;
-} rdc_headerv2_t;
-#define RDC_HDR_V2 0x52444302 /* RDC2 */
-
-#define RDC_SYNC 0x1
-#define RDC_REV_SYNC 0x2
-#define RDC_FULL_SYNC 0x3
-
-#define RDC_FAILED 0x1
-#define RDC_COMPLETED 0x2
-
-typedef struct {
- char file[NSC_MAXPATH];
- char bitmap[NSC_MAXPATH];
-} rdc_hdr_addr_t;
-
-typedef struct {
- int32_t magic;
- rdc_hdr_addr_t primary;
- rdc_hdr_addr_t secondary;
- int32_t flags;
- int32_t autosync;
- int32_t maxqfbas;
- int32_t maxqitems;
- int32_t syshostid; /* for cluster bitmaps */
-} rdc_headerv3_t;
-#define RDC_HDR_V3 0x52444303 /* RDC3 */
-
-typedef struct {
- int32_t magic;
- rdc_hdr_addr_t primary;
- rdc_hdr_addr_t secondary;
- int32_t flags;
- int32_t autosync;
- int32_t maxqfbas;
- int32_t maxqitems;
- int32_t syshostid; /* for cluster bitmaps */
- int32_t asyncthr;
-} rdc_headerv4_t;
-#define RDC_HDR_V4 0x52444304 /* RDC4 */
-
-typedef struct {
- int32_t magic;
- rdc_hdr_addr_t primary;
- rdc_hdr_addr_t secondary;
- int32_t flags;
- int32_t autosync;
- int64_t maxqfbas;
- int64_t maxqitems;
- int32_t syshostid; /* for cluster bitmaps */
- int32_t asyncthr;
- int32_t refcntsize; /* size in bytes of each refcount */
-} rdc_headerv5_t;
-#define RDC_HDR_V5 0x52444305 /* RDC5 */
-
-typedef rdc_headerv5_t rdc_header_t; /* Current header type */
-#define RDC_HDR_MAGIC RDC_HDR_V5 /* Current header magic number */
-
-#endif /* _KERNEL */
-
-#define RDC_BITMAP_FBA 1 /* Offset at which the bitmap starts */
-#define RDC_BITREF_FBA(krdc) (RDC_BITMAP_FBA + FBA_LEN(krdc->bitmap_size))
-
-#ifdef _KERNEL
-
-#define RDC_FUTILE_ATTEMPTS 50
-typedef struct aio_buf_s {
- struct aio_buf_s *next; /* next aio_buf */
- nsc_buf_t *rdc_abufp; /* actual anon buf */
- int kindex; /* index we are attached to */
-} aio_buf_t;
-
-typedef struct rdc_thrsync {
- kmutex_t lock;
- int threads;
- int complete;
- kcondvar_t cv;
-} rdc_thrsync_t;
-
-typedef struct sync_status_s {
- int offset;
- struct sync_status_s *next;
-} sync_status_t;
-
-typedef struct rdc_syncthr {
- nsc_off_t offset;
- nsc_size_t len;
- struct rdc_k_info *krdc;
- sync_status_t *status;
-} rdc_syncthr_t;
-
-/*
- * RDC buffer header
- */
-
-typedef struct rdc_buf_s {
- nsc_buf_t rdc_bufh; /* exported buffer header */
- nsc_buf_t *rdc_bufp; /* underlying buffer */
- aio_buf_t *rdc_anon; /* ANON async buffer */
- struct rdc_fd_s *rdc_fd; /* back link */
- size_t rdc_vsize; /* size of allocated nsc_vec_t */
- int rdc_flags; /* flags */
- kmutex_t aio_lock; /* lock for rdc_anon */
- rdc_thrsync_t rdc_sync; /* for thread syncronization */
-} rdc_buf_t;
-
-#define RDC_VEC_ALLOC 0x1 /* local kmem vector for remote io */
-#define RDC_ALLOC 0x2 /* rdc_bufp is nsc_buf_alloc'd */
-#define RDC_ASYNC_VEC 0x4 /* Keep tmp handle for async flusher */
-#define RDC_REMOTE_BUF 0x8 /* buffer alloc'd for remote io only */
-#define RDC_NULL_BUF 0x10 /* tell diskq to only store io_hdr */
-#define RDC_ASYNC_BUF 0x20 /* this buf is to an async vol */
-#define RDC_NULLBUFREAD 0x0f000000 /* read because RDC_NULL_BUF detected */
-
-#define BUF_IS_ASYNC(h) (((h) != NULL) && (h)->rdc_flags & RDC_ASYNC_BUF)
-#define RDC_REMOTE(h) (((h) != NULL) && ((h)->rdc_flags & RDC_REMOTE_BUF) && \
- (((h)->rdc_flags & RDC_ASYNC_VEC) == 0))
-
-/* check a handle against a supplied pos/len pair */
-
-#define RDC_HANDLE_LIMITS(h, p, l) \
- (((h)->sb_user & RDC_DISKQUE) || \
- ((p) >= (h)->sb_pos) && \
- (((p) + (l)) <= ((h)->sb_pos + (h)->sb_len)))
-
-/* check a dset against a supplied pos/len pair */
-
-#define RDC_DSET_LIMITS(d, p, l) \
- (((p) >= (d)->pos) && \
- (((p) + (l)) <= ((d)->pos + (d)->fbalen)))
-
-/*
- * RDC device info structures
- */
-
-typedef struct _rdc_info_dev_s {
- nsc_fd_t *bi_fd; /* file descriptor */
- nsc_iodev_t *bi_iodev; /* I/O device structure */
- struct rdc_k_info *bi_krdc; /* back link */
- int bi_rsrv; /* Count of reserves held */
- int bi_orsrv; /* Reserves for other io provider */
- int bi_failed; /* Count of failed (faked) reserves */
- int bi_ofailed; /* Other io provider failed reserves */
- int bi_flag; /* Reserve flags */
-} _rdc_info_dev_t;
-
-
-typedef struct rdc_info_dev_s {
- struct rdc_info_dev_s *id_next; /* forward link */
- _rdc_info_dev_t id_cache_dev; /* cached device info */
- _rdc_info_dev_t id_raw_dev; /* raw device info */
- kmutex_t id_rlock; /* reserve/release lock */
- kcondvar_t id_rcv; /* nsc_release pending cv */
- int id_sets; /* # of sets referencing */
- int id_release; /* # of pending nsc_releases */
- int id_flag; /* flags */
-} rdc_info_dev_t;
-
-
-typedef struct rdc_path_s {
- nsc_path_t *rp_tok; /* nsc_register_path token */
- int rp_ref; /* # of rdc_fd_t's */
-} rdc_path_t;
-
-
-/*
- * Values for id_flag
- */
-#define RDC_ID_CLOSING 0x1 /* device is closing */
-
-#include <sys/nsctl/rdc_diskq.h>
-
-/*
- * value for diskio.seq.
- */
-#define RDC_NOSEQ (0) /* ignore sequence */
-#define RDC_NEWSEQ (1) /* start of sequence */
-
-typedef struct rdc_sleepq {
- struct rdc_sleepq *next;
- uint_t seq; /* sequence in queue */
- int idx; /* idx number of request */
- int pindex; /* primary host set index */
- int sindex; /* secondary host set index */
- uint64_t qpos; /* offset on primary's queue */
- int nocache; /* cache flag to alloc_buf */
-} rdc_sleepq_t;
-
-/*
- * RDC group structure
- */
-typedef struct rdc_group {
- int count;
- int rdc_writer;
- int unregistering;
- kmutex_t lock;
- net_queue ra_queue; /* io todo async queues */
- kcondvar_t iowaitcv; /* wait for flusher */
- kcondvar_t unregistercv; /* wait for unregister */
- int rdc_thrnum; /* number of threads */
- int rdc_addthrnum; /* number threads added to thr set */
- kmutex_t addthrnumlk; /* lock for above */
- rdc_sleepq_t *sleepq; /* head of waiting tasks */
- /*
- * Dual use, the outgoing sequence number on the client.
- * The next expected sequence number on the server.
- * Protected by the ra_queue lock.
- */
- uint_t seq;
- /*
- * Dual use, the last acknowledged sequence number.
- * Used to ensure that the queue doesn't overflow on server
- * and to stall transmissions on the client.
- * Protected by the ra_queue lock.
- */
- uint_t seqack;
- int asyncstall; /* count of asleep threads */
- int asyncdis; /* discard stalled output */
- kcondvar_t asyncqcv; /* output stall here */
- int flags; /* memory or disk. status etc */
- disk_queue diskq; /* disk queue */
- nsc_fd_t *diskqfd; /* diskq handle */
- nsc_path_t *q_tok; /* q registration */
- int diskqrsrv; /* reserve count */
- kmutex_t diskqmutex; /* enables/disables/reserves */
- uint_t synccount; /* number of group members syncing */
-} rdc_group_t;
-
-/* group state */
-#define RDC_DISKQ_KILL 0x01 /* a force kill of diskq pending */
-
-#define RDC_IS_DISKQ(grp) (grp->flags & RDC_DISKQUE)
-#define RDC_IS_MEMQ(grp) (grp->flags & RDC_MEMQUE)
-
-/*
- * These flags are used in the
- * aux_state field, and are used to track:
- * AUXSYNCIP: When the code has a sync thread running, used instead
- * of the RC_SYNCING flag which gets cleared before the sync thread
- * terminates.
- * AUXWRITE: Set when rdc_sync_write_thr is running, so the rdc_unintercept
- * code can wait until a one-to-many write has actually terminated.
- */
-#define RDC_AUXSYNCIP 0x01 /* a sync is in progress */
-#define RDC_AUXWRITE 0x02 /* I've got a write in progress */
-
-
-/*
- * RDC kernel-private information
- */
-typedef struct rdc_k_info {
- int index; /* Index into array */
- int remote_index; /* -1 means unknown */
- int type_flag;
- int rpc_version; /* RPC version this set supps */
- int spare1;
- nsc_off_t syncbitpos;
- kmutex_t syncbitmutex; /* lock for syncbitpos */
- volatile int busy_count; /* ioctls in progress */
- volatile int sync_done;
- int aux_state; /* syncing ,don't disable */
- rdc_thrsync_t syncs; /* _rdc_sync thread tracking */
- rdc_info_dev_t *devices;
- nsc_iodev_t *iodev; /* I/O device structure */
- rdc_path_t cache_path;
- rdc_path_t raw_path;
- rdc_if_t *intf;
- rdc_srv_t *lsrv; /* list of servinfo */
- nsc_size_t maxfbas; /* returned from nsc_maxfbas */
- unsigned char *dcio_bitmap;
- void *bitmap_ref; /* Incore bitmap bit ref */
- struct rdc_group *group;
- nsc_size_t bitmap_size;
- int bmaprsrv; /* bitmap reserve count */
- int bitmap_write;
- nsc_fd_t *bitmapfd;
- nsc_fd_t *remote_fd; /* FCAL direct io */
- volatile int disk_status; /* set to halt sync */
- int closing;
- nsc_path_t *b_tok; /* Bitmap registration */
- int b_ref;
- kmutex_t dc_sleep;
- kmutex_t bmapmutex; /* mutex for bitmap ops */
- kcondvar_t busycv; /* wait for ioctl to complete */
- kcondvar_t closingcv; /* unregister_path/close */
- kcondvar_t haltcv; /* wait for sync to halt */
- kcondvar_t synccv; /* wait for sync to halt */
- struct rdc_net_dataset *net_dataset; /* replaces hnds */
- int64_t io_time; /* moved from cd_info */
- struct rdc_k_info *many_next; /* 1-to-many circular list */
- struct rdc_k_info *multi_next; /* to multihop krdc */
- struct rdc_k_info *group_next; /* group circular list */
- kstat_t *io_kstats; /* io kstat */
- kstat_t *bmp_kstats; /* bitmap io kstat */
- kstat_t *set_kstats; /* set kstat */
- kmutex_t kstat_mutex; /* mutex for kstats */
- kmutex_t bmp_kstat_mutex; /* mutex for kstats */
- struct bm_ref_ops *bm_refs;
-} rdc_k_info_t;
-
-#define c_fd devices->id_cache_dev.bi_fd
-#define c_rsrv devices->id_cache_dev.bi_rsrv
-#define c_failed devices->id_cache_dev.bi_failed
-#define c_flag devices->id_cache_dev.bi_flag
-
-#define c_tok cache_path.rp_tok
-#define c_ref cache_path.rp_ref
-
-#define r_fd devices->id_raw_dev.bi_fd
-#define r_rsrv devices->id_raw_dev.bi_rsrv
-#define r_failed devices->id_raw_dev.bi_failed
-#define r_flag devices->id_raw_dev.bi_flag
-
-#define r_tok raw_path.rp_tok
-#define r_ref raw_path.rp_ref
-
-/*
- * flags for _rdc_rsrv_devs()
- */
-
-/*
- * which device(s) to reserve - integer bitmap.
- */
-
-#define RDC_CACHE 0x1 /* data device in cache mode */
-#define RDC_RAW 0x2 /* data device in raw mode */
-#define RDC_BMP 0x4 /* bitmap device */
-#define RDC_QUE 0x8 /* diskq device */
-
-/*
- * device usage after reserve - integer flag.
- */
-
-#define RDC_INTERNAL 0x1 /* reserve for rdc internal purposes */
-#define RDC_EXTERNAL 0x2 /* reserve in response to io provider Attach */
-
-/*
- * Utility macro for nsc_*() io function returns.
- */
-
-#define RDC_SUCCESS(rc) (((rc) == NSC_DONE) || ((rc) == NSC_HIT))
-
-/*
- * RDC file descriptor structure
- */
-
-typedef struct rdc_fd_s {
- rdc_k_info_t *rdc_info; /* devices info structure */
- int rdc_type; /* open type, diskq or bitmap */
- int rdc_oflags; /* raw or cached open type */
-} rdc_fd_t;
-
-/*
- * fd and rsrv macros
- */
-
-#define RSRV(bi) (((bi)->bi_rsrv > 0) || ((bi)->bi_failed > 0))
-#define ORSRV(bi) (((bi)->bi_orsrv > 0) || ((bi)->bi_ofailed > 0))
-#define RFAILED(bi) (((bi)->bi_failed > 0) || ((bi)->bi_ofailed > 0))
-
-#define IS_RSRV(bi) (RSRV(bi) || ORSRV(bi))
-
-#define IS_CRSRV(gcd) (IS_RSRV(&(gcd)->devices->id_cache_dev))
-#define IS_RRSRV(gcd) (IS_RSRV(&(gcd)->devices->id_raw_dev))
-
-#define IS_RFAILED(gcd) \
- (RFAILED(&(gcd)->devices->id_cache_dev) || \
- RFAILED(&(gcd)->devices->id_raw_dev))
-
-#define RDC_IS_BMP(rdc) ((rdc)->rdc_type == RDC_BMP)
-#define RDC_IS_QUE(rdc) ((rdc)->rdc_type == RDC_QUE)
-#define RDC_IS_RAW(rdc) (((rdc)->rdc_oflags & NSC_CACHE) == 0)
-#define RDC_U_FD(gcd) (IS_CRSRV(gcd) ? (gcd)->c_fd : (gcd)->r_fd)
-#define RDC_FD(rdc) (RDC_U_FD(rdc->rdc_info))
-
-
-typedef struct rdc_host_u {
- char *nodename;
- int netaddr;
- struct netbuf *naddr;
-} rdc_host_t;
-
-/*
- * Reply from remote read
- * - convenience defines for the client side code.
- * - keep this in sync with the readres structure in rdc_prot.h/.x
- */
-#define rdcrdresult readres
-#define rr_status status
-#define rr_ok readres_u.reply
-#define rr_bufsize rr_ok.data.data_len
-#define rr_data rr_ok.data.data_val
-
-/*
- * Flags for remote read rpc
- *
- * _START must be a unique rpc, _DATA and _END may be OR-d together.
- */
-#define RDC_RREAD_DATA 0x1 /* Intermediate rpc with data payload */
-#define RDC_RREAD_START 0x2 /* Setup rpc */
-#define RDC_RREAD_END 0x4 /* End rpc */
-#define RDC_RREAD_FAIL 0x8 /* Primary is failed */
-
-/*
- * Flags for remote write rpc
- */
-#define RDC_RWRITE_FAIL 0x8 /* Primary is failed */
-
-/*
- * macro used to determine if the incomming sq, with sequence
- * value x, should be placed before the sq with sequence value y.
- * This has to account for integer wrap. We account for integer
- * wrap by checking if the difference between x and y is within
- * half of the maximum integer value (RDC_MAXINT) or not.
- */
-
-#define RDC_BITSPERBYTE 8
-#define RDC_BITS(type) (RDC_BITSPERBYTE * (long)sizeof (type))
-#define RDC_HIBITI ((unsigned)1 << (RDC_BITS(int) - 1))
-#define RDC_MAXINT ((int)(~RDC_HIBITI))
-#define RDC_RANGE ((RDC_MAXINT / 2) -1)
-
-#define RDC_INFRONT(x, y) (((x < y) && ((y - x) < RDC_RANGE)) ? 1 : \
- ((x > y) && ((x - y) > RDC_RANGE)) ? 1 : 0)
-
-
-
-
-#endif /* _KERNEL */
-
-/*
- * RDC user-visible information
- */
-typedef rdc_set_t rdc_u_info_t;
-
-
-/*
- * RDC flags for set state / set cd RPC.
- * Must remain compatible with rdc RPC protocol version v3.
- */
-#define CCIO_NONE 0x0000
-#define CCIO_ENABLE 0x0008
-#define CCIO_SLAVE 0x0010
-#define CCIO_DONE 0x0020
-#define CCIO_ENABLELOG 0x0100
-#define CCIO_RSYNC 0x0400
-#define CCIO_REMOTE 0x2000
-
-
-/*
- * In kernel type flags (krdc->type_flag).
- */
-#define RDC_CONFIGURED 0x1
-#define RDC_DISABLEPEND 0x2 /* Suspend/Disable is in progress */
-#define RDC_ASYNCMODE 0x4
-#define RDC_RESUMEPEND 0x8
-#define RDC_RESPONSIBLE 0x10
-#define RDC_BUSYWAIT 0x20
-#define RDC_UNREGISTER 0x40 /* Unregister is in progress */
-#define RDC_QDISABLEPEND 0x100 /* Q Suspend/Disable is in progress */
-
-#define IS_ENABLED(urdc) ((IS_CONFIGURED(&rdc_k_info[(urdc)->index]) && \
- (rdc_get_vflags(urdc) & RDC_ENABLED)))
-#define IS_CONFIGURED(krdc) ((krdc)->type_flag & RDC_CONFIGURED)
-#define IS_MANY(krdc) ((krdc)->many_next != (krdc))
-#define IS_MULTI(krdc) ((krdc)->multi_next != NULL)
-
-#define IS_VALID_INDEX(index) ((index) >= 0 && (index) < rdc_max_sets && \
- IS_CONFIGURED(&rdc_k_info[(index)]))
-
-#define RDC_NOFLUSH 0 /* Do not do a flush when starting logging */
-#define RDC_NOREMOTE 0 /* Do no remote logging notifications */
-#define RDC_FLUSH 1 /* Do a flush when starting logging */
-#define RDC_ALLREMOTE 2 /* Notify all remote group members */
-#define RDC_OTHERREMOTE 4 /* Notify all remote group members except */
- /* the one corresponding to the current set, */
- /* to prevent recursion in the case where */
- /* the request was initiated from the remote */
- /* node. */
-#define RDC_FORCE_GROUP 8 /* set all group memebers logging regardless */
-
-#ifdef _KERNEL
-
-/*
- * Functions, vars
- */
-
-#define RDC_SYNC_EVENT_TIMEOUT (60 * HZ)
-typedef struct {
- clock_t lbolt;
- int event;
- int ack;
- int daemon_waiting; /* Daemon waiting in ioctl */
- int kernel_waiting; /* Kernel waiting for daemon to reply */
- char master[NSC_MAXPATH];
- char group[NSC_MAXPATH];
- kmutex_t mutex;
- kcondvar_t cv;
- kcondvar_t done_cv;
-} rdc_sync_event_t;
-extern rdc_sync_event_t rdc_sync_event;
-extern clock_t rdc_sync_event_timeout;
-extern kmutex_t rdc_sync_mutex;
-
-extern rdc_u_info_t *rdc_u_info;
-extern rdc_k_info_t *rdc_k_info;
-
-extern int rdc_max_sets;
-
-extern unsigned long rdc_async_timeout;
-
-extern int rdc_self_host();
-extern uint64_t mirror_getsize(int index);
-extern void rdc_sleepqdiscard(rdc_group_t *);
-
-
-#ifdef DEBUG
-extern void rdc_stallzero(int);
-#endif
-
-struct rdc_net_dataitem {
- void *dptr;
- int len; /* byte count */
- int mlen; /* actual malloced size */
- struct rdc_net_dataitem *next;
-};
-typedef struct rdc_net_dataitem rdc_net_dataitem_t;
-
-struct rdc_net_dataset {
- int id;
- int inuse;
- int delpend;
- int nitems;
- nsc_off_t pos;
- nsc_size_t fbalen;
- rdc_net_dataitem_t *head;
- rdc_net_dataitem_t *tail;
- struct rdc_net_dataset *next;
-};
-typedef struct rdc_net_dataset rdc_net_dataset_t;
-
-
-#endif /* _KERNEL */
-
-
-#define RDC_TCP_DEV "/dev/tcp"
-
-#define RDC_VERS_MIN RDC_VERSION5
-#define RDC_VERS_MAX RDC_VERSION7
-
-#define RDC_HEALTH_THRESHOLD 20
-#define RDC_MIN_HEALTH_THRES 5
-#define SNDR_MAXTHREADS 16
-/*
- * These next two defines are the default value of the async queue size
- * They have been calculated to be 8MB of data with an average of
- * 2K IO size
- */
-#define RDC_MAXTHRES_QUEUE 16384 /* max # of fbas on async q */
-#define RDC_MAX_QITEMS 4096 /* max # of items on async q */
-#define RDC_ASYNCTHR 2 /* number of async threads */
-
-#define RDC_RPC_MAX (RDC_MAXDATA + sizeof (net_data5) +\
- (RPC_MAXDATASIZE - 8192))
-#define ATM_NONE 0
-#define ATM_INIT 1
-#define ATM_EXIT 2
-
-#define RDC_CLNT_TMOUT 16
-
-#define BMAP_BLKSIZE 1024
-#define BMAP_BLKSIZEV7 RDC_MAXDATA
-
-/* right now we can only trace 1m or less writes to the bitmap (32 bits wide) */
-#define RDC_MAX_MAXFBAS 2048
-
-#if defined(_KERNEL)
-/* kstat interface */
-
-/*
- * Per module kstats
- * only one instance
- */
-typedef struct {
- kstat_named_t m_maxsets; /* Max # of sndr sets */
- kstat_named_t m_maxfbas; /* Max # of FBAS from nsctl */
- kstat_named_t m_rpc_timeout; /* global RPC timeout */
- kstat_named_t m_health_thres; /* Health thread timeout */
- kstat_named_t m_bitmap_writes; /* True for bitmap writes */
- kstat_named_t m_clnt_cots_calls; /* # of clnt COTS calls */
- kstat_named_t m_clnt_clts_calls; /* # of clnt CLTS calls */
- kstat_named_t m_svc_cots_calls; /* # of server COTS calls */
- kstat_named_t m_svc_clts_calls; /* # of server CLTS calls */
- kstat_named_t m_bitmap_ref_delay; /* # of bitmap ref overflows */
-} sndr_m_stats_t;
-
-/*
- * Per set kstats
- * one instance per configured set
- */
-typedef struct {
- kstat_named_t s_flags; /* from rdc_set_t */
- kstat_named_t s_syncflags; /* from rdc_set_t */
- kstat_named_t s_bmpflags; /* from rdc_set_t */
- kstat_named_t s_syncpos; /* from rdc_set_t */
- kstat_named_t s_volsize; /* from rdc_set_t */
- kstat_named_t s_bits_set; /* from rdc_set_t */
- kstat_named_t s_autosync; /* from rdc_set_t */
- kstat_named_t s_maxqfbas; /* from rdc_set_t */
- kstat_named_t s_maxqitems; /* from rdc_set_t */
- kstat_named_t s_primary_vol; /* from rdc_set_t */
- kstat_named_t s_secondary_vol; /* from rdc_set_t */
- kstat_named_t s_bitmap; /* from rdc_set_t */
- kstat_named_t s_primary_intf; /* from rdc_set_t */
- kstat_named_t s_secondary_intf; /* from rdc_set_t */
- kstat_named_t s_type_flag; /* from rdc_k_info_t */
- kstat_named_t s_bitmap_size; /* from rdc_k_info_t */
- kstat_named_t s_disk_status; /* from rdc_k_info_t */
- kstat_named_t s_if_if_down; /* from rdc_if_t */
- kstat_named_t s_if_rpc_version; /* from rdc_if_t */
- kstat_named_t s_aqueue_blk_hwm; /* from rdc_k_info_t */
- kstat_named_t s_aqueue_itm_hwm; /* from rdc_k_info_t */
- kstat_named_t s_aqueue_throttle; /* from rdc_k_info_t */
- kstat_named_t s_aqueue_items;
- kstat_named_t s_aqueue_blocks;
- kstat_named_t s_aqueue_type;
-} rdc_info_stats_t;
-#endif /* _KERNEL */
-
-#ifndef _SunOS_5_6 /* i.e. 2.7+ */
-typedef int xdr_t;
-#else /* i.e. 2.6- */
-typedef unsigned long rpcprog_t;
-typedef unsigned long rpcvers_t;
-typedef unsigned long rpcproc_t;
-typedef unsigned long rpcprot_t;
-typedef unsigned long rpcport_t;
-#endif /* _SunOS_5_6 */
-
-
-#ifdef _KERNEL
-
-extern nsc_size_t MAX_RDC_FBAS;
-extern volatile int net_exit;
-extern nsc_size_t rdc_maxthres_queue; /* max # of fbas on async q */
-extern int rdc_max_qitems; /* max # of items on async q */
-extern int rdc_asyncthr; /* # of async threads */
-
-#ifdef DEBUG
-extern kmutex_t rdc_cntlock;
-extern int rdc_datasetcnt;
-#endif
-
-/*
- * Macro to keep tabs on dataset memory usage.
- */
-#ifdef DEBUG
-#define RDC_DSMEMUSE(x) \
- mutex_enter(&rdc_cntlock);\
- rdc_datasetcnt += (x);\
- mutex_exit(&rdc_cntlock);
-#else
-#define RDC_DSMEMUSE(x)
-#endif
-
-
-
-
-
-extern kmutex_t rdc_ping_lock;
-extern rdc_if_t *rdc_if_top;
-
-extern int _rdc_enqueue_write(rdc_k_info_t *, nsc_off_t, nsc_size_t, int,
- nsc_buf_t *);
-extern int rdc_net_state(int, int);
-extern int rdc_net_getbmap(int, int);
-extern int rdc_net_getsize(int, uint64_t *);
-extern int rdc_net_write(int, int, nsc_buf_t *, nsc_off_t, nsc_size_t, uint_t,
- int, netwriteres *);
-extern int rdc_net_read(int, int, nsc_buf_t *, nsc_off_t, nsc_size_t);
-extern int _rdc_remote_read(rdc_k_info_t *, nsc_buf_t *, nsc_off_t, nsc_size_t,
- int);
-extern int _rdc_multi_write(nsc_buf_t *, nsc_off_t, nsc_size_t, int,
- rdc_k_info_t *);
-extern int rdc_start_server(struct rdc_svc_args *, int);
-extern aio_buf_t *rdc_aio_buf_get(rdc_buf_t *, int);
-extern void rdc_aio_buf_del(rdc_buf_t *, rdc_k_info_t *);
-extern aio_buf_t *rdc_aio_buf_add(int, rdc_buf_t *);
-extern int rdc_net_getstate(rdc_k_info_t *, int *, int *, int *, int);
-extern kmutex_t rdc_conf_lock;
-extern kmutex_t rdc_many_lock;
-extern int rdc_drain_queue(int);
-extern int flush_group_queue(int);
-extern void rdc_dev_close(rdc_k_info_t *);
-extern int rdc_dev_open(rdc_set_t *, int);
-extern void rdc_get_details(rdc_k_info_t *);
-extern int rdc_lookup_bitmap(char *);
-extern int rdc_lookup_enabled(char *, int);
-extern int rdc_lookup_byaddr(rdc_set_t *);
-extern int rdc_lookup_byname(rdc_set_t *);
-extern int rdc_intercept(rdc_k_info_t *);
-extern int rdc_unintercept(rdc_k_info_t *);
-extern int _rdc_rsrv_devs(rdc_k_info_t *, int, int);
-extern void _rdc_rlse_devs(rdc_k_info_t *, int);
-extern void _rdc_unload(void);
-extern int _rdc_load(void);
-extern int _rdc_configure(void);
-extern void _rdc_deconfigure(void);
-extern void _rdc_async_throttle(rdc_k_info_t *, long);
-extern int rdc_writer(int);
-extern int rdc_dump_alloc_bufs_cd(int);
-extern void rdc_dump_alloc_bufs(rdc_if_t *);
-extern int rdc_check_secondary(rdc_if_t *, int);
-extern void rdc_dump_queue(int);
-extern int rdc_isactive_if(struct netbuf *, struct netbuf *);
-extern rdc_if_t *rdc_add_to_if(rdc_srv_t *, struct netbuf *, struct netbuf *,
- int);
-extern void rdc_remove_from_if(rdc_if_t *);
-extern void rdc_set_if_vers(rdc_u_info_t *, rpcvers_t);
-
-extern void rdc_print_svinfo(rdc_srv_t *, char *);
-extern rdc_srv_t *rdc_create_svinfo(char *, struct netbuf *,
- struct knetconfig *);
-extern void rdc_destroy_svinfo(rdc_srv_t *);
-
-extern void init_rdc_netbuf(struct netbuf *);
-extern void free_rdc_netbuf(struct netbuf *);
-extern void dup_rdc_netbuf(const struct netbuf *, struct netbuf *);
-extern int rdc_netbuf_toint(struct netbuf *);
-extern struct netbuf *rdc_int_tonetbuf(int);
-extern void rdc_lor(const uchar_t *, uchar_t *, int);
-extern int rdc_resume2(rdc_k_info_t *);
-extern void rdc_set_flags(rdc_u_info_t *, int);
-extern void rdc_clr_flags(rdc_u_info_t *, int);
-extern int rdc_get_vflags(rdc_u_info_t *);
-extern void rdc_set_mflags(rdc_u_info_t *, int);
-extern void rdc_clr_mflags(rdc_u_info_t *, int);
-extern int rdc_get_mflags(rdc_u_info_t *);
-extern void rdc_set_flags_log(rdc_u_info_t *, int, char *);
-extern void rdc_group_log(rdc_k_info_t *krdc, int flush, char *why);
-extern int _rdc_config(void *, int, spcs_s_info_t, int *);
-extern void rdc_many_enter(rdc_k_info_t *);
-extern void rdc_many_exit(rdc_k_info_t *);
-extern void rdc_group_enter(rdc_k_info_t *);
-extern void rdc_group_exit(rdc_k_info_t *);
-extern int _rdc_sync_event_wait(void *, void *, int, spcs_s_info_t, int *);
-extern int _rdc_sync_event_notify(int, char *, char *);
-extern int _rdc_link_down(void *, int, spcs_s_info_t, int *);
-extern void rdc_delgroup(rdc_group_t *);
-extern int rdc_write_bitmap_fba(rdc_k_info_t *, nsc_off_t);
-extern int rdc_bitmapset(int, char *, char *, void *, int, nsc_off_t, int);
-extern rdc_net_dataset_t *rdc_net_add_set(int);
-extern rdc_net_dataset_t *rdc_net_get_set(int, int);
-extern void rdc_net_put_set(int, rdc_net_dataset_t *);
-extern void rdc_net_del_set(int, rdc_net_dataset_t *);
-extern void rdc_net_free_set(rdc_k_info_t *, rdc_net_dataset_t *);
-extern int rdc_lookup_byhostdev(char *intf, char *file);
-extern int rdc_lookup_configured(char *path);
-extern void rdc_dump_dsets(int);
-extern void set_busy(rdc_k_info_t *);
-extern void wakeup_busy(rdc_k_info_t *);
-
-
-#ifdef DEBUG
-extern int rdc_async6(void *, int mode, int *);
-extern int rdc_readgen(void *, int, int *);
-#endif
-
-#endif /* _KERNEL */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _RDC_IO_H */
diff --git a/usr/src/uts/common/avs/ns/rdc/rdc_ioctl.h b/usr/src/uts/common/avs/ns/rdc/rdc_ioctl.h
deleted file mode 100644
index ddb6fb5970..0000000000
--- a/usr/src/uts/common/avs/ns/rdc/rdc_ioctl.h
+++ /dev/null
@@ -1,498 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _RDC_IOCTL_H
-#define _RDC_IOCTL_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/unistat/spcs_s.h>
-#include <sys/nsctl/nsctl.h>
-#ifndef DS_DDICT
-#include <rpc/rpc.h>
-#endif
-
-#ifdef _SunOS_5_6
-#define netbuf32 netbuf
-#include <sys/nsctl/model.h>
-#endif
-
-typedef struct _rdc_ioctl_s {
- long arg0;
- long arg1;
- long arg2;
- long arg3;
- long arg4;
- long magic;
- spcs_s_info_t ustatus;
- long pad[1];
-} _rdc_ioctl_t;
-
-#ifdef _SYSCALL32
-typedef struct _rdc_ioctl32_s {
- int32_t arg0;
- int32_t arg1;
- int32_t arg2;
- int32_t arg3;
- int32_t arg4;
- int32_t magic;
- spcs_s_info32_t ustatus;
- int32_t pad[1];
-} _rdc_ioctl32_t;
-#endif /* _SYSCALL32 */
-
-/*
- * Ioctl command numbers
- */
-
-#define _RDCI_(x) (('R'<<16)|('D'<<8)|(x))
-
-/*
- * Generic rdc ioctl arguments structure.
- * Individual ioctl's will use 0-n of these arguments.
- *
- * Each rdc ioctl is described first by the command number
- * e.g. #define RDC_CONFIG _RDCI_(0)
- *
- * Followed by a description of each argument (if any).
- * Each argument is on a single line.
- *
- */
-
-#define RDC_CONFIG _RDCI_(0)
-/*
- * rdc_config_t *user_configuration;
- */
-
-#define RDC_ENABLE_SVR _RDCI_(1)
-/*
- * rdc_svc_args_t *daemon_configuration;
- */
-
-#define RDC_STATUS _RDCI_(2)
-/*
- * rdc_status_t *rdc_status;
- */
-
-#define RDC_VERSION _RDCI_(3)
-/*
- * rdc_version_t *rdc_version;
- */
-
-#define RDC_LINK_DOWN _RDCI_(4)
-/*
- * char *rdc_host;
- */
-
-#define RDC_SYNC_EVENT _RDCI_(5)
-/*
- * char *rdc_master;
- * char *rdc_group;
- */
-
-#define RDC_POOL_CREATE _RDCI_(6)
-/*
- * struct svcpool_args *
- */
-
-#define RDC_POOL_WAIT _RDCI_(7)
-/*
- * int id
- */
-
-#define RDC_POOL_RUN _RDCI_(8)
-/*
- * int id
- */
-#define RDC_BITMAPOP _RDCI_(9)
-
-#ifdef DEBUG
-#define RDC_ASYNC6 _RDCI_(20) /* send async message by hand */
-#define RDC_CLRKSTAT _RDCI_(21) /* clear kstat_io structure */
-#define RDC_STALL0 _RDCI_(22) /* stall sequence 0 on server */
-#define RDC_READGEN _RDCI_(23) /* cause a read on server */
-#endif
-
-
-#define MAX_RDC_HOST_SIZE 64
-
-/*
- * Change this when the ioctl structure changes
- */
-#define RDC_MAGIC 0xf00d0001
-
-typedef struct rdc_addr {
- struct netbuf addr;
- char intf[MAX_RDC_HOST_SIZE];
- char file[NSC_MAXPATH];
- char bitmap[NSC_MAXPATH];
-} rdc_addr_t;
-
-#ifdef _SYSCALL32
-struct rdc_addr32 {
- struct netbuf32 addr;
- char intf[MAX_RDC_HOST_SIZE];
- char file[NSC_MAXPATH];
- char bitmap[NSC_MAXPATH];
-};
-#endif /* _SYSCALL32 */
-
-/*
- * User level rdc set structure - must be a multiple of 64bits long.
- */
-typedef struct rdc_set {
- rdc_addr_t primary;
- rdc_addr_t secondary;
- struct knetconfig *netconfig;
- long align1;
- double alignfix;
- int flags; /* See RDC flags below */
- int sync_flags; /* See RDC flags below */
- int bmap_flags; /* See RDC flags below */
- int mflags; /* RDC 1-to-many flags */
- int index; /* 0 .. rdc_max_sets - 1 */
- int bits_set; /* Bits set in bitmap */
- int autosync; /* Autosync on (1) or off (0) */
- int syshostid; /* for cluster integration */
- int asyncthr; /* # of async threads */
- int setid; /* unique set id for this set */
- uint64_t sync_pos; /* Progress through sync */
- uint64_t volume_size; /* Size of volume */
- int64_t maxqfbas; /* max # of fbas on async q */
- int64_t maxqitems; /* max # of items on async q */
- char group_name[NSC_MAXPATH]; /* Group the set belongs to */
- char direct_file[NSC_MAXPATH]; /* Local FCAL direct io file */
- char disk_queue[NSC_MAXPATH]; /* Disk Queue for set|group */
-} rdc_set_t;
-
-#ifdef _SYSCALL32
-struct rdc_set32 {
- struct rdc_addr32 primary;
- struct rdc_addr32 secondary;
- caddr32_t netconfig;
- int32_t align1;
- double alignfix;
- int32_t flags; /* See RDC flags below */
- int32_t sync_flags; /* See RDC flags below */
- int32_t bmap_flags; /* See RDC flags below */
- int32_t mflags; /* RDC 1-to-many flags */
- int32_t index; /* 0 .. rdc_max_sets - 1 */
- int32_t bits_set; /* Bits set in bitmap */
- int32_t autosync; /* Autosync on (1) or off (0) */
- int32_t syshostid; /* for cluster integration */
- int32_t asyncthr; /* # of async threads */
- int32_t setid; /* unique set id for this set */
- uint64_t sync_pos; /* Progress through sync */
- uint64_t volume_size; /* Size of volume */
- int64_t maxqfbas; /* max # of fbas on async q */
- int64_t maxqitems; /* max # of items on async q */
- char group_name[NSC_MAXPATH]; /* Group the set belongs to */
- char direct_file[NSC_MAXPATH]; /* Local FCAL direct io file */
- char disk_queue[NSC_MAXPATH]; /* Disk Queue for set|group */
-};
-#endif /* _SYSCALL32 */
-
-/*
- * Parameter structure to pass to RDC_CONFIG
- */
-
-typedef struct rdc_config {
- int command; /* RDC_CMD_XXX */
- int options; /* RDC_OPT_XXX */
- int pad[2]; /* Do NOT remove - 32/64-bit padding */
- rdc_set_t rdc_set[1]; /* The rdc sets */
-} rdc_config_t;
-
-#ifdef _SYSCALL32
-struct rdc_config32 {
- int32_t command; /* RDC_CMD_XXX */
- int32_t options; /* RDC_OPT_XXX */
- int32_t pad[2]; /* Do NOT remove - 32/64-bit padding */
- struct rdc_set32 rdc_set[1]; /* The rdc sets */
-};
-#endif /* _SYSCALL32 */
-
-#define RDC_BITMAPSET 0x01
-#define RDC_BITMAPOR 0x02
-typedef struct rdc_bitmap_op {
- nsc_off_t offset; /* byte offset within bitmap mod fba */
- int32_t op; /* or/set operation */
- char sechost[MAX_RDC_HOST_SIZE];
- char secfile[NSC_MAXPATH];
- int32_t len; /* length of bitmap in bytes */
- unsigned long addr; /* address of bitmap in userland */
-} rdc_bitmap_op_t;
-
-#ifdef _SYSCALL32
-typedef struct rdc_bitmap_op32 {
- nsc_off_t offset;
- int32_t op;
- char sechost[MAX_RDC_HOST_SIZE];
- char secfile[NSC_MAXPATH];
- int32_t len;
- uint32_t addr;
-} rdc_bitmap_op32_t;
-
-#endif /* _SYSCALL32 */
-
-#ifdef DEBUG
-/*
- * structure to initiate an asynchronous send to the secondary,
- * so we can test the queuing code.
- */
-typedef struct rdc_async6 {
- char sechost[MAX_RDC_HOST_SIZE];
- char secfile[NSC_MAXPATH];
- int pos; /* Position in file */
- int len;
- int seq;
- int pat; /* fill data with this */
- int idx; /* server returned index */
- int spos; /* sub task start block */
- int slen; /* sub task length */
- int endind; /* set when last block in multi request */
-} rdc_async6_t;
-/*
- * structure to initiate a read on the secondary, so we can test the
- * maxfba break up code.
- */
-typedef struct rdc_readgen {
- char sechost[MAX_RDC_HOST_SIZE];
- char secfile[NSC_MAXPATH];
- int len;
- int pos;
- int idx;
- int flag;
- int rpcversion;
- void *data; /* where to place the data from the read */
-} rdc_readgen_t;
-
-#ifdef _SYSCALL32
-typedef struct rdc_readgen32 {
- char sechost[MAX_RDC_HOST_SIZE];
- char secfile[NSC_MAXPATH];
- int len;
- int pos;
- int idx;
- int flag;
- int rpcversion;
- caddr32_t data; /* where to place the data from the read */
-} rdc_readgen32_t;
-#endif
-#endif
-
-
-
-
-
-/*
- * Config ioctl commands
- */
-#define RDC_CMD_ENABLE 1 /* New enable */
-#define RDC_CMD_DISABLE 2 /* Complete disable */
-#define RDC_CMD_RESUME 3 /* Local re-enable */
-#define RDC_CMD_SUSPEND 4 /* Local clear */
-#define RDC_CMD_LOG 5 /* Start logging mode */
-#define RDC_CMD_COPY 6 /* Start synching */
-#define RDC_CMD_RECONFIG 7 /* Change the rdc set */
-#define RDC_CMD_TUNABLE 8 /* Change a tunable parameter */
-#define RDC_CMD_WAIT 9 /* Wait for syncs to complete */
-#define RDC_CMD_HEALTH 10 /* Return health state */
-#define RDC_CMD_STATUS 11 /* Single set status */
-#define RDC_CMD_RESET 12 /* reset error or failed status */
-#define RDC_CMD_INITQ 14 /* initialise the disk queue */
-#define RDC_CMD_FLUSHQ 15 /* flush queue for set */
-#define RDC_CMD_ADDQ 16 /* add diskq to a set/group */
-#define RDC_CMD_REMQ 17 /* nice remove a diskq from set/grp */
-#define RDC_CMD_KILLQ 18 /* forced disgard of queue */
-#define RDC_CMD_REPQ 19 /* replace queue */
-
-
-
-
-
-/*
- * Config ioctl options
- */
-#define RDC_OPT_SYNC 0x1 /* RDC_CMD_ENABLE, RDC_CMD_RESUME */
-#define RDC_OPT_ASYNC 0x2 /* RDC_CMD_ENABLE, RDC_CMD_RESUME */
-#define RDC_OPT_PRIMARY 0x4 /* All */
-#define RDC_OPT_SECONDARY 0x8 /* All */
-#define RDC_OPT_FORWARD 0x10 /* RDC_CMD_COPY */
-#define RDC_OPT_REVERSE 0x20 /* RDC_CMD_COPY */
-#define RDC_OPT_FULL 0x40 /* RDC_CMD_COPY */
-#define RDC_OPT_UPDATE 0x80 /* RDC_CMD_COPY */
-#define RDC_OPT_SETBMP 0x100 /* RDC_CMD_ENABLE */
-#define RDC_OPT_CLRBMP 0x200 /* RDC_CMD_ENABLE */
-#define RDC_OPT_REVERSE_ROLE 0x400 /* RDC_CMD_RECONFIG */
-#define RDC_OPT_FORCE_QINIT 0x800 /* RDC_CMD_INITQ */
-#define RDC_OPT_SET_QNOBLOCK 0x1000 /* RDC_CMD_TUNABLE */
-#define RDC_OPT_CLR_QNOBLOCK 0x2000 /* RDC_CMD_TUNABLE */
-#define RDC_OPT_FORCE_DISABLE 0x4000 /* RDC_CMD_DISABLE */
-
-/*
- * RDC flags
- */
-
-/*
- * Passed out by the kernel (status)
- */
-#define RDC_ENABLED 0x2 /* RDC enabled */
-#define RDC_PRIMARY 0x4 /* This node is the primary */
-#define RDC_SLAVE 0x8 /* This node is target of the synch */
-#define RDC_VOL_FAILED 0x10 /* Volume is failed */
-#define RDC_BMP_FAILED 0x20 /* Bitmap is failed */
-#define RDC_SYNC_NEEDED 0x40 /* Sync is needed */
-#define RDC_RSYNC_NEEDED 0x80 /* Reverse sync is needed */
-#define RDC_SYNCING 0x100 /* Synch in progress */
-#define RDC_LOGGING 0x200 /* Logging */
-#define RDC_FCAL_FAILED 0x400 /* Direct remote I/O failed */
-#define RDC_ASYNC 0x800 /* Set is in async replicating mode */
-#define RDC_FULL 0x1000 /* Full sync, not an update */
-#define RDC_CLR_AFTERSYNC 0x2000 /* clr bitmap on secondary after sync */
-#define RDC_DISKQ_FAILED 0x4000 /* Diskq I/O has failed */
-#define RDC_QUEUING 0x8000 /* logging, but queueing to disk */
-#ifndef RDC_QNOBLOCK
-#define RDC_QNOBLOCK 0x10000
-#endif
-#define RDC_SYNC_START 0
-#define RDC_SYNC_DONE 1
-#define RDC_RSYNC_START 2
-
-#ifdef _KERNEL
-
-/*
- * urdc->flags vs urdc->mflags usage:
- *
- * All flags are valid in urdc->flags, in which case the condition
- * holds for the specific urdc.
- *
- * The flags in RDC_MFLAGS can also be in urdc->mflags, in which case
- * the condition holds for a urdc somewhere on the many/multi chains
- * connected to this urdc.
- */
-
-#define RDC_GROUP 0x7f8 /* Volume states that affect a group */
-
-/*
- * Mask of volume flags that are valid in urdc->mflags
- */
-#define RDC_MFLAGS (RDC_SLAVE | RDC_RSYNC_NEEDED)
-
-#define IS_SLAVE(urdc) (rdc_get_mflags(urdc) & RDC_SLAVE)
-
-/*
- * Mask of volume flags that are maintained in sync_flags not flags,
- * and protected by rdc_many_lock rather than the group lock.
- * This allows code that is operating on one set to change the flags
- * of another set.
- */
-#define RDC_SFLAGS (RDC_SYNC_NEEDED | RDC_RSYNC_NEEDED | \
- RDC_VOL_FAILED | RDC_CLR_AFTERSYNC)
-
-/*
- * Mask of volume flags that are maintained in bmap_flags not flags,
- * and protected by the bmapmutex rather than the group lock.
- */
-#define RDC_BFLAGS RDC_BMP_FAILED
-
-#define RDC_VFLAGS (~(RDC_SFLAGS | RDC_BFLAGS))
-
-#define RDC_SYNC_STATE_FLAGS (RDC_LOGGING | RDC_SYNCING | RDC_QUEUING | \
- RDC_ASYNC)
-
-#define IS_ASYNC(urdc) (rdc_get_vflags(urdc) & RDC_ASYNC)
-#define IS_PRIMARY(urdc) (rdc_get_vflags(urdc) & RDC_PRIMARY)
-#define IS_SECONDARY(urdc) (!IS_PRIMARY(urdc))
-#define IS_STATE(urdc, state) (rdc_get_vflags(urdc) & (state))
-#define IS_REPLICATING(urdc) (!(rdc_get_vflags(urdc) & RDC_LOGGING) && \
- !(rdc_get_vflags(urdc) & RDC_SYNCING))
-
-#endif /* _KERNEL */
-
-typedef struct rdc_status {
- int nset; /* Number of sets requested/enabled */
- int maxsets; /* Max # of sets allowed today */
- rdc_set_t rdc_set[1];
-} rdc_status_t;
-
-#ifdef _SYSCALL32
-struct rdc_status32 {
- int32_t nset; /* Number of sets requested/enabled */
- int32_t maxsets; /* Max # of sets allowed today */
- struct rdc_set32 rdc_set[1];
-};
-#endif /* _SYSCALL32 */
-
-typedef struct rdc_svc_args {
- int fd; /* Connection endpoint */
- int nthr; /* Number of server threads */
- char netid[128]; /* Identify transport */
- struct netbuf addrmask; /* Address mask for host */
-} rdc_svc_args_t;
-
-#ifdef _SYSCALL32
-struct rdc_svc_args32 {
- int32_t fd;
- int32_t nthr;
- char netid[128];
- struct netbuf32 addrmask;
-};
-#endif /* _SYSCALL32 */
-
-typedef struct rdc_version {
- int major; /* Major release number */
- int minor; /* Minor release number */
- int micro; /* Micro release number */
- int baseline; /* Baseline revison number */
-} rdc_version_t;
-#ifdef _SYSCALL32
-typedef struct rdc_version32 {
- int32_t major; /* Major release number */
- int32_t minor; /* Minor release number */
- int32_t micro; /* Micro release number */
- int32_t baseline; /* Baseline revison number */
-} rdc_version32_t;
-#endif
-
-
-#if !defined(_KERNEL)
-
-#define RDC_IOCTL(cmd, a0, a1, a2, a3, a4, ustatus) \
- rdc_ioctl((long)(cmd), (long)(a0), (long)(a1), (long)(a2), \
- (long)(a3), (long)(a4), (ustatus))
-
-extern int rdc_ioctl(long, long, long, long, long, long, spcs_s_info_t);
-extern int rdc_ioctl_simple(long, void *);
-
-#endif /* ! _KERNEL */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _RDC_IOCTL_H */
diff --git a/usr/src/uts/common/avs/ns/rdc/rdc_prot.x b/usr/src/uts/common/avs/ns/rdc/rdc_prot.x
deleted file mode 100644
index cf9055c186..0000000000
--- a/usr/src/uts/common/avs/ns/rdc/rdc_prot.x
+++ /dev/null
@@ -1,390 +0,0 @@
-%/*
-% * CDDL HEADER START
-% *
-% * The contents of this file are subject to the terms of the
-% * Common Development and Distribution License (the "License").
-% * You may not use this file except in compliance with the License.
-% *
-% * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-% * or http://www.opensolaris.org/os/licensing.
-% * See the License for the specific language governing permissions
-% * and limitations under the License.
-% *
-% * When distributing Covered Code, include this CDDL HEADER in each
-% * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-% * If applicable, add the following below this CDDL HEADER, with the
-% * fields enclosed by brackets "[]" replaced with your own identifying
-% * information: Portions Copyright [yyyy] [name of copyright owner]
-% *
-% * CDDL HEADER END
-% */
-%
-%
-%/*
-% * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-% * Use is subject to license terms.
-% */
-%
-%/*
-% * Auto generated from rdc_prot.x
-% */
-%
-%/*
-% * Network Replicator RPC spec
-% */
-
-%
-%/*
-% * We don't define netbuf in RPCL, since it would contain structure member
-% * names that would conflict with the definition of struct netbuf in
-% * <tiuser.h>. Instead we merely declare the XDR routine xdr_netbuf() here,
-% * and implement it ourselves in rpc/rpcb_prot.c.
-% */
-%#ifdef __cplusplus
-%extern "C" bool_t xdr_netbuf(XDR *, struct netbuf *);
-%
-%#elif __STDC__
-%extern bool_t xdr_netbuf(XDR *, struct netbuf *);
-%
-%#else /* K&R C */
-%bool_t xdr_netbuf();
-%
-%#endif /* K&R C */
-const RDC_PORT = 121;
-const RDC_MAXDATA = 32768;
-const RDC_MAXNAMLEN = 64;
-const RDC_BMAPBLKSIZE = 1024;
-const RDC_MAXADDR = 32;
-const RDC_MAXPENDQ = 64;
-
-%/*
-% * Use this to limit the size of the net_pendvec_t array
-% * to ~ 32k
-% */
-const RDC_PENDQLIM = 1365;
-%
-%/*
-% * Error status
-% */
-enum rdcstat {
- RDC_OK = 0,
- RDCERR_PERM = 1,
- RDCERR_NOENT = 2,
- RDCERR_NOMEM = 3
-};
-
-%
-%/*
-%* Set state (V4)
-%*/
-
-struct set_state4 {
- opaque netaddr[RDC_MAXADDR];
- opaque rnetaddr[RDC_MAXADDR];
- int netaddrlen;
- int rnetaddrlen;
- unsigned flag;
- opaque pfile[RDC_MAXNAMLEN];
- opaque sfile[RDC_MAXNAMLEN];
-};
-
-const RDC_XDR_MAXNAMLEN = RDC_MAXNAMLEN;
-
-struct set_state {
- struct netbuf netaddr;
- struct netbuf rnetaddr;
- int netaddrlen;
- int rnetaddrlen;
- unsigned flag;
- string pfile<RDC_XDR_MAXNAMLEN>;
- string sfile<RDC_XDR_MAXNAMLEN>;
-};
-
-%
-%/*
-% * Get size of volume
-% */
-struct getsize {
- int cd;
-};
-
-%
-%/*
-% * Remote read (v5)
-% */
-struct rread {
- int cd;
- int len;
- int pos;
- int idx;
- int flag;
-};
-
-%
-%/*
-% * Remote read (v6)
-% */
-struct rread6 {
- int cd;
- int len;
- u_longlong_t pos;
- int idx;
- int flag;
-};
-
-%
-%/*
-% * status OK from remote read
-% */
-struct readok {
- opaque data<RDC_MAXDATA>;
-};
-union readres switch (rdcstat status) {
-case RDC_OK:
- readok reply;
-default:
- void;
-};
-
-%
-%/*
-% * Initiate bit map scoreboard transfer (v5)
-% */
-struct bmap {
- int cd;
- int dual;
- int size;
-};
-
-%
-%/*
-% * Initiate bit map scoreboard transfer (v6)
-% */
-struct bmap6 {
- int cd;
- int dual;
- u_longlong_t size;
-};
-
-%
-%/*
-% * Scoreboard bitmap data (v5)
-% */
-struct net_bdata {
- int cd;
- int offset;
- int size;
- opaque data<RDC_BMAPBLKSIZE>;
-};
-
-%
-%/*
-% * Scoreboard bitmap data (v6)
-% */
-struct net_bdata6 {
- u_longlong_t offset;
- int size;
- int cd;
- int endoblk;
- opaque data<RDC_BMAPBLKSIZE>;
-};
-
-%
-%/*
-% * Data transfer and allocation (v5)
-% */
-struct net_data5 {
- int local_cd;
- int cd;
- int pos;
- int len;
- int flag;
- int idx;
- int seq;
- int sfba;
- int endoblk;
- int nfba;
- opaque data<RDC_MAXDATA>;
-};
-
-%
-%/*
-% * Data transfer and allocation (v6)
-% */
-struct net_data6 {
- int local_cd;
- int cd;
- u_longlong_t pos;
- u_longlong_t qpos;
- u_longlong_t sfba;
- int nfba;
- int len;
- int flag;
- int idx;
- unsigned int seq;
- int endoblk;
- opaque data<RDC_MAXDATA>;
-};
-
-
-struct net_pendvec {
- u_longlong_t apos;
- u_longlong_t qpos;
- int alen;
- unsigned int seq;
- int pindex;
-};
-typedef net_pendvec net_pendvec_t;
-
-
-
-%/*
-% * results returned from a netwrite request. (v6)
-% * index = index number of request assigned by server when
-% * requests is broken down into smaller chunks.
-% * result = 0 request ok.
-% * result = 1 request is pending.
-% * result < 0 failure, set with -errno.
-% * If the vecdata array is not empty, then it contains
-% * a list of apos and alen
-% * pairs of previously pending requests that have been written.
-% */
-struct netwriteres {
- int index;
- int result;
- unsigned int seq;
- net_pendvec_t vecdata<RDC_PENDQLIM>;
-};
-
-
-
-%
-%/*
-% * Ping
-% */
-struct rdc_ping6 {
- opaque p_ifaddr[RDC_MAXADDR];
- opaque s_ifaddr[RDC_MAXADDR];
-};
-
-struct rdc_ping {
- struct netbuf p_ifaddr;
- struct netbuf s_ifaddr;
-};
-
-
-/*
- * Remote file service routines
- */
-
-program RDC_PROGRAM {
-
- /*
- * This is protocol version 5 that shipped with SNDR 3.1
- * We must support this protocol until (protocol
- * version 7) is released.
- * I.e. N-1 protocol support.
- */
-
- version RDC_VERSION5 {
-
- void
- RDCPROC_NULL(void) = 0;
-
- int
- RDCPROC_GETSIZE(int) = 2;
-
- int
- RDCPROC_WRITE5(net_data5) = 4;
-
- readres
- RDCPROC_READ5(rread) = 5;
-
- int
- RDCPROC_STATE(set_state4) = 7;
-
- int
- RDCPROC_PING4(rdc_ping6) = 8;
-
- int
- RDCPROC_BMAP(net_bmap) = 9;
-
- int
- RDCPROC_BDATA(net_bdata) = 10;
-
- int
- RDCPROC_GETSTATE4(set_state4) = 12;
- } = 5;
-
- /*
- * This is protocol version 6 that shipped with SNDR 3.2
- * We must support this protocol until (protocol
- * version 8) is released.
- * I.e. N-1 protocol support.
- *
- * Changed to support multiple transmitting async threads
- * (sequence numbers and write reply structure)
- * and 64bit datapath.
- */
-
- version RDC_VERSION6 {
-
- void
- RDCPROC_NULL(void) = 0;
-
- u_longlong_t
- RDCPROC_GETSIZE6(int) = 2;
-
- netwriteres
- RDCPROC_WRITE6(net_data6) = 4;
-
- readres
- RDCPROC_READ6(rread6) = 5;
-
- int
- RDCPROC_STATE(set_state4) = 7;
-
- int
- RDCPROC_PING4(rdc_ping6) = 8;
-
- int
- RDCPROC_BMAP6(net_bmap6) = 9;
-
- int
- RDCPROC_BDATA6(net_bdata6) = 10;
-
- int
- RDCPROC_GETSTATE4(set_state4) = 12;
- } = 6;
-
- version RDC_VERSION7 {
-
- void
- RDCPROC_NULL(void) = 0;
-
- u_longlong_t
- RDCPROC_GETSIZE6(int) = 2;
-
- netwriteres
- RDCPROC_WRITE6(net_data6) = 4;
-
- readres
- RDCPROC_READ6(rread6) = 5;
-
- int
- RDCPROC_STATE(set_state) = 7;
-
- int
- RDCPROC_PING4(rdc_ping) = 8;
-
- int
- RDCPROC_BMAP6(net_bmap6) = 9;
-
- int
- RDCPROC_BDATA6(net_bdata6) = 10;
-
- int
- RDCPROC_GETSTATE4(set_state) = 12;
- } = 7;
-
-} = 100143;
diff --git a/usr/src/uts/common/avs/ns/rdc/rdc_stub.c b/usr/src/uts/common/avs/ns/rdc/rdc_stub.c
deleted file mode 100644
index c1ef2dc502..0000000000
--- a/usr/src/uts/common/avs/ns/rdc/rdc_stub.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/cmn_err.h>
-#include <sys/modctl.h>
-#include <sys/errno.h>
-
-#include <rpc/auth.h>
-#include <rpc/svc.h>
-
-#include <sys/nsctl/nsctl.h>
-#include <sys/nsctl/nsvers.h>
-#include "rdc_stub.h"
-
-static void null_dispatch(struct svc_req *req, SVCXPRT *xprt);
-static void (*dispatch)(struct svc_req *, SVCXPRT *) = null_dispatch;
-
-/*
- * Solaris module setup.
- */
-extern struct mod_ops mod_miscops;
-
-static struct modlmisc modlmisc = {
- &mod_miscops, /* Type of module */
- "nws:Remote Mirror kRPC Stub:" ISS_VERSION_STR
-};
-
-static struct modlinkage modlinkage = {
- MODREV_1,
- &modlmisc,
- NULL
-};
-
-
-int
-_init(void)
-{
- return (mod_install(&modlinkage));
-}
-
-
-int
-_fini(void)
-{
- /* unload is forbidden */
- return (EBUSY);
-}
-
-
-int
-_info(struct modinfo *modinfop)
-{
- return (mod_info(&modlinkage, modinfop));
-}
-
-
-/*
- * rdcstub_dispatch is the place holder for rdcsrv_dispatch.
- * rdcsrv registers this function as kRPC dispatch function.
- * If rdcsrv is unloaded (uninstall package), then dispatch
- * is set to null_dispatch
- */
-void
-rdcstub_dispatch(struct svc_req *req, SVCXPRT *xprt)
-{
- (*dispatch)(req, xprt);
-}
-
-/* ARGSUSED */
-static void
-null_dispatch(struct svc_req *req, SVCXPRT *xprt)
-{
- svcerr_noproc(xprt);
-}
-
-void
-rdcstub_set_dispatch(void (*disp)(struct svc_req *, SVCXPRT *))
-{
- ASSERT(disp != NULL);
- dispatch = disp;
-}
-
-void
-rdcstub_unset_dispatch()
-{
- dispatch = null_dispatch;
-}
diff --git a/usr/src/uts/common/avs/ns/rdc/rdc_stub.h b/usr/src/uts/common/avs/ns/rdc/rdc_stub.h
deleted file mode 100644
index 19b71eb4bf..0000000000
--- a/usr/src/uts/common/avs/ns/rdc/rdc_stub.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _RDC_STUB_H
-#define _RDC_STUB_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef _KERNEL
-
-extern void rdcstub_dispatch(struct svc_req *, SVCXPRT *);
-extern void rdcstub_set_dispatch(void (*)(struct svc_req *, SVCXPRT *));
-extern void rdcstub_unset_dispatch();
-
-#endif /* _KERNEL */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _RDC_STUB_H */
diff --git a/usr/src/uts/common/avs/ns/rdc/rdc_subr.c b/usr/src/uts/common/avs/ns/rdc/rdc_subr.c
deleted file mode 100644
index de5e1dd50a..0000000000
--- a/usr/src/uts/common/avs/ns/rdc/rdc_subr.c
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/ksynch.h>
-#include <sys/errno.h>
-#include <sys/debug.h>
-#include <sys/cmn_err.h>
-#include <sys/kmem.h>
-#include <sys/errno.h>
-
-#ifdef _SunOS_2_6
-/*
- * on 2.6 both dki_lock.h and rpc/types.h define bool_t so we
- * define enum_t here as it is all we need from rpc/types.h
- * anyway and make it look like we included it. Yuck.
- */
-#define _RPC_TYPES_H
-typedef int enum_t;
-#else
-#ifndef DS_DDICT
-#include <rpc/types.h>
-#endif
-#endif /* _SunOS_2_6 */
-
-#include <sys/nsc_thread.h>
-#include <sys/nsctl/nsctl.h>
-#include "rdc_io.h"
-#include "rdc_ioctl.h"
-#include "rdc_prot.h"
-
-/*
- * Initialize a netbuf suitable for
- * describing an address
- */
-
-void
-init_rdc_netbuf(struct netbuf *nbuf)
-{
- nbuf->buf = kmem_zalloc(RDC_MAXADDR, KM_SLEEP);
- nbuf->maxlen = RDC_MAXADDR;
- nbuf->len = 0;
-}
-
-/*
- * Free a netbuf
- */
-
-void
-free_rdc_netbuf(struct netbuf *nbuf)
-{
- if (!(nbuf) || !(nbuf->buf)) {
-#ifdef DEBUG
- cmn_err(CE_PANIC, "Null netbuf in free_rdc_netbuf");
-#endif
- return;
- }
- kmem_free(nbuf->buf, nbuf->maxlen);
- nbuf->buf = NULL;
- nbuf->maxlen = 0;
- nbuf->len = 0;
-}
-
-
-/*
- * Duplicate a netbuf, must be followed by a free_rdc_netbuf().
- */
-void
-dup_rdc_netbuf(const struct netbuf *from, struct netbuf *to)
-{
- init_rdc_netbuf(to);
- to->len = from->len;
-
- if (from->len > to->maxlen) {
- cmn_err(CE_WARN, "!dup_rdc_netbuf: from->len %d, to->maxlen %d",
- from->len, to->maxlen);
- }
-
- bcopy(from->buf, to->buf, (size_t)from->len);
-}
-
-
-#ifdef DEBUG
-void
-rdc_print_svinfo(rdc_srv_t *svp, char *str)
-{
- int i;
-
- if (svp == NULL)
- return;
-
- cmn_err(CE_NOTE, "!rdc %s servinfo: %p\n", str, (void *) svp);
-
- if (svp->ri_knconf != NULL) {
- cmn_err(CE_NOTE, "!knconf: semantics %d",
- svp->ri_knconf->knc_semantics);
- cmn_err(CE_NOTE, "! protofmly %s",
- svp->ri_knconf->knc_protofmly);
- cmn_err(CE_NOTE, "! proto %s",
- svp->ri_knconf->knc_proto);
- cmn_err(CE_NOTE, "! rdev %lx",
- svp->ri_knconf->knc_rdev);
- }
-
- for (i = 0; i < svp->ri_addr.len; i++)
- printf("%u ", svp->ri_addr.buf[i]);
-
- cmn_err(CE_NOTE, "!\naddr: len %d buf %p\n",
- svp->ri_addr.len, (void *) svp->ri_addr.buf);
- cmn_err(CE_NOTE, "!host: %s\n", svp->ri_hostname);
-}
-#endif /* DEBUG */
-
-/*
- * Initialize an rdc servinfo
- * Contains all the protocol we need to do a client rpc
- * A chain of rdc_srv_t indicates a one to many
- */
-
-rdc_srv_t *
-rdc_create_svinfo(char *host, struct netbuf *svaddr, struct knetconfig *conf)
-{
- rdc_srv_t *nvp;
- int hlen = strlen(host) + 1;
-
- if (conf == NULL) {
- return (NULL);
- }
-
- if (host == NULL) {
- return (NULL);
- }
-
- nvp = kmem_zalloc(sizeof (*nvp), KM_SLEEP);
- nvp->ri_knconf = kmem_alloc(sizeof (*nvp->ri_knconf), KM_SLEEP);
- nvp->ri_hostname = kmem_zalloc(hlen, KM_SLEEP);
-
- if (nvp == NULL || nvp->ri_hostname == NULL || nvp->ri_knconf == NULL) {
- rdc_destroy_svinfo(nvp);
- return (NULL);
- }
-
- nvp->ri_hostnamelen = hlen;
-
- bcopy((void *)conf, (void *)nvp->ri_knconf, sizeof (*nvp->ri_knconf));
- nvp->ri_knconf->knc_protofmly = kmem_zalloc(KNC_STRSIZE + 1, KM_SLEEP);
- nvp->ri_knconf->knc_proto = kmem_zalloc(KNC_STRSIZE + 1, KM_SLEEP);
-
- if (nvp->ri_knconf->knc_protofmly == NULL ||
- nvp->ri_knconf->knc_proto == NULL) {
- rdc_destroy_svinfo(nvp);
- return (NULL);
-
- }
-
- (void) strncpy(nvp->ri_knconf->knc_protofmly, conf->knc_protofmly,
- KNC_STRSIZE);
- (void) strncpy(nvp->ri_knconf->knc_proto, conf->knc_proto, KNC_STRSIZE);
-
- dup_rdc_netbuf(svaddr, &nvp->ri_addr);
-
- nvp->ri_secdata = NULL; /* For now */
- (void) strncpy(nvp->ri_hostname, host, hlen);
-#ifdef DEBUG_IP
- rdc_print_svinfo(nvp, "!create");
-#endif
- return (nvp);
-}
-
-void
-rdc_destroy_svinfo(rdc_srv_t *svp)
-{
- if (svp == NULL)
- return;
-
- if (svp->ri_addr.buf && svp->ri_addr.maxlen)
- free_rdc_netbuf(&(svp->ri_addr));
-
- if (svp->ri_knconf->knc_protofmly)
- kmem_free(svp->ri_knconf->knc_protofmly, KNC_STRSIZE + 1);
-
- if (svp->ri_knconf->knc_proto)
- kmem_free(svp->ri_knconf->knc_proto, KNC_STRSIZE + 1);
-
- if (svp->ri_knconf)
- kmem_free(svp->ri_knconf, sizeof (*svp->ri_knconf));
-
- kmem_free(svp, sizeof (*svp));
-}
-
-/*
- * rdc_netbuf_toint
- * Returns oldsytle ipv4 RDC ver 3 addresses for RPC protocol from netbuf
- * Note: This would never be called in the case of IPv6 and a program
- * mismatch ie ver 3 to ver 4
- */
-int
-rdc_netbuf_toint(struct netbuf *nb)
-{
- int ret;
- if (nb->len > RDC_MAXADDR)
- cmn_err(CE_NOTE, "!rdc_netbuf_toint: bad size %d", nb->len);
-
- switch (nb->len) {
- case 4:
- bcopy(nb->buf, (char *)&ret, sizeof (int));
- return (ret);
-
- case 8:
- case 16:
- case 32:
- bcopy(&nb->buf[4], (char *)&ret, sizeof (int));
- return (ret);
-
- default:
- cmn_err(CE_NOTE, "!rdc_netbuf_toint: size %d", nb->len);
- }
- return (0);
-}
diff --git a/usr/src/uts/common/avs/ns/rdc/rdc_svc.c b/usr/src/uts/common/avs/ns/rdc/rdc_svc.c
deleted file mode 100644
index ea1425055d..0000000000
--- a/usr/src/uts/common/avs/ns/rdc/rdc_svc.c
+++ /dev/null
@@ -1,3079 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * kRPC Server for sndr
- */
-
-#include <sys/types.h>
-#include <sys/ksynch.h>
-#include <sys/cmn_err.h>
-#include <sys/kmem.h>
-#include <sys/cred.h>
-#include <sys/conf.h>
-#include <sys/stream.h>
-#include <sys/errno.h>
-
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_k.h>
-#include <sys/unistat/spcs_errors.h>
-
-#ifdef _SunOS_2_6
-/*
- * on 2.6 both dki_lock.h and rpc/types.h define bool_t so we
- * define enum_t here as it is all we need from rpc/types.h
- * anyway and make it look like we included it. Yuck.
- */
-#define _RPC_TYPES_H
-typedef int enum_t;
-#else
-#ifndef DS_DDICT
-#include <rpc/types.h>
-#endif
-#endif /* _SunOS_2_6 */
-
-#ifndef DS_DDICT
-#include <rpc/auth.h>
-#include <rpc/svc.h>
-#include <rpc/xdr.h>
-#endif
-#include <sys/ddi.h>
-#include <sys/nsc_thread.h>
-#ifdef DS_DDICT
-#include <sys/nsctl/contract.h>
-#endif
-#include <sys/nsctl/nsctl.h>
-#include <sys/ncall/ncall.h>
-
-#include <sys/sdt.h> /* dtrace is S10 or later */
-
-#include "rdc_io.h"
-#include "rdc_bitmap.h"
-#include "rdcsrv.h"
-
-static rdc_sleepq_t *rdc_newsleepq();
-static void rdc_delsleepq(rdc_sleepq_t *);
-static int rdc_sleepq(rdc_group_t *, rdc_sleepq_t *);
-static int rdc_combywrite(rdc_k_info_t *, nsc_buf_t *);
-static int rdc_writemaxfba(rdc_k_info_t *, rdc_u_info_t *,
- rdc_net_dataset_t *, uint_t, int);
-static void rdc_setbitind(int *, net_pendvec_t *, rdc_net_dataset_t *, uint_t,
- int, int);
-static void rdc_dopending(rdc_group_t *, netwriteres *);
-static nsc_vec_t *rdc_dset2vec(rdc_net_dataset_t *);
-static int rdc_combyread(rdc_k_info_t *, rdc_u_info_t *, nsc_buf_t *);
-static int rdc_readmaxfba(int, nsc_off_t, nsc_size_t, int);
-static int rdc_dsetcopy(rdc_net_dataset_t *, nsc_vec_t *, nsc_off_t, nsc_size_t,
- char *, int, int);
-
-/* direction for dsetcopy() */
-#define COPY_IN 1 /* copy data into the rpc buffer */
-#define COPY_OUT 2 /* copy data out of the rpc buffer */
-
-#define MAX_EINTR_COUNT 1000
-
-static int rdc_rread_slow;
-static rdcsrv_t rdc_srvtab[];
-
-#ifdef DEBUG
-static int rdc_netwrite6;
-static int rdc_stall0;
-static int rdc_sleepcnt;
-int rdc_datasetcnt;
-#endif
-
-
-int
-_rdc_sync_event_notify(int operation, char *volume, char *group)
-{
- int ack = 0;
- clock_t time;
-
- mutex_enter(&rdc_sync_mutex);
- mutex_enter(&rdc_sync_event.mutex);
-
- if (rdc_sync_event.daemon_waiting) {
- rdc_sync_event.daemon_waiting = 0;
- rdc_sync_event.event = operation;
- (void) strncpy(rdc_sync_event.master, volume, NSC_MAXPATH);
- (void) strncpy(rdc_sync_event.group, group, NSC_MAXPATH);
-
- cv_signal(&rdc_sync_event.cv);
-
- rdc_sync_event.kernel_waiting = 1;
- time = cv_reltimedwait_sig(&rdc_sync_event.done_cv,
- &rdc_sync_event.mutex, rdc_sync_event_timeout,
- TR_CLOCK_TICK);
- if (time == (clock_t)0 || time == (clock_t)-1) {
- /* signalled or timed out */
- ack = 0;
- } else {
- if (rdc_sync_event.ack)
- ack = 1;
- else
- ack = -1;
- }
- }
- mutex_exit(&rdc_sync_event.mutex);
- mutex_exit(&rdc_sync_mutex);
- return (ack);
-}
-
-
-int
-_rdc_sync_event_wait(void *arg0, void *arg1, int mode, spcs_s_info_t kstatus,
- int *rvp)
-{
- int rc = 0;
- static char master[NSC_MAXPATH];
-
- master[0] = '\0';
- *rvp = 0;
- if (ddi_copyin(arg0, master, NSC_MAXPATH, mode))
- return (EFAULT);
-
- mutex_enter(&rdc_sync_event.mutex);
-
- if (rdc_sync_event.kernel_waiting &&
- (rdc_sync_event.lbolt - nsc_lbolt() < rdc_sync_event_timeout)) {
- /* We haven't been away too long */
- if (master[0])
- rdc_sync_event.ack = 1;
- else
- rdc_sync_event.ack = 0;
- rdc_sync_event.kernel_waiting = 0;
- cv_signal(&rdc_sync_event.done_cv);
- }
-
- rdc_sync_event.daemon_waiting = 1;
- if (cv_wait_sig(&rdc_sync_event.cv, &rdc_sync_event.mutex) == 0) {
- rdc_sync_event.daemon_waiting = 0;
- rc = EAGAIN;
- spcs_s_add(kstatus, rc);
- } else {
- (void) ddi_copyout(rdc_sync_event.master, arg0, NSC_MAXPATH,
- mode);
- (void) ddi_copyout(rdc_sync_event.group, arg1, NSC_MAXPATH,
- mode);
- *rvp = rdc_sync_event.event;
- }
- rdc_sync_event.lbolt = nsc_lbolt();
- mutex_exit(&rdc_sync_event.mutex);
-
- return (rc);
-}
-
-
-static int
-rdc_allow_sec_sync(rdc_u_info_t *urdc, int option)
-{
- rdc_k_info_t *krdc = &rdc_k_info[urdc->index];
- rdc_k_info_t *ktmp;
- rdc_u_info_t *utmp;
-
- if (!IS_MULTI(krdc))
- return (0);
-
- rdc_many_enter(krdc);
-
- krdc = krdc->multi_next;
- urdc = &rdc_u_info[krdc->index];
-
- if (!IS_ENABLED(urdc)) {
- rdc_many_exit(krdc);
- return (0);
- }
-
- if (option == CCIO_RSYNC) {
-
- /* Reverse sync */
-
- if (rdc_get_mflags(urdc) & RDC_RSYNC_NEEDED) {
- /*
- * Reverse sync needed or in progress.
- */
- rdc_many_exit(krdc);
- return (-1);
- }
- } else {
- ASSERT(option == CCIO_SLAVE);
-
- /* Forward sync */
-
- if (rdc_get_mflags(urdc) & RDC_SLAVE) {
- /*
- * Reverse syncing is bad, as that means that data
- * is already flowing to the target of the requested
- * sync operation.
- */
- rdc_many_exit(krdc);
- return (-1);
- }
-
- /*
- * Clear "reverse sync needed" on all 1-many volumes.
- * The data on them will be updated from the primary of this
- * requested sync operation, so the aborted reverse sync need
- * not be completed.
- */
-
- if ((rdc_get_mflags(urdc) & RDC_RSYNC_NEEDED) ||
- (rdc_get_vflags(urdc) & RDC_VOL_FAILED)) {
- rdc_clr_mflags(urdc, RDC_RSYNC_NEEDED);
- rdc_clr_flags(urdc, RDC_VOL_FAILED);
- rdc_write_state(urdc);
- }
- if (IS_MANY(krdc)) {
- for (ktmp = krdc->many_next; ktmp != krdc;
- ktmp = ktmp->many_next) {
- utmp = &rdc_u_info[ktmp->index];
- if (!IS_ENABLED(utmp))
- continue;
- if (rdc_get_mflags(utmp) & RDC_RSYNC_NEEDED) {
- rdc_clr_mflags(utmp, RDC_RSYNC_NEEDED);
- rdc_write_state(utmp);
- }
- }
- }
- }
-
- rdc_many_exit(krdc);
-
- return (0);
-}
-
-
-/*
- * r_net_null
- * Proc 0 Null action
- */
-static void
-r_net_null(SVCXPRT *xprt)
-{
- (void) svc_sendreply(xprt, xdr_void, 0);
-}
-
-/*
- * r_net_read
- */
-static void
-r_net_read(SVCXPRT *xprt)
-{
- readres resp;
- rdc_u_info_t *urdc;
- struct rread diskio;
- char *buffer = NULL;
- uchar_t *sv_addr;
- nsc_vec_t *vec;
- int pos, st;
- int nocache;
- int sv_len;
- nsc_vec_t *vector = NULL;
- rdc_net_dataset_t *dset = NULL;
- int vecsz = 0;
-
- st = SVC_GETARGS(xprt, xdr_rread, (char *)&diskio);
- if (!st) {
- (void) svc_sendreply(xprt, xdr_int, (char *)&st);
- return;
- }
- nocache = (diskio.flag & RDC_RREAD_FAIL) ? 0 : NSC_NOCACHE;
-
- if ((diskio.cd >= rdc_max_sets) || (diskio.cd < 0)) {
- resp.rr_status = RDCERR_NOENT;
- (void) svc_sendreply(xprt, xdr_readres, (char *)&resp);
-#ifdef DEBUG
- cmn_err(CE_NOTE,
- "!r_net_read: EPROTO cd out or not enabled");
-#endif
- return;
- }
-
- urdc = &rdc_u_info[diskio.cd];
-
- if (diskio.flag & RDC_RREAD_START) {
- /* setup rpc */
- if (!IS_ENABLED(urdc)) {
- st = 0;
- (void) svc_sendreply(xprt, xdr_int, (char *)&st);
- return;
- }
- st = rdc_readmaxfba(diskio.cd, diskio.pos, diskio.len,
- nocache);
-
- if (!svc_sendreply(xprt, xdr_int, (char *)&st)) {
- if (st != 0) {
- rdc_net_dataset_t *dset;
- if (dset = rdc_net_get_set(diskio.cd, st)) {
- rdc_net_del_set(diskio.cd, dset);
- } else {
- cmn_err(CE_NOTE, "!r_net_read: get_set "
- "has failed in cleanup");
- }
- }
- }
- return;
- }
-
- /* data rpc */
-
-#ifdef DEBUG
- if ((diskio.flag & RDC_RREAD_DATA) == 0) {
- cmn_err(CE_WARN, "!r_net_read: received non-DATA rpc! flag %x",
- diskio.flag);
- }
-#endif
-
- dset = rdc_net_get_set(diskio.cd, diskio.idx);
- if (dset) {
- vector = rdc_dset2vec(dset);
- }
- if (vector == NULL) {
- resp.rr_status = RDCERR_NOMEM;
- (void) svc_sendreply(xprt, xdr_readres, (char *)&resp);
- goto cleanup;
- }
- vecsz = (dset->nitems + 1) * sizeof (nsc_vec_t);
-
- if (!IS_ENABLED(urdc)) {
- resp.rr_status = RDCERR_NOENT;
- (void) svc_sendreply(xprt, xdr_readres, (char *)&resp);
- goto cleanup;
- }
- resp.rr_status = RDC_OK;
-
- /* find place in vector */
- vec = vector;
- pos = diskio.pos - dset->pos;
-
- for (; pos >= FBA_NUM(vec->sv_len); vec++)
- pos -= FBA_NUM(vec->sv_len);
-
- sv_addr = vec->sv_addr + FBA_SIZE(pos);
- sv_len = vec->sv_len - FBA_SIZE(pos);
-
- /*
- * IF the data is in a single sb_vec entry
- * THEN
- * we can just point to that
- * ELSE
- * we have to alloc a local buffer,
- * copy the data in and the point to
- * the local buffer.
- */
-
- if (sv_len >= FBA_SIZE(diskio.len)) {
- /* fast */
- resp.rr_data = (char *)sv_addr;
- resp.rr_bufsize = FBA_SIZE(diskio.len);
- } else {
- /* slow */
- rdc_rread_slow++; /* rough count */
- resp.rr_bufsize = FBA_SIZE(diskio.len);
- buffer = kmem_alloc(resp.rr_bufsize, KM_NOSLEEP);
- if (!buffer) {
- resp.rr_status = RDCERR_NOMEM;
- } else {
- resp.rr_data = buffer;
- if (!rdc_dsetcopy(dset, vector, diskio.pos, diskio.len,
- resp.rr_data, resp.rr_bufsize, COPY_IN)) {
- resp.rr_status = RDCERR_NOMEM; /* ??? */
- }
- }
- }
-
- st = svc_sendreply(xprt, xdr_readres, (char *)&resp); /* send data */
-
-cleanup:
-
- if (dset) {
- if (!st ||
- (diskio.flag & RDC_RREAD_END) ||
- (resp.rr_status != RDC_OK)) {
- /*
- * RPC reply failed, OR
- * Last RPC for this IO operation, OR
- * We are failing this IO operation.
- *
- * Do cleanup.
- */
- rdc_net_del_set(diskio.cd, dset);
- } else {
- rdc_net_put_set(diskio.cd, dset);
- }
- }
-
- if (buffer)
- kmem_free(buffer, resp.rr_bufsize);
- if (vector) {
- kmem_free(vector, vecsz);
- RDC_DSMEMUSE(-vecsz);
- }
-}
-
-/*
- * r_net_read (v6)
- */
-static void
-r_net_read6(SVCXPRT *xprt)
-{
- readres resp;
- rdc_u_info_t *urdc;
- struct rread6 diskio;
- char *buffer = NULL;
- uchar_t *sv_addr;
- nsc_vec_t *vec;
- int pos, st;
- int nocache;
- int sv_len;
- nsc_vec_t *vector = NULL;
- rdc_net_dataset_t *dset = NULL;
- int vecsz = 0;
-
- st = SVC_GETARGS(xprt, xdr_rread6, (char *)&diskio);
- if (!st) {
- (void) svc_sendreply(xprt, xdr_int, (char *)&st);
- return;
- }
- nocache = (diskio.flag & RDC_RREAD_FAIL) ? 0 : NSC_NOCACHE;
-
- if ((diskio.cd >= rdc_max_sets) || (diskio.cd < 0)) {
- resp.rr_status = RDCERR_NOENT;
- (void) svc_sendreply(xprt, xdr_readres, (char *)&resp);
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!r_net_read6: EPROTO cd out or not enabled");
-#endif
- return;
- }
-
- urdc = &rdc_u_info[diskio.cd];
-
- if (diskio.flag & RDC_RREAD_START) {
- /* setup rpc */
- if (!IS_ENABLED(urdc)) {
- st = 0;
- (void) svc_sendreply(xprt, xdr_int, (char *)&st);
- return;
- }
- st = rdc_readmaxfba(diskio.cd, diskio.pos, diskio.len,
- nocache);
-
- if (!svc_sendreply(xprt, xdr_int, (char *)&st)) {
- if (st != 0) {
- rdc_net_dataset_t *dset;
- if (dset = rdc_net_get_set(diskio.cd, st)) {
- rdc_net_del_set(diskio.cd, dset);
- } else {
- cmn_err(CE_NOTE, "!read6: get_set "
- "has failed in cleanup");
- }
- }
- }
- return;
- }
-
- /* data rpc */
-
-#ifdef DEBUG
- if ((diskio.flag & RDC_RREAD_DATA) == 0) {
- cmn_err(CE_WARN, "!read6: received non-DATA rpc! flag %x",
- diskio.flag);
- }
-#endif
-
- dset = rdc_net_get_set(diskio.cd, diskio.idx);
- if (dset) {
- vector = rdc_dset2vec(dset);
- }
- if (vector == NULL) {
- resp.rr_status = RDCERR_NOMEM;
- (void) svc_sendreply(xprt, xdr_readres, (char *)&resp);
- goto cleanup;
- }
- vecsz = (dset->nitems + 1) * sizeof (nsc_vec_t);
-
- if (!IS_ENABLED(urdc)) {
- resp.rr_status = RDCERR_NOENT;
- (void) svc_sendreply(xprt, xdr_readres, (char *)&resp);
- goto cleanup;
- }
- resp.rr_status = RDC_OK;
-
- /* find place in vector */
- vec = vector;
- pos = diskio.pos - dset->pos;
-
- for (; pos >= FBA_NUM(vec->sv_len); vec++)
- pos -= FBA_NUM(vec->sv_len);
-
- sv_addr = vec->sv_addr + FBA_SIZE(pos);
- sv_len = vec->sv_len - FBA_SIZE(pos);
-
- /*
- * IF the data is in a single sb_vec entry
- * THEN
- * we can just point to that
- * ELSE
- * we have to alloc a local buffer,
- * copy the data in and the point to
- * the local buffer.
- */
-
- if (sv_len >= FBA_SIZE(diskio.len)) {
- /* fast */
- resp.rr_data = (char *)sv_addr;
- resp.rr_bufsize = FBA_SIZE(diskio.len);
- } else {
- /* slow */
- rdc_rread_slow++; /* rough count */
- resp.rr_bufsize = FBA_SIZE(diskio.len);
- buffer = kmem_alloc(resp.rr_bufsize, KM_NOSLEEP);
- if (!buffer) {
- resp.rr_status = RDCERR_NOMEM;
- } else {
- resp.rr_data = buffer;
- if (!rdc_dsetcopy(dset, vector, diskio.pos, diskio.len,
- resp.rr_data, resp.rr_bufsize, COPY_IN)) {
- resp.rr_status = RDCERR_NOMEM; /* ??? */
- }
- }
- }
-
- st = svc_sendreply(xprt, xdr_readres, (char *)&resp); /* send data */
-
-cleanup:
-
- if (dset) {
- if (!st ||
- (diskio.flag & RDC_RREAD_END) ||
- (resp.rr_status != RDC_OK)) {
- /*
- * RPC reply failed, OR
- * Last RPC for this IO operation, OR
- * We are failing this IO operation.
- *
- * Do cleanup.
- */
- rdc_net_del_set(diskio.cd, dset);
- } else {
- rdc_net_put_set(diskio.cd, dset);
- }
- }
-
- if (buffer)
- kmem_free(buffer, resp.rr_bufsize);
- if (vector) {
- kmem_free(vector, vecsz);
- RDC_DSMEMUSE(-vecsz);
- }
-}
-
-/*
- * r_net_write (Version 5)
- * 0 reply indicates error
- * >0 reply indicates a net handle index
- * <0 reply indicates errno
- * ret net handle index
- * ret2 general error
- * ret3 multi-hop errors (never returned)
- */
-static void
-r_net_write5(SVCXPRT *xprt)
-{
- rdc_k_info_t *krdc;
- rdc_u_info_t *urdc;
- struct net_data5 diskio;
- rdc_net_dataset_t *dset;
- rdc_net_dataitem_t *ditem;
- int nocache;
- int ret = 0;
- int ret2 = 0;
- int st;
-
- krdc = NULL;
- diskio.data.data_val = kmem_alloc(RDC_MAXDATA, KM_NOSLEEP);
-
- if (!diskio.data.data_val) {
- ret2 = ENOMEM;
- goto out;
- }
- RDC_DSMEMUSE(RDC_MAXDATA);
- st = SVC_GETARGS(xprt, xdr_net_data5, (char *)&diskio);
- if (!st) {
- ret2 = ENOMEM;
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!r_net_write5:SVC_GETARGS failed: st %d", st);
-#endif
- goto out;
- }
- if ((diskio.cd >= rdc_max_sets) || (diskio.cd < 0)) {
- ret2 = EPROTO;
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!r_net_write6: EPROTO cd out or not enabled");
-#endif
- goto out;
- }
-
- nocache = (diskio.flag & RDC_RWRITE_FAIL) ? 0 : NSC_NOCACHE;
- krdc = &rdc_k_info[diskio.cd];
- urdc = &rdc_u_info[diskio.cd];
-
- if (!IS_ENABLED(urdc) || IS_STATE(urdc, RDC_LOGGING)) {
- ret2 = EPROTO;
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!r_net_write6: cd logging / not enabled (%x)",
- rdc_get_vflags(urdc));
-#endif
- krdc = NULL; /* so we don't try to unqueue kstat entry */
- goto out;
- }
-
- if (krdc->io_kstats) {
- mutex_enter(krdc->io_kstats->ks_lock);
- kstat_runq_enter(KSTAT_IO_PTR(krdc->io_kstats));
- mutex_exit(krdc->io_kstats->ks_lock);
- }
-
-
- /* -1 index says allocate a buffer */
- if (diskio.idx < 0) {
- dset = rdc_net_add_set(diskio.cd);
- if (dset == NULL) {
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!r_net_write5: "
- "failed to add dataset");
-#endif
- ret2 = EIO;
- goto out;
- } else {
- ret = dset->id;
- dset->pos = diskio.pos;
- dset->fbalen = diskio.len;
- diskio.idx = ret;
- }
- ditem = kmem_alloc(sizeof (rdc_net_dataitem_t), KM_NOSLEEP);
- if (ditem == NULL) {
- ret2 = ENOMEM;
- goto out;
- }
- RDC_DSMEMUSE(sizeof (rdc_net_dataitem_t));
- /*
- * If this is a single transfer, then we don't
- * need to allocate any memory for the data,
- * just point the ditem data pointer to the
- * existing buffer.
- */
- ditem->next = NULL;
- if (diskio.endoblk) {
- ditem->dptr = diskio.data.data_val;
- /*
- * So we don't free it twice.
- */
- diskio.data.data_val = NULL;
- ditem->len = diskio.data.data_len;
- ditem->mlen = RDC_MAXDATA;
- } else {
- /*
- * Allocate the memory for the complete
- * transfer.
- */
- ditem->dptr = kmem_alloc(FBA_SIZE(diskio.len),
- KM_NOSLEEP);
- if (ditem->dptr == NULL) {
- ret2 = ENOMEM;
- goto out;
- }
- RDC_DSMEMUSE(FBA_SIZE(diskio.len));
- ditem->len = FBA_SIZE(diskio.len);
- ditem->mlen = ditem->len;
-
- /*
- * Copy the data to the new buffer.
- */
- ASSERT(diskio.data.data_len == FBA_SIZE(diskio.nfba));
- bcopy(diskio.data.data_val, ditem->dptr,
- diskio.data.data_len);
- /*
- * free the old data buffer.
- */
- kmem_free(diskio.data.data_val, RDC_MAXDATA);
- RDC_DSMEMUSE(-RDC_MAXDATA);
- diskio.data.data_val = NULL;
- }
- dset->head = ditem;
- dset->tail = ditem;
- dset->nitems++;
- } else {
- ret = diskio.idx;
- dset = rdc_net_get_set(diskio.cd, diskio.idx);
- if (dset == NULL) {
- ret2 = EPROTO;
-#ifdef DEBUG
- cmn_err(CE_NOTE,
- "!r_net_write5: net_get_set failed cd %d idx %d",
- diskio.cd, diskio.idx);
-#endif
- goto out;
- }
- /*
- * We have to copy the data from the rpc buffer
- * to the data in ditem.
- */
- ditem = dset->head;
- bcopy(diskio.data.data_val, (char *)ditem->dptr +
- FBA_SIZE(diskio.sfba - diskio.pos), diskio.data.data_len);
-
- kmem_free(diskio.data.data_val, RDC_MAXDATA);
- RDC_DSMEMUSE(-RDC_MAXDATA);
- diskio.data.data_val = NULL;
- }
- ASSERT(dset);
-
- if (diskio.endoblk) {
- ret2 = rdc_writemaxfba(krdc, urdc, dset, diskio.seq, nocache);
- rdc_net_del_set(diskio.cd, dset);
- dset = NULL;
- }
-out:
- if (!RDC_SUCCESS(ret2)) {
- if (ret2 > 0)
- ret2 = -ret2;
- DTRACE_PROBE1(rdc_svcwrite5_err_ret2, int, ret2);
- st = svc_sendreply(xprt, xdr_int, (char *)&ret2);
- } else
- st = svc_sendreply(xprt, xdr_int, (char *)&ret);
-
- if (krdc && krdc->io_kstats && ret2 != ENOMEM) {
- mutex_enter(krdc->io_kstats->ks_lock);
- kstat_runq_exit(KSTAT_IO_PTR(krdc->io_kstats));
- mutex_exit(krdc->io_kstats->ks_lock);
- }
- /*
- * On Error we must cleanup.
- * If we have a handle, free it.
- * If we have a network handle, free it.
- */
- if (!st || !RDC_SUCCESS(ret2)) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!r_net_write5 error case? st %x ret %d",
- st, ret2);
-#endif
- if (dset) {
- rdc_net_del_set(diskio.cd, dset);
- }
-
- } else {
- if (dset) {
- rdc_net_put_set(diskio.cd, dset);
- }
- }
- if (diskio.data.data_val) {
- kmem_free(diskio.data.data_val, RDC_MAXDATA);
- RDC_DSMEMUSE(-RDC_MAXDATA);
- }
-}
-
-/*
- * r_net_write (Version 6)
- * index 0 = error, or net handle index.
- * result = 0 , ok.
- * result = 1, pending write.
- * result < 0 error, and is the -errno.
- * ret net handle index.
- * ret2 general error.
- */
-static void
-r_net_write6(SVCXPRT *xprt)
-{
- rdc_k_info_t *krdc;
- rdc_u_info_t *urdc;
- rdc_group_t *group;
- struct net_data6 diskio;
- struct netwriteres netret;
- rdc_net_dataset_t *dset;
- rdc_net_dataitem_t *ditem;
- int ret = 0;
- int ret2 = 0;
- int st;
- int nocache;
-
- netret.vecdata.vecdata_val = NULL;
- netret.vecdata.vecdata_len = 0;
- dset = NULL;
- krdc = NULL;
- diskio.data.data_val = kmem_alloc(RDC_MAXDATA, KM_NOSLEEP);
-
- if (!diskio.data.data_val) {
- ret2 = ENOMEM;
- goto out;
- }
- RDC_DSMEMUSE(RDC_MAXDATA);
- st = SVC_GETARGS(xprt, xdr_net_data6, (char *)&diskio);
- if (!st) {
- ret2 = ENOMEM;
-#ifdef DEBUG
- cmn_err(CE_NOTE,
- "!r_net_write6:SVC_GETARGS failed: st %d", st);
-#endif
- goto out;
- }
-
- if ((diskio.cd >= rdc_max_sets) || (diskio.cd < 0)) {
- ret2 = EPROTO;
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!r_net_write6: EPROTO cd out or not enabled");
-#endif
- goto out;
- }
-
- nocache = (diskio.flag & RDC_RWRITE_FAIL) ? 0 : NSC_NOCACHE;
- netret.seq = diskio.seq;
-
- krdc = &rdc_k_info[diskio.cd];
- urdc = &rdc_u_info[diskio.cd];
-
- if (!IS_ENABLED(urdc) || IS_STATE(urdc, RDC_LOGGING)) {
- ret2 = EPROTO;
-#ifdef DEBUG
- cmn_err(CE_NOTE,
- "!r_net_write6: cd logging or not enabled (%x)",
- rdc_get_vflags(urdc));
-#endif
- krdc = NULL; /* so we don't try to unqueue kstat entry */
- goto out;
- }
-
- group = krdc->group;
- if (group == NULL) {
- ret2 = EIO;
-#ifdef DEBUG
- cmn_err(CE_NOTE,
- "!r_net_write6: No group structure for set %s:%s",
- urdc->secondary.intf, urdc->secondary.file);
-#endif
- krdc = NULL; /* so we don't try to unqueue kstat entry */
- goto out;
- }
-
-#ifdef DEBUG
- if (rdc_netwrite6) {
- cmn_err(CE_NOTE,
- "!r_net_write6: idx %d seq %u current seq %u pos %llu "
- "len %d sfba %llu nfba %d endoblk %d",
- diskio.idx, diskio.seq, group->seq,
- (unsigned long long)diskio.pos, diskio.len,
- (unsigned long long)diskio.sfba, diskio.nfba,
- diskio.endoblk);
- }
-#endif
-
- if (krdc->io_kstats) {
- mutex_enter(krdc->io_kstats->ks_lock);
- kstat_runq_enter(KSTAT_IO_PTR(krdc->io_kstats));
- mutex_exit(krdc->io_kstats->ks_lock);
- }
-
- /* -1 index says allocate a net dataset */
- if (diskio.idx < 0) {
- dset = rdc_net_add_set(diskio.cd);
- if (dset == NULL) {
-#ifdef DEBUG
- cmn_err(CE_NOTE,
- "!r_net_write6: failed to add dataset");
-#endif
- ret2 = EIO;
- goto out;
- } else {
- ret = dset->id;
- dset->pos = (nsc_off_t)diskio.pos; /* 64bit! */
- dset->fbalen = diskio.len;
- diskio.idx = ret;
- }
- ditem = kmem_alloc(sizeof (rdc_net_dataitem_t), KM_NOSLEEP);
- if (ditem == NULL) {
- ret2 = ENOMEM;
- goto out;
- }
- RDC_DSMEMUSE(sizeof (rdc_net_dataitem_t));
- /*
- * If this is a single transfer, then we don't
- * need to allocate any memory for the data,
- * just point the ditem data pointer to the
- * existing buffer.
- */
- ditem->next = NULL;
- if (diskio.endoblk) {
- ditem->dptr = diskio.data.data_val;
- /*
- * So we don't free it twice.
- */
- diskio.data.data_val = NULL;
- ditem->len = diskio.data.data_len;
- ditem->mlen = RDC_MAXDATA;
- } else {
- /*
- * Allocate the memory for the complete
- * transfer.
- */
- ditem->dptr = kmem_alloc(FBA_SIZE(diskio.len),
- KM_NOSLEEP);
- if (ditem->dptr == NULL) {
- ret2 = ENOMEM;
- goto out;
- }
- RDC_DSMEMUSE(FBA_SIZE(diskio.len));
- ditem->len = FBA_SIZE(diskio.len);
- ditem->mlen = ditem->len;
-
- /*
- * Copy the data to the new buffer.
- */
- ASSERT(diskio.data.data_len == FBA_SIZE(diskio.nfba));
- bcopy(diskio.data.data_val, ditem->dptr,
- diskio.data.data_len);
- /*
- * free the old data buffer.
- */
- kmem_free(diskio.data.data_val, RDC_MAXDATA);
- RDC_DSMEMUSE(-RDC_MAXDATA);
- diskio.data.data_val = NULL;
- }
- dset->head = ditem;
- dset->tail = ditem;
- dset->nitems++;
- } else {
- ret = diskio.idx;
- dset = rdc_net_get_set(diskio.cd, diskio.idx);
- if (dset == NULL) {
- ret2 = EPROTO;
-#ifdef DEBUG
- cmn_err(CE_NOTE,
- "!r_net_write6: net_get_set failed cd %d idx %d "
- "packet sequence %u expected seq %u",
- diskio.cd, diskio.idx, diskio.seq, group->seq);
-#endif
- goto out;
- }
- /*
- * We have to copy the data from the rpc buffer
- * to the data in ditem.
- */
- ditem = dset->head;
- bcopy(diskio.data.data_val, (char *)ditem->dptr +
- FBA_SIZE(diskio.sfba - diskio.pos), diskio.data.data_len);
-
- kmem_free(diskio.data.data_val, RDC_MAXDATA);
- RDC_DSMEMUSE(-RDC_MAXDATA);
- diskio.data.data_val = NULL;
- }
- ASSERT(dset);
-
- if (diskio.endoblk) {
-#ifdef DEBUG
- if (diskio.seq == (RDC_NEWSEQ + 1)) {
- rdc_stallzero(2);
- }
-#endif
- if (diskio.seq == RDC_NEWSEQ) {
- /*
- * magic marker, start of sequence.
- */
- mutex_enter(&group->ra_queue.net_qlock);
- /*
- * see if some threads are stuck.
- */
- if (group->sleepq) {
- rdc_sleepqdiscard(group);
- }
- group->seqack = RDC_NEWSEQ;
- mutex_exit(&group->ra_queue.net_qlock);
- }
-
- if ((diskio.seq != RDC_NOSEQ) && (diskio.seq != RDC_NEWSEQ)) {
- /*
- * see if we are allowed through here to
- * do the write, or if we have to q the
- * request and send back a pending reply.
- */
- mutex_enter(&group->ra_queue.net_qlock);
- if (diskio.seq != group->seq) {
- rdc_sleepq_t *sq;
- int maxseq;
-
- /*
- * Check that we have room.
- */
- maxseq = group->seqack + RDC_MAXPENDQ + 1;
- if (maxseq < group->seqack) {
- /*
- * skip magic values.
- */
- maxseq += RDC_NEWSEQ + 1;
- }
- if (!RDC_INFRONT(diskio.seq, maxseq)) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!net_write6: Queue "
- "size %d exceeded seqack %u "
- "this seq %u maxseq %u seq %u",
- RDC_MAXPENDQ, group->seqack,
- diskio.seq, maxseq, group->seq);
-#endif
- DTRACE_PROBE2(qsize_exceeded, int, diskio.seq,
- int, maxseq);
- if (!(rdc_get_vflags(urdc) &
- RDC_VOL_FAILED)) {
- rdc_many_enter(krdc);
- rdc_set_flags(urdc,
- RDC_VOL_FAILED);
- rdc_many_exit(krdc);
- rdc_write_state(urdc);
- }
- ret2 = EIO;
- rdc_sleepqdiscard(group);
- group->seq = RDC_NEWSEQ;
- group->seqack = RDC_NEWSEQ;
- mutex_exit(&group->ra_queue.net_qlock);
- goto out;
- }
-
- sq = rdc_newsleepq();
- sq->seq = diskio.seq;
- sq->sindex = diskio.cd;
- sq->pindex = diskio.local_cd;
- sq->idx = diskio.idx;
- sq->qpos = diskio.qpos;
- sq->nocache = nocache;
- if (rdc_sleepq(group, sq)) {
- ret2 = EIO;
- group->seq = RDC_NEWSEQ;
- group->seqack = RDC_NEWSEQ;
- rdc_sleepqdiscard(group);
- mutex_exit(&group->ra_queue.net_qlock);
- goto out;
- }
- rdc_net_put_set(diskio.cd, dset);
- dset = NULL;
- if (krdc->io_kstats) {
- mutex_enter(krdc->io_kstats->ks_lock);
- kstat_waitq_enter(KSTAT_IO_PTR(krdc->
- io_kstats));
- mutex_exit(krdc->io_kstats->ks_lock);
- }
- mutex_exit(&group->ra_queue.net_qlock);
- /*
- * pending state.
- */
- netret.result = 1;
- netret.index = diskio.idx;
- st = svc_sendreply(xprt, xdr_netwriteres,
- (char *)&netret);
- if (krdc->io_kstats && ret2 != ENOMEM) {
- mutex_enter(krdc->io_kstats->ks_lock);
- kstat_runq_exit(KSTAT_IO_PTR(
- krdc->io_kstats));
- mutex_exit(krdc->io_kstats->ks_lock);
- }
- return;
- }
- mutex_exit(&group->ra_queue.net_qlock);
- }
-
- ret2 = rdc_writemaxfba(krdc, urdc, dset, diskio.seq, nocache);
- rdc_net_del_set(diskio.cd, dset);
- dset = NULL;
-#ifdef DEBUG
- if (!RDC_SUCCESS(ret2)) {
- cmn_err(CE_WARN, "!r_net_write6: writemaxfba failed %d",
- ret2);
- }
-#endif
- if (diskio.seq != RDC_NOSEQ) {
- mutex_enter(&group->ra_queue.net_qlock);
- group->seq = diskio.seq + 1;
- if (group->seq < diskio.seq)
- group->seq = RDC_NEWSEQ + 1;
- if (group->sleepq &&
- (group->sleepq->seq == group->seq)) {
- rdc_dopending(group, &netret);
- }
- group->seqack = group->seq;
- mutex_exit(&group->ra_queue.net_qlock);
- }
- }
-out:
- if (!RDC_SUCCESS(ret2)) {
- DTRACE_PROBE1(rdc_svcwrite6_err_ret2, int, ret2);
- netret.result = -ret2;
- } else {
- netret.result = 0;
- netret.index = ret;
- }
- st = svc_sendreply(xprt, xdr_netwriteres, (char *)&netret);
- if (netret.vecdata.vecdata_val) {
- kmem_free(netret.vecdata.vecdata_val,
- netret.vecdata.vecdata_len * sizeof (net_pendvec_t));
- }
- if (krdc && krdc->io_kstats && ret2 != ENOMEM) {
- mutex_enter(krdc->io_kstats->ks_lock);
- kstat_runq_exit(KSTAT_IO_PTR(krdc->io_kstats));
- mutex_exit(krdc->io_kstats->ks_lock);
- }
- /*
- * On Error we must cleanup.
- * If we have a handle, free it.
- * If we have a network handle, free it.
- * If we hold the main nsc buffer, free it.
- */
- if (!st || !RDC_SUCCESS(ret2)) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!r_net_write6 error st %x ret %d seq %u",
- st, ret2, diskio.seq);
-#endif
- if (dset) {
- rdc_net_del_set(diskio.cd, dset);
- }
- } else {
- if (dset) {
- rdc_net_put_set(diskio.cd, dset);
- }
- }
- if (diskio.data.data_val) {
- kmem_free(diskio.data.data_val, RDC_MAXDATA);
- RDC_DSMEMUSE(-RDC_MAXDATA);
- }
-}
-
-/*
- * r_net_ping4
- *
- * received on the primary.
- */
-static void
-r_net_ping4(SVCXPRT *xprt, struct svc_req *req)
-{
- struct rdc_ping6 ping;
- int e, ret = 0;
- rdc_if_t *ip;
-
- e = SVC_GETARGS(xprt, xdr_rdc_ping6, (char *)&ping);
- if (e) {
- mutex_enter(&rdc_ping_lock);
-
- /* update specified interface */
-
- for (ip = rdc_if_top; ip; ip = ip->next) {
- if ((bcmp(ping.p_ifaddr, ip->ifaddr.buf,
- RDC_MAXADDR) == 0) &&
- (bcmp(ping.s_ifaddr, ip->r_ifaddr.buf,
- RDC_MAXADDR) == 0)) {
- ip->new_pulse++;
- ip->deadness = 1;
-
- /* Update the rpc protocol version to use */
-
- ip->rpc_version = req->rq_vers;
- break;
- }
- }
-
- mutex_exit(&rdc_ping_lock);
- } else {
- svcerr_decode(xprt);
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!SNDR: couldn't get ping4 arguments");
-#endif
- }
-
- (void) svc_sendreply(xprt, xdr_int, (char *)&ret);
-}
-
-/*
- * r_net_ping7
- *
- * received on the primary.
- */
-static void
-r_net_ping7(SVCXPRT *xprt, struct svc_req *req)
-{
- struct rdc_ping ping;
- int e, ret = 0;
- rdc_if_t *ip;
- unsigned short *sp;
-
- bzero(&ping, sizeof (struct rdc_ping));
- e = SVC_GETARGS(xprt, xdr_rdc_ping, (char *)&ping);
- if (e) {
- sp = (unsigned short *)ping.p_ifaddr.buf;
- *sp = ntohs(*sp);
- sp = (unsigned short *)ping.s_ifaddr.buf;
- *sp = ntohs(*sp);
- mutex_enter(&rdc_ping_lock);
-
- /* update specified interface */
-
- for (ip = rdc_if_top; ip; ip = ip->next) {
- if ((bcmp(ping.p_ifaddr.buf, ip->ifaddr.buf,
- ping.p_ifaddr.len) == 0) &&
- (bcmp(ping.s_ifaddr.buf, ip->r_ifaddr.buf,
- ping.s_ifaddr.len) == 0)) {
- ip->new_pulse++;
- ip->deadness = 1;
-
- /* Update the rpc protocol version to use */
-
- ip->rpc_version = req->rq_vers;
- break;
- }
- }
-
- mutex_exit(&rdc_ping_lock);
- } else {
- svcerr_decode(xprt);
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!SNDR: couldn't get ping7 arguments");
-#endif
- }
-
- (void) svc_sendreply(xprt, xdr_int, (char *)&ret);
-}
-
-
-/*
- * r_net_bmap (v5)
- * WARNING acts as both client and server
- */
-static void
-r_net_bmap(SVCXPRT *xprt)
-{
- int e, ret = EINVAL;
- struct bmap b;
- rdc_k_info_t *krdc;
- rdc_u_info_t *urdc;
- struct bmap6 b6;
-
-
- e = SVC_GETARGS(xprt, xdr_bmap, (char *)&b);
- if (e == TRUE) {
- krdc = &rdc_k_info[b.cd];
- urdc = &rdc_u_info[b.cd];
- if (b.cd >= 0 && b.cd < rdc_max_sets && IS_ENABLED(urdc) &&
- ((krdc->type_flag & RDC_DISABLEPEND) == 0)) {
- krdc->rpc_version = RDC_VERSION5;
- b6.cd = b.cd;
- b6.dual = b.dual;
- b6.size = b.size;
- ret = RDC_SEND_BITMAP(&b6);
- }
- }
-
- (void) svc_sendreply(xprt, xdr_int, (char *)&ret);
-}
-
-/*
- * r_net_bmap (v6)
- * WARNING acts as both client and server
- */
-static void
-r_net_bmap6(SVCXPRT *xprt)
-{
- int e, ret = EINVAL;
- struct bmap6 b;
- rdc_k_info_t *krdc;
- rdc_u_info_t *urdc;
-
- e = SVC_GETARGS(xprt, xdr_bmap6, (char *)&b);
- if (e == TRUE) {
- krdc = &rdc_k_info[b.cd];
- urdc = &rdc_u_info[b.cd];
- if (b.cd >= 0 && b.cd < rdc_max_sets && IS_ENABLED(urdc) &&
- ((krdc->type_flag & RDC_DISABLEPEND) == 0)) {
- krdc->rpc_version = RDC_VERSION6;
- ret = RDC_SEND_BITMAP(&b);
- }
- }
- /*
- * If the bitmap send has succeeded, clear it.
- */
- if (ret == 0) {
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!Bitmap clear in r_net_bmap6");
-#endif
- RDC_ZERO_BITMAP(krdc);
- rdc_many_enter(krdc);
- rdc_clr_flags(urdc, RDC_CLR_AFTERSYNC);
- rdc_many_exit(krdc);
- }
- (void) svc_sendreply(xprt, xdr_int, (char *)&ret);
-}
-
-/*
- * r_net_bdata
- */
-static void
-r_net_bdata(SVCXPRT *xprt)
-{
- struct net_bdata bd;
- struct net_bdata6 bd6;
- int e, ret = -1;
- rdc_k_info_t *krdc;
- rdc_u_info_t *urdc;
-
- /*
- * We have to convert it to the internal form here,
- * net_data6, when we know that we will have to convert
- * it back to the v5 variant for transmission.
- */
-
- bd.data.data_val = kmem_alloc(BMAP_BLKSIZE, KM_NOSLEEP);
- if (bd.data.data_val == NULL)
- goto out;
-
- e = SVC_GETARGS(xprt, xdr_net_bdata, (char *)&bd);
- if (e == TRUE) {
- krdc = &rdc_k_info[bd.cd];
- urdc = &rdc_u_info[bd.cd];
- if (bd.cd >= 0 && bd.cd < rdc_max_sets && IS_ENABLED(urdc) &&
- ((krdc->type_flag & RDC_DISABLEPEND) == 0)) {
- bd6.cd = bd.cd;
- bd6.offset = bd.offset;
- bd6.size = bd.size;
- bd6.data.data_len = bd.data.data_len;
- bd6.data.data_val = bd.data.data_val;
- ret = RDC_OR_BITMAP(&bd6);
- }
- }
- kmem_free(bd.data.data_val, BMAP_BLKSIZE);
-out:
- (void) svc_sendreply(xprt, xdr_int, (char *)&ret);
-}
-
-/*
- * r_net_bdata v6
- */
-static void
-r_net_bdata6(SVCXPRT *xprt)
-{
- struct net_bdata6 bd;
- int e, ret = -1;
- rdc_k_info_t *krdc;
- rdc_u_info_t *urdc;
-
- /*
- * just allocate the bigger block, regardless of < V7
- * bd.size will dictate how much we lor into our bitmap
- * the other option would be write r_net_bdata7 that is identical
- * to this function, but a V7 alloc.
- */
- bd.data.data_val = kmem_alloc(BMAP_BLKSIZEV7, KM_NOSLEEP);
- if (bd.data.data_val == NULL)
- goto out;
-
- e = SVC_GETARGS(xprt, xdr_net_bdata6, (char *)&bd);
- if (e == TRUE) {
- krdc = &rdc_k_info[bd.cd];
- urdc = &rdc_u_info[bd.cd];
- if (bd.cd >= 0 && bd.cd < rdc_max_sets && IS_ENABLED(urdc) &&
- ((krdc->type_flag & RDC_DISABLEPEND) == 0))
- ret = RDC_OR_BITMAP(&bd);
- }
- /*
- * Write the merged bitmap.
- */
- if ((ret == 0) && bd.endoblk && (krdc->bitmap_write > 0)) {
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!r_net_bdata6: Written bitmap for %s:%s",
- urdc->secondary.intf, urdc->secondary.file);
-#endif
- ret = rdc_write_bitmap(krdc);
- }
- kmem_free(bd.data.data_val, BMAP_BLKSIZEV7);
-out:
- (void) svc_sendreply(xprt, xdr_int, (char *)&ret);
-}
-
-/*
- * r_net_getsize (v5)
- */
-static void
-r_net_getsize(SVCXPRT *xprt)
-{
- int e, ret = -1, index;
- rdc_k_info_t *krdc;
-
- e = SVC_GETARGS(xprt, xdr_int, (char *)&index);
- if (e) {
- krdc = &rdc_k_info[index];
- if (IS_VALID_INDEX(index) && ((krdc->type_flag &
- RDC_DISABLEPEND) == 0))
- ret = mirror_getsize(index);
- }
- (void) svc_sendreply(xprt, xdr_int, (char *)&ret);
-}
-
-/*
- * r_net_getsize (v6)
- */
-static void
-r_net_getsize6(SVCXPRT *xprt)
-{
- int e, index;
- rdc_k_info_t *krdc;
- uint64_t ret;
-
- /*
- * small change in semantics here, as we can't return
- * -1 over the wire anymore.
- */
- ret = 0;
-
- e = SVC_GETARGS(xprt, xdr_int, (char *)&index);
- if (e) {
- krdc = &rdc_k_info[index];
- if (IS_VALID_INDEX(index) && ((krdc->type_flag &
- RDC_DISABLEPEND) == 0))
- ret = mirror_getsize(index);
- }
- (void) svc_sendreply(xprt, xdr_u_longlong_t, (char *)&ret);
-}
-
-
-/*
- * r_net_state4
- */
-static void
-r_net_state4(SVCXPRT *xprt)
-{
- rdc_u_info_t *urdc;
- rdc_k_info_t *krdc;
- struct set_state4 state;
- rdc_set_t rdc_set;
- int e, index = -1;
- int options;
- int log = 0;
- int done = 0;
- int slave = 0;
- int rev_sync = 0;
-
- e = SVC_GETARGS(xprt, xdr_set_state4, (char *)&state);
- if (e) {
- init_rdc_netbuf(&(rdc_set.primary.addr));
- init_rdc_netbuf(&(rdc_set.secondary.addr));
- bcopy(state.netaddr, rdc_set.primary.addr.buf,
- state.netaddrlen);
- bcopy(state.rnetaddr, rdc_set.secondary.addr.buf,
- state.rnetaddrlen);
- rdc_set.primary.addr.len = state.netaddrlen;
- rdc_set.secondary.addr.len = state.rnetaddrlen;
- (void) strncpy(rdc_set.primary.file, state.pfile,
- RDC_MAXNAMLEN);
- (void) strncpy(rdc_set.secondary.file, state.sfile,
- RDC_MAXNAMLEN);
- options = state.flag;
- index = rdc_lookup_byaddr(&rdc_set);
-
- krdc = &rdc_k_info[index];
-
- if (index < 0 || (krdc->type_flag & RDC_DISABLEPEND)) {
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!r_net_state: no index or disable pending");
-#endif
- (void) svc_sendreply(xprt, xdr_int, (char *)&index);
- return;
- }
-
- urdc = &rdc_u_info[index];
-
- if (!IS_ENABLED(urdc)) {
- index = -1;
-#ifdef DEBUG
- cmn_err(CE_WARN, "!r_net_state: set not enabled ");
-#endif
- (void) svc_sendreply(xprt, xdr_int, (char *)&index);
- return;
- }
-
- if (krdc->lsrv == NULL) {
- cmn_err(CE_NOTE, "!r_net_state: no valid svp\n");
- index = -1;
- (void) svc_sendreply(xprt, xdr_int, (char *)&index);
- return;
- }
- if (!krdc || !krdc->group) {
-#ifdef DEBUG
- cmn_err(CE_NOTE,
- "!r_net_state: no valid krdc %p\n", (void*)krdc);
-#endif
- index = -1;
- (void) svc_sendreply(xprt, xdr_int, (char *)&index);
- return;
- }
-
- mutex_enter(&rdc_conf_lock);
- if (krdc->type_flag & RDC_DISABLEPEND) {
- mutex_exit(&rdc_conf_lock);
- index = -1;
-#ifdef DEBUG
- cmn_err(CE_WARN, "!r_net_state: disable pending");
-#endif
- (void) svc_sendreply(xprt, xdr_int, (char *)&index);
- return;
- }
- set_busy(krdc);
- mutex_exit(&rdc_conf_lock);
-
- rdc_group_enter(krdc);
-
- if (rdc_get_vflags(urdc) & RDC_PRIMARY)
- krdc->intf = rdc_add_to_if(krdc->lsrv,
- &(urdc->primary.addr), &(urdc->secondary.addr), 1);
- else
- krdc->intf = rdc_add_to_if(krdc->lsrv,
- &(urdc->secondary.addr), &(urdc->primary.addr), 0);
-
- if (options & CCIO_SLAVE) {
- /*
- * mark that the bitmap needs clearing.
- */
- rdc_many_enter(krdc);
- rdc_set_flags(urdc, RDC_CLR_AFTERSYNC);
- rdc_many_exit(krdc);
-
- /* Starting forward sync */
- if (urdc->volume_size == 0)
- rdc_get_details(krdc);
- if (urdc->volume_size == 0) {
- index = -1;
- goto out;
- }
- if (krdc->dcio_bitmap == NULL) {
- if (rdc_resume_bitmap(krdc) < 0) {
- index = -1;
- goto out;
- }
- }
- if (rdc_allow_sec_sync(urdc, CCIO_SLAVE) < 0) {
- index = -1;
- goto out;
- }
- rdc_dump_dsets(index);
- slave = 1;
- } else if (options & CCIO_RSYNC) {
- /*
- * mark that the bitmap needs clearing.
- */
- rdc_many_enter(krdc);
- rdc_set_flags(urdc, RDC_CLR_AFTERSYNC);
- rdc_many_exit(krdc);
-
- /* Starting reverse sync */
- if (rdc_get_vflags(urdc) & (RDC_SYNC_NEEDED |
- RDC_VOL_FAILED | RDC_BMP_FAILED)) {
- index = -1;
- goto out;
- }
- if (rdc_allow_sec_sync(urdc, CCIO_RSYNC) < 0) {
- index = -1;
- goto out;
- }
- rdc_dump_dsets(index);
- rev_sync = 1;
- } else if (options & CCIO_DONE) {
- /* Sync completed OK */
- if (rdc_get_vflags(urdc) & RDC_SYNC_NEEDED)
- done = 1; /* forward sync complete */
- rdc_many_enter(krdc);
- rdc_clr_flags(urdc, RDC_SYNCING | RDC_SYNC_NEEDED);
- rdc_clr_mflags(urdc, RDC_SLAVE | RDC_RSYNC_NEEDED);
- rdc_many_exit(krdc);
- rdc_write_state(urdc);
- if (rdc_get_vflags(urdc) & RDC_CLR_AFTERSYNC) {
- RDC_ZERO_BITMAP(krdc);
- rdc_many_enter(krdc);
- rdc_clr_flags(urdc, RDC_CLR_AFTERSYNC);
- rdc_many_exit(krdc);
- }
- } else if (options & CCIO_ENABLELOG) {
- /* Sync aborted or logging started */
- if (!(rdc_get_vflags(urdc) & RDC_PRIMARY)) {
- rdc_clr_flags(urdc, RDC_SYNCING);
- rdc_many_enter(krdc);
- rdc_clr_mflags(urdc, RDC_SLAVE);
- rdc_many_exit(krdc);
- }
- log = 1;
- }
-out:
- rdc_group_exit(krdc);
- free_rdc_netbuf(&(rdc_set.primary.addr));
- free_rdc_netbuf(&(rdc_set.secondary.addr));
-
- if (slave) {
- if (_rdc_sync_event_notify(RDC_SYNC_START,
- urdc->secondary.file, urdc->group_name) >= 0) {
- rdc_group_enter(krdc);
- rdc_clr_flags(urdc, RDC_LOGGING);
- rdc_many_enter(krdc);
- rdc_clr_flags(urdc, RDC_VOL_FAILED);
- rdc_set_flags(urdc,
- RDC_SYNCING | RDC_SYNC_NEEDED);
- rdc_set_mflags(urdc, RDC_SLAVE);
- rdc_many_exit(krdc);
- rdc_write_state(urdc);
- rdc_group_exit(krdc);
- } else {
- index = -1;
- }
- } else if (rev_sync) {
- /* Check to see if volume is mounted */
- if (_rdc_sync_event_notify(RDC_RSYNC_START,
- urdc->secondary.file, urdc->group_name) >= 0) {
- rdc_group_enter(krdc);
- rdc_clr_flags(urdc, RDC_LOGGING);
- rdc_set_flags(urdc, RDC_SYNCING);
- rdc_write_state(urdc);
- rdc_group_exit(krdc);
- } else {
- index = -1;
- }
- } else if (done) {
-
- /*
- * special case...
- * if this set is in a group, then sndrsyncd will
- * make sure that all sets in the group are REP
- * before updating the config to "update", telling
- * sndrsyncd that it is ok to take anther snapshot
- * on a following sync. The important part about
- * the whole thing is that syncd needs kernel stats.
- * however, this thread must set the set busy to
- * avoid disables. since this is the only
- * sync_event_notify() that will cause a status
- * call back into the kernel, and we will not be
- * accessing the group structure, we have to wakeup now
- */
-
- mutex_enter(&rdc_conf_lock);
- wakeup_busy(krdc);
- mutex_exit(&rdc_conf_lock);
-
- (void) _rdc_sync_event_notify(RDC_SYNC_DONE,
- urdc->secondary.file, urdc->group_name);
- }
- }
-
- if (!done) {
- mutex_enter(&rdc_conf_lock);
- wakeup_busy(krdc);
- mutex_exit(&rdc_conf_lock);
- }
-
- (void) svc_sendreply(xprt, xdr_int, (char *)&index);
- if (log) {
- rdc_group_enter(krdc);
- rdc_group_log(krdc, RDC_NOFLUSH | RDC_OTHERREMOTE,
- "Sync aborted or logging started");
- rdc_group_exit(krdc);
- }
-}
-
-
-/*
- * r_net_state
- */
-static void
-r_net_state(SVCXPRT *xprt)
-{
- rdc_u_info_t *urdc;
- rdc_k_info_t *krdc;
- struct set_state state;
- rdc_set_t rdc_set;
- int e, index = -1;
- int options;
- int log = 0;
- int done = 0;
- int slave = 0;
- int rev_sync = 0;
- unsigned short *sp;
-
- bzero(&state, sizeof (struct set_state));
- e = SVC_GETARGS(xprt, xdr_set_state, (char *)&state);
- if (e) {
- init_rdc_netbuf(&(rdc_set.primary.addr));
- init_rdc_netbuf(&(rdc_set.secondary.addr));
- sp = (unsigned short *)(state.netaddr.buf);
- *sp = ntohs(*sp);
- bcopy(state.netaddr.buf, rdc_set.primary.addr.buf,
- state.netaddrlen);
- sp = (unsigned short *)(state.rnetaddr.buf);
- *sp = ntohs(*sp);
- bcopy(state.rnetaddr.buf, rdc_set.secondary.addr.buf,
- state.rnetaddrlen);
- rdc_set.primary.addr.len = state.netaddrlen;
- rdc_set.secondary.addr.len = state.rnetaddrlen;
- (void) strncpy(rdc_set.primary.file, state.pfile,
- RDC_MAXNAMLEN);
- (void) strncpy(rdc_set.secondary.file, state.sfile,
- RDC_MAXNAMLEN);
- options = state.flag;
- index = rdc_lookup_byaddr(&rdc_set);
-
- krdc = &rdc_k_info[index];
-
- if (index < 0 || (krdc->type_flag & RDC_DISABLEPEND)) {
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!r_net_state: no index or disable pending");
-#endif
- (void) svc_sendreply(xprt, xdr_int, (char *)&index);
- return;
- }
-
- urdc = &rdc_u_info[index];
-
- if (!IS_ENABLED(urdc)) {
- index = -1;
-#ifdef DEBUG
- cmn_err(CE_WARN, "!r_net_state: set not enabled ");
-#endif
- (void) svc_sendreply(xprt, xdr_int, (char *)&index);
- return;
- }
-
- if (krdc->lsrv == NULL) {
- cmn_err(CE_NOTE, "!r_net_state: no valid svp\n");
- index = -1;
- (void) svc_sendreply(xprt, xdr_int, (char *)&index);
- return;
- }
- if (!krdc || !krdc->group) {
-#ifdef DEBUG
- cmn_err(CE_NOTE,
- "!r_net_state: no valid krdc %p\n", (void*)krdc);
-#endif
- index = -1;
- (void) svc_sendreply(xprt, xdr_int, (char *)&index);
- return;
- }
-
- mutex_enter(&rdc_conf_lock);
- if (krdc->type_flag & RDC_DISABLEPEND) {
- mutex_exit(&rdc_conf_lock);
- index = -1;
-#ifdef DEBUG
- cmn_err(CE_WARN, "!r_net_state: disable pending");
-#endif
- (void) svc_sendreply(xprt, xdr_int, (char *)&index);
- return;
- }
- set_busy(krdc);
- mutex_exit(&rdc_conf_lock);
-
- rdc_group_enter(krdc);
-
- if (rdc_get_vflags(urdc) & RDC_PRIMARY)
- krdc->intf = rdc_add_to_if(krdc->lsrv,
- &(urdc->primary.addr), &(urdc->secondary.addr), 1);
- else
- krdc->intf = rdc_add_to_if(krdc->lsrv,
- &(urdc->secondary.addr), &(urdc->primary.addr), 0);
-
- if (options & CCIO_SLAVE) {
- /*
- * mark that the bitmap needs clearing.
- */
- rdc_many_enter(krdc);
- rdc_set_flags(urdc, RDC_CLR_AFTERSYNC);
- rdc_many_exit(krdc);
-
- /* Starting forward sync */
- if (urdc->volume_size == 0)
- rdc_get_details(krdc);
- if (urdc->volume_size == 0) {
- index = -1;
- goto out;
- }
- if (krdc->dcio_bitmap == NULL) {
- if (rdc_resume_bitmap(krdc) < 0) {
- index = -1;
- goto out;
- }
- }
- if (rdc_allow_sec_sync(urdc, CCIO_SLAVE) < 0) {
- index = -1;
- goto out;
- }
- rdc_dump_dsets(index);
- slave = 1;
- } else if (options & CCIO_RSYNC) {
- /*
- * mark that the bitmap needs clearing.
- */
- rdc_many_enter(krdc);
- rdc_set_flags(urdc, RDC_CLR_AFTERSYNC);
- rdc_many_exit(krdc);
-
- /* Starting reverse sync */
- if (rdc_get_vflags(urdc) & (RDC_SYNC_NEEDED |
- RDC_VOL_FAILED | RDC_BMP_FAILED)) {
- index = -1;
- goto out;
- }
- if (rdc_allow_sec_sync(urdc, CCIO_RSYNC) < 0) {
- index = -1;
- goto out;
- }
- rdc_dump_dsets(index);
- rev_sync = 1;
- } else if (options & CCIO_DONE) {
- /* Sync completed OK */
- if (rdc_get_vflags(urdc) & RDC_SYNC_NEEDED)
- done = 1; /* forward sync complete */
- rdc_many_enter(krdc);
- rdc_clr_flags(urdc, RDC_SYNCING | RDC_SYNC_NEEDED);
- rdc_clr_mflags(urdc, RDC_SLAVE | RDC_RSYNC_NEEDED);
- rdc_many_exit(krdc);
- rdc_write_state(urdc);
- if (rdc_get_vflags(urdc) & RDC_CLR_AFTERSYNC) {
- RDC_ZERO_BITMAP(krdc);
- rdc_many_enter(krdc);
- rdc_clr_flags(urdc, RDC_CLR_AFTERSYNC);
- rdc_many_exit(krdc);
- }
- } else if (options & CCIO_ENABLELOG) {
- /* Sync aborted or logging started */
- if (!(rdc_get_vflags(urdc) & RDC_PRIMARY)) {
- rdc_clr_flags(urdc, RDC_SYNCING);
- rdc_many_enter(krdc);
- rdc_clr_mflags(urdc, RDC_SLAVE);
- rdc_many_exit(krdc);
- }
- log = 1;
- }
-out:
- rdc_group_exit(krdc);
- free_rdc_netbuf(&(rdc_set.primary.addr));
- free_rdc_netbuf(&(rdc_set.secondary.addr));
-
- if (slave) {
- if (_rdc_sync_event_notify(RDC_SYNC_START,
- urdc->secondary.file, urdc->group_name) >= 0) {
- rdc_group_enter(krdc);
- rdc_clr_flags(urdc, RDC_LOGGING);
- rdc_many_enter(krdc);
- rdc_clr_flags(urdc, RDC_VOL_FAILED);
- rdc_set_flags(urdc,
- RDC_SYNCING | RDC_SYNC_NEEDED);
- rdc_set_mflags(urdc, RDC_SLAVE);
- rdc_many_exit(krdc);
- rdc_write_state(urdc);
- rdc_group_exit(krdc);
- } else {
- index = -1;
- }
- } else if (rev_sync) {
- /* Check to see if volume is mounted */
- if (_rdc_sync_event_notify(RDC_RSYNC_START,
- urdc->secondary.file, urdc->group_name) >= 0) {
- rdc_group_enter(krdc);
- rdc_clr_flags(urdc, RDC_LOGGING);
- rdc_set_flags(urdc, RDC_SYNCING);
- rdc_write_state(urdc);
- rdc_group_exit(krdc);
- } else {
- index = -1;
- }
- } else if (done) {
-
- /*
- * special case...
- * if this set is in a group, then sndrsyncd will
- * make sure that all sets in the group are REP
- * before updating the config to "update", telling
- * sndrsyncd that it is ok to take anther snapshot
- * on a following sync. The important part about
- * the whole thing is that syncd needs kernel stats.
- * however, this thread must set the set busy to
- * avoid disables. since this is the only
- * sync_event_notify() that will cause a status
- * call back into the kernel, and we will not be
- * accessing the group structure, we have to wakeup now
- */
-
- mutex_enter(&rdc_conf_lock);
- wakeup_busy(krdc);
- mutex_exit(&rdc_conf_lock);
-
- (void) _rdc_sync_event_notify(RDC_SYNC_DONE,
- urdc->secondary.file, urdc->group_name);
- }
- }
-
- if (!done) {
- mutex_enter(&rdc_conf_lock);
- wakeup_busy(krdc);
- mutex_exit(&rdc_conf_lock);
- }
-
- (void) svc_sendreply(xprt, xdr_int, (char *)&index);
- if (log) {
- rdc_group_enter(krdc);
- rdc_group_log(krdc, RDC_NOFLUSH | RDC_OTHERREMOTE,
- "Sync aborted or logging started");
- rdc_group_exit(krdc);
- }
- free_rdc_netbuf(&(state.netaddr));
- free_rdc_netbuf(&(state.rnetaddr));
-}
-
-/*
- * r_net_getstate4
- * Return our state to client
- */
-static void
-r_net_getstate4(SVCXPRT *xprt, struct svc_req *req)
-{
- int e, ret = -1, index = -1;
- struct set_state4 state;
- rdc_u_info_t *urdc;
- rdc_set_t rdc_set;
-
- bzero(&state, sizeof (struct set_state));
- e = SVC_GETARGS(xprt, xdr_set_state4, (char *)&state);
- if (e) {
- init_rdc_netbuf(&(rdc_set.primary.addr));
- init_rdc_netbuf(&(rdc_set.secondary.addr));
- bcopy(state.netaddr, rdc_set.primary.addr.buf,
- state.netaddrlen);
- bcopy(state.rnetaddr, rdc_set.secondary.addr.buf,
- state.rnetaddrlen);
- rdc_set.primary.addr.len = state.netaddrlen;
- rdc_set.secondary.addr.len = state.rnetaddrlen;
- (void) strncpy(rdc_set.primary.file, state.pfile,
- RDC_MAXNAMLEN);
- (void) strncpy(rdc_set.secondary.file, state.sfile,
- RDC_MAXNAMLEN);
- index = rdc_lookup_byaddr(&rdc_set);
- if (index >= 0) {
- urdc = &rdc_u_info[index];
-
- ret = 0;
- if (rdc_get_vflags(urdc) & RDC_SYNCING)
- ret |= 4;
- if (rdc_get_vflags(urdc) & RDC_SLAVE)
- ret |= 2;
- if (rdc_get_vflags(urdc) & RDC_LOGGING)
- ret |= 1;
- rdc_set_if_vers(urdc, req->rq_vers);
- }
- free_rdc_netbuf(&(rdc_set.primary.addr));
- free_rdc_netbuf(&(rdc_set.secondary.addr));
- }
- (void) svc_sendreply(xprt, xdr_int, (char *)&ret);
-}
-
-/*
- * r_net_getstate7
- * Return our state to client
- */
-static void
-r_net_getstate7(SVCXPRT *xprt, struct svc_req *req)
-{
- int e, ret = -1, index = -1;
- struct set_state state;
- char pstr[RDC_MAXNAMLEN];
- char sstr[RDC_MAXNAMLEN];
- rdc_u_info_t *urdc;
- rdc_set_t rdc_set;
- unsigned short *sp;
-
- bzero(&state, sizeof (struct set_state));
- state.pfile = pstr;
- state.sfile = sstr;
-
- e = SVC_GETARGS(xprt, xdr_set_state, (char *)&state);
- if (e) {
- init_rdc_netbuf(&(rdc_set.primary.addr));
- init_rdc_netbuf(&(rdc_set.secondary.addr));
- sp = (unsigned short *)(state.netaddr.buf);
- *sp = ntohs(*sp);
- bcopy(state.netaddr.buf, rdc_set.primary.addr.buf,
- state.netaddrlen);
- sp = (unsigned short *)(state.rnetaddr.buf);
- *sp = ntohs(*sp);
- bcopy(state.rnetaddr.buf, rdc_set.secondary.addr.buf,
- state.rnetaddrlen);
- rdc_set.primary.addr.len = state.netaddrlen;
- rdc_set.secondary.addr.len = state.rnetaddrlen;
- /*
- * strncpy(rdc_set.primary.file, state.pfile, RDC_MAXNAMLEN);
- * strncpy(rdc_set.secondary.file, state.sfile, RDC_MAXNAMLEN);
- */
- bcopy(state.pfile, rdc_set.primary.file, RDC_MAXNAMLEN);
- bcopy(state.sfile, rdc_set.secondary.file, RDC_MAXNAMLEN);
- index = rdc_lookup_byaddr(&rdc_set);
- if (index >= 0) {
- urdc = &rdc_u_info[index];
-
- ret = 0;
- if (rdc_get_vflags(urdc) & RDC_SYNCING)
- ret |= 4;
- if (rdc_get_vflags(urdc) & RDC_SLAVE)
- ret |= 2;
- if (rdc_get_vflags(urdc) & RDC_LOGGING)
- ret |= 1;
- rdc_set_if_vers(urdc, req->rq_vers);
- }
- free_rdc_netbuf(&(rdc_set.primary.addr));
- free_rdc_netbuf(&(rdc_set.secondary.addr));
- }
- (void) svc_sendreply(xprt, xdr_int, (char *)&ret);
-}
-
-/*
- * copy from/to a dset/vector combination to a network xdr buffer.
- */
-static int
-rdc_dsetcopy(rdc_net_dataset_t *dset, nsc_vec_t *invec, nsc_off_t fba_pos,
- nsc_size_t fba_len, char *bdata, int blen, int dir)
-{
- nsc_vec_t *vec;
- uchar_t *sv_addr;
- uchar_t *data;
- int sv_len;
- nsc_off_t fpos;
- int len;
- int n;
-
- if (!bdata || !dset || !invec) {
-#ifdef DEBUG
- cmn_err(CE_NOTE,
- "!rdc: dsetcopy: parameters failed bdata %p, dset %p "
- "invec %p", (void *)bdata, (void *)dset, (void *)invec);
-#endif
- return (FALSE);
- }
-
- if (fba_len > MAX_RDC_FBAS ||
- (dir != COPY_IN && dir != COPY_OUT)) {
-#ifdef DEBUG
- cmn_err(CE_NOTE,
- "!rdc: dsetcopy: params failed fba_len %" NSC_SZFMT
- " fba_pos %" NSC_SZFMT ", dir %d", fba_len, fba_pos, dir);
-#endif
- return (FALSE);
- }
-
- data = (uchar_t *)bdata; /* pointer to data in rpc */
- len = FBA_SIZE(fba_len); /* length of this transfer in bytes */
- fpos = fba_pos; /* start fba offset within buffer */
-
- if (!len) {
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!rdc: dsetcopy: len = 0");
-#endif
- return (FALSE);
- }
-
- if (len != blen) {
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!rdc:dsetcopy: len %d != blen %d", len, blen);
-#endif
- if (len > blen)
- len = blen;
- }
-
- if (!RDC_DSET_LIMITS(dset, fba_pos, fba_len)) {
- /* should never happen */
-#ifdef DEBUG
- cmn_err(CE_NOTE,
- "!rdc: dsetcopy: handle limits pos %" NSC_SZFMT " (%"
- NSC_SZFMT ") len %" NSC_SZFMT " (%" NSC_SZFMT ")",
- fba_pos, dset->pos, fba_len, dset->fbalen);
-#endif
- return (FALSE); /* Don't overrun handle */
- }
-
- vec = invec;
- fpos -= dset->pos;
-
- /* find starting position in vector */
-
- for (; fpos >= FBA_NUM(vec->sv_len); vec++)
- fpos -= FBA_NUM(vec->sv_len);
-
- /*
- * Copy data
- */
-
- sv_addr = vec->sv_addr + FBA_SIZE(fpos);
- sv_len = vec->sv_len - FBA_SIZE(fpos);
-
- while (len) {
- if (!sv_addr) /* end of vec - how did this happen? */
- break;
-
- n = min(sv_len, len);
-
- if (dir == COPY_OUT)
- bcopy(data, sv_addr, (size_t)n);
- else
- bcopy(sv_addr, data, (size_t)n);
-
- sv_len -= n;
- len -= n;
-
- sv_addr += n;
- data += n;
-
- if (sv_len <= 0) {
- /* goto next vector */
- vec++;
- sv_addr = vec->sv_addr;
- sv_len = vec->sv_len;
- }
- }
-
- return (TRUE);
-}
-
-
-/*
- * rdc_start_server
- * Starts the kRPC server for rdc. Uses tli file descriptor passed down
- * from user level rdc server.
- *
- * Returns: 0 or errno (NOT unistat!).
- */
-int
-rdc_start_server(struct rdc_svc_args *args, int mode)
-{
- file_t *fp;
- int ret;
- struct cred *cred;
- STRUCT_HANDLE(rdc_svc_args, rs);
-
- STRUCT_SET_HANDLE(rs, mode, args);
- cred = ddi_get_cred();
- if (drv_priv(cred) != 0)
- return (EPERM);
- fp = getf(STRUCT_FGET(rs, fd));
- if (fp == NULL) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!rdc_start_server fd %d, fp %p", args->fd,
- (void *) fp);
-#endif
- return (EBADF);
- }
-
- ret = rdcsrv_load(fp, rdc_srvtab, args, mode);
-
- releasef(STRUCT_FGET(rs, fd));
- return (ret);
-}
-
-/*
- * Allocate a new sleepq element.
- */
-
-static rdc_sleepq_t *
-rdc_newsleepq()
-{
- rdc_sleepq_t *sq;
-
- sq = kmem_alloc(sizeof (rdc_sleepq_t), KM_SLEEP);
- sq->next = NULL;
-#ifdef DEBUG
- mutex_enter(&rdc_cntlock);
- rdc_sleepcnt++;
- mutex_exit(&rdc_cntlock);
-#endif
- return (sq);
-}
-
-/*
- * free memory/resources used by a sleepq element.
- */
-static void
-rdc_delsleepq(rdc_sleepq_t *sq)
-{
- rdc_net_dataset_t *dset;
-
- if (sq->idx != -1) {
- dset = rdc_net_get_set(sq->sindex, sq->idx);
- if (dset) {
- rdc_net_del_set(sq->sindex, dset);
- }
- }
- kmem_free(sq, sizeof (rdc_sleepq_t));
-#ifdef DEBUG
- mutex_enter(&rdc_cntlock);
- rdc_sleepcnt--;
- mutex_exit(&rdc_cntlock);
-#endif
-}
-
-
-/*
- * skip down the sleep q and insert the sleep request
- * in ascending order. Return 0 on success, 1 on failure.
- */
-static int
-rdc_sleepq(rdc_group_t *group, rdc_sleepq_t *sq)
-{
- rdc_sleepq_t *findsq;
-
-
- ASSERT(MUTEX_HELD(&group->ra_queue.net_qlock));
- if (group->sleepq == NULL) {
- group->sleepq = sq;
- } else {
- if (sq->seq == group->sleepq->seq) {
- cmn_err(CE_WARN, "!rdc_sleepq: Attempt to "
- "add duplicate request to queue %d", sq->seq);
- return (1);
- }
- if (RDC_INFRONT(sq->seq, group->sleepq->seq)) {
- sq->next = group->sleepq;
- group->sleepq = sq;
- } else {
- findsq = group->sleepq;
-
- while (findsq->next) {
- if (sq->seq == findsq->next->seq) {
- cmn_err(CE_WARN, "!rdc_sleepq: "
- "Attempt to add duplicate "
- "request to queue %d", sq->seq);
- return (1);
- }
- if (RDC_INFRONT(sq->seq, findsq->next->seq)) {
- sq->next = findsq->next;
- findsq->next = sq;
- break;
- }
- findsq = findsq->next;
- }
- if (findsq->next == NULL)
- findsq->next = sq;
- }
- }
- return (0);
-}
-
-/*
- * run down the sleep q and discard all the sleepq elements.
- */
-void
-rdc_sleepqdiscard(rdc_group_t *group)
-{
- rdc_sleepq_t *sq;
- rdc_k_info_t *krdc;
-
- ASSERT(MUTEX_HELD(&group->ra_queue.net_qlock));
- sq = group->sleepq;
-
- while (sq) {
- rdc_sleepq_t *dsq;
-
- dsq = sq;
- krdc = &rdc_k_info[dsq->sindex];
- if (krdc->io_kstats) {
- mutex_enter(krdc->io_kstats->ks_lock);
- kstat_waitq_exit(KSTAT_IO_PTR(krdc->io_kstats));
- mutex_exit(krdc->io_kstats->ks_lock);
- }
- sq = sq->next;
- rdc_delsleepq(dsq);
- }
- group->sleepq = NULL;
-}
-
-/*
- * split any write requests down to maxfba sized chunks.
- */
-/*ARGSUSED*/
-static int
-rdc_writemaxfba(rdc_k_info_t *krdc, rdc_u_info_t *urdc,
- rdc_net_dataset_t *dset, uint_t seq, int nocache)
-{
- int len;
- int ret;
- nsc_vec_t vector[2];
- nsc_buf_t *handle;
- int reserved;
- int rtype;
- nsc_size_t mfba;
- nsc_size_t wsize;
- nsc_off_t pos;
- int eintr_count;
- unsigned char *daddr;
- int kstat_len;
-
- kstat_len = len = dset->fbalen;
- ret = 0;
- handle = NULL;
- reserved = 0;
- rtype = RDC_RAW;
-
- ASSERT(dset->nitems == 1);
-
- eintr_count = 0;
- do {
- ret = _rdc_rsrv_devs(krdc, rtype, RDC_INTERNAL);
- if (ret == EINTR) {
- ++eintr_count;
- delay(2);
- }
- } while ((ret == EINTR) && (eintr_count < MAX_EINTR_COUNT));
- if (ret != 0) {
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!rdc_writemaxfba: reserve devs "
- "failed %d", ret);
-#endif
- goto out;
-
- }
- reserved = 1;
- /*
- * Perhaps we should cache mfba.
- */
- ret = nsc_maxfbas(RDC_U_FD(krdc), 0, &mfba);
- if (ret != 0) {
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!rdc_writemaxfba: msc_maxfbas failed %d",
- ret);
-#endif
- goto out;
- }
-
- ASSERT(urdc->volume_size != 0);
- if (dset->pos + len > urdc->volume_size) {
- /* should never happen */
- /*
- * also need to trim down the vector
- * sizes.
- */
- kstat_len = len = urdc->volume_size - dset->pos;
- dset->head->len -= FBA_SIZE(len);
- ASSERT(dset->head->len > 0);
- }
- daddr = dset->head->dptr;
- pos = dset->pos;
- vector[1].sv_addr = NULL;
- vector[1].sv_len = 0;
-
- while (len > 0) {
- wsize = min((nsc_size_t)len, mfba);
- vector[0].sv_addr = daddr;
- vector[0].sv_len = FBA_SIZE(wsize);
-
- if (handle) {
- (void) nsc_free_buf(handle);
- handle = NULL;
- }
- ret = nsc_alloc_buf(RDC_U_FD(krdc), pos, wsize,
- NSC_WRBUF|NSC_NODATA|nocache, &handle);
- if (ret != 0) {
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!rdc_writemaxfba: "
- "nsc_alloc (d1) buf failed %d at "
- "pos %" NSC_SZFMT " len %" NSC_SZFMT,
- ret, pos, wsize);
-#endif
- goto out;
- }
- handle->sb_vec = &vector[0];
- ret = rdc_combywrite(krdc, handle);
- if (ret != 0) {
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!rdc_writemaxfba: "
- "write failed (d1) %d offset %" NSC_SZFMT " "
- "length %" NSC_SZFMT, ret, pos, wsize);
-#endif
- goto out;
- }
- pos += wsize;
- len -= wsize;
- daddr += FBA_SIZE(wsize);
- }
-out:
- if (!RDC_SUCCESS(ret)) {
- if (!(rdc_get_vflags(urdc) & RDC_VOL_FAILED)) {
- ASSERT(!(rdc_get_vflags(urdc) &
- RDC_PRIMARY));
- rdc_many_enter(krdc);
- rdc_set_flags(urdc, RDC_SYNC_NEEDED);
- rdc_set_flags_log(urdc, RDC_VOL_FAILED,
- "svc write failed");
- rdc_many_exit(krdc);
- rdc_write_state(urdc);
- }
- } else {
- /* success */
-#ifdef DEBUG
- if (rdc_netwrite6) {
- /*
- * This string is used in the ZatoIchi MASNDR
- * tests, if you change this, update the test.
- */
- cmn_err(CE_NOTE, "!writemaxfba: Write "
- "sequence %u", seq);
- }
-#endif
- if (krdc->io_kstats) {
- KSTAT_IO_PTR(krdc->io_kstats)->writes++;
- KSTAT_IO_PTR(krdc->io_kstats)->nwritten +=
- FBA_SIZE(kstat_len);
- }
- }
- if (handle)
- (void) nsc_free_buf(handle);
- if (reserved)
- _rdc_rlse_devs(krdc, rtype);
- return (ret);
-}
-
-static int
-rdc_combywrite(rdc_k_info_t *krdc, nsc_buf_t *handle)
-{
- int rsync;
- int ret;
- int multiret;
-
- rsync = -1;
- ret = 0;
- /* Handle multihop I/O even on error */
- if (IS_MULTI(krdc)) {
- rdc_k_info_t *ktmp;
- rdc_u_info_t *utmp;
-
- rdc_many_enter(krdc);
- /*
- * Find a target primary that is enabled,
- * taking account of the fact that this
- * could be a multihop secondary
- * connected to a 1-to-many primary.
- */
- ktmp = krdc->multi_next;
- if (ktmp == NULL) {
- rdc_many_exit(krdc);
- goto multi_done;
- }
- utmp = &rdc_u_info[ktmp->index];
- do {
- if ((rdc_get_vflags(utmp) & RDC_PRIMARY)
- /* CSTYLED */
- && IS_ENABLED(utmp))
- break;
-
- ktmp = ktmp->many_next;
- utmp = &rdc_u_info[ktmp->index];
- } while (ktmp != krdc->multi_next);
-
- if (!(rdc_get_vflags(utmp) & RDC_PRIMARY) ||
- !IS_ENABLED(utmp)) {
- rdc_many_exit(krdc);
- goto multi_done;
- }
-
- rdc_many_exit(krdc);
- rsync = (rdc_get_mflags(utmp) & RDC_SLAVE);
- if (!rsync) {
- /* normal case - local io first */
- ret = nsc_write(handle, handle->sb_pos, handle->sb_len,
- 0);
- }
- multiret = _rdc_multi_write(handle, handle->sb_pos,
- handle->sb_len, 0, ktmp);
- if (!RDC_SUCCESS(multiret)) {
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!combywrite: "
- "rdc_multi_write failed "
- "status %d ret %d",
- handle->sb_error, multiret);
-#endif
- if (!(rdc_get_vflags(utmp) &
- RDC_VOL_FAILED)) {
- rdc_many_enter(ktmp);
- if (rdc_get_vflags(utmp) &
- RDC_PRIMARY) {
- rdc_set_mflags(utmp,
- RDC_RSYNC_NEEDED);
- } else {
- rdc_set_flags(utmp,
- RDC_SYNC_NEEDED);
- }
- rdc_set_flags(utmp,
- RDC_VOL_FAILED);
- rdc_many_exit(ktmp);
- rdc_write_state(utmp);
- }
- }
- }
-
-multi_done:
- if (rsync != 0) {
- /*
- * Either:
- * reverse sync in progress and so we
- * need to do the local io after the
- * (multihop) secondary io.
- * Or:
- * no multihop and this is the only io
- * required.
- */
- ret = nsc_write(handle, handle->sb_pos, handle->sb_len, 0);
-
- }
- return (ret);
-}
-/*
- * set the pos and len values in the piggyback reply.
- */
-static void
-rdc_setbitind(int *pendcnt, net_pendvec_t *pvec, rdc_net_dataset_t *dset,
- uint_t seq, int pindex, int qpos)
-{
- int pc;
- ASSERT(*pendcnt < RDC_MAXPENDQ);
-
- pc = *pendcnt;
- pvec[pc].seq = seq;
- pvec[pc].apos = dset->pos;
- pvec[pc].qpos = qpos;
- pvec[pc].alen = dset->fbalen;
- pvec[pc].pindex = pindex;
- *pendcnt = pc + 1;
- DTRACE_PROBE1(pvec_reply, int, seq);
-}
-
-/*
- * Enters with group->ra_queue.net_qlock held.
- * Tries to construct the return status data for
- * all the pending requests in the sleepq that it can
- * satisfy.
- */
-static void
-rdc_dopending(rdc_group_t *group, netwriteres *netretp)
-{
- int pendcnt;
- net_pendvec_t *pendvec;
- rdc_sleepq_t *sq;
- int ret;
- int pendsz;
-
- ASSERT(MUTEX_HELD(&group->ra_queue.net_qlock));
-
- pendcnt = 0;
- pendsz = RDC_MAXPENDQ * sizeof (net_pendvec_t);
- pendvec = kmem_alloc(pendsz, KM_SLEEP);
-
- /*
- * now look at the Q of pending tasks, attempt
- * to write any that have been waiting for
- * me to complete my write, and piggyback
- * their results in my reply, by setiing pendcnt
- * to the number of extra requests sucessfully
- * processed.
- */
- while (group->sleepq && group->sleepq->seq == group->seq) {
- rdc_k_info_t *krdc;
- rdc_u_info_t *urdc;
- struct rdc_net_dataset *dset;
-
- sq = group->sleepq;
- group->sleepq = sq->next;
- mutex_exit(&group->ra_queue.net_qlock);
-
- krdc = &rdc_k_info[sq->sindex];
- urdc = &rdc_u_info[sq->sindex];
- if (krdc->io_kstats) {
- mutex_enter(krdc->io_kstats->ks_lock);
- kstat_waitq_exit(KSTAT_IO_PTR(krdc->io_kstats));
- mutex_exit(krdc->io_kstats->ks_lock);
- }
-
- dset = rdc_net_get_set(sq->sindex, sq->idx);
- if (dset == NULL) {
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!pending: %s:%s rdc_net_get_set "
- "failed", urdc->secondary.intf,
- urdc->secondary.file);
-#endif
- /*
- * as we failed to get the pointer, there
- * is no point expecting the cleanup
- * code in rdc_delsleepq() to get it
- * either.
- */
- sq->idx = -1;
- goto cleansq;
- }
- sq->idx = -1; /* marked as cleaned up */
-
- ret = rdc_writemaxfba(krdc, urdc, dset, sq->seq, sq->nocache);
- if (RDC_SUCCESS(ret)) {
- rdc_setbitind(&pendcnt, pendvec, dset,
- sq->seq, sq->pindex, sq->qpos);
- } else {
- cmn_err(CE_WARN, "!dopending: Write of pending "
- "asynchronous task failed, with "
- "sequence number %u for SNDR set %s:%s",
- sq->seq, urdc->secondary.intf,
- urdc->secondary.file);
- }
- rdc_net_del_set(sq->sindex, dset);
-cleansq:
- mutex_enter(&group->ra_queue.net_qlock);
- group->seq = sq->seq + 1;
- if (group->seq < sq->seq)
- group->seq = RDC_NEWSEQ + 1;
- rdc_delsleepq(sq);
- }
- mutex_exit(&group->ra_queue.net_qlock);
- if (pendcnt) {
- int vecsz;
-#ifdef DEBUG
- if (rdc_netwrite6) {
- cmn_err(CE_NOTE, "!packing pend, count %d", pendcnt);
- }
-#endif
- vecsz = pendcnt * sizeof (net_pendvec_t);
- netretp->vecdata.vecdata_val =
- kmem_alloc(vecsz, KM_SLEEP);
- netretp->vecdata.vecdata_len = pendcnt;
- bcopy(pendvec, netretp->vecdata.vecdata_val, vecsz);
- }
- kmem_free(pendvec, pendsz);
- mutex_enter(&group->ra_queue.net_qlock);
-}
-
-/*
- * Take the dset and allocate and fill in the vector.
- */
-static nsc_vec_t *
-rdc_dset2vec(rdc_net_dataset_t *dset)
-{
- nsc_vec_t *vecret;
- int i;
- rdc_net_dataitem_t *ditem;
-
- ASSERT(dset->nitems > 0);
- ASSERT(dset->head);
- ASSERT(dset->tail);
-
- vecret = kmem_alloc((dset->nitems + 1) * sizeof (nsc_vec_t),
- KM_NOSLEEP);
- if (vecret == NULL) {
- return (NULL);
- }
- RDC_DSMEMUSE((dset->nitems + 1) * sizeof (nsc_vec_t));
- ditem = dset->head;
- for (i = 0; i < dset->nitems; i++) {
- ASSERT(ditem);
- vecret[i].sv_addr = ditem->dptr;
- vecret[i].sv_len = ditem->len;
- ditem = ditem->next;
- }
- /*
- * Null terminate.
- */
- vecret[i].sv_addr = NULL;
- vecret[i].sv_len = 0;
- /*
- * Check the list and count matches.
- */
- ASSERT(ditem == NULL);
- return (vecret);
-}
-
-/*
- * Split the local read into maxfba sized chunks.
- * Returns 0 on an error, or a valid idx on success.
- */
-static int
-rdc_readmaxfba(int cd, nsc_off_t pos, nsc_size_t fbalen, int nocache)
-{
- int idx;
- rdc_k_info_t *krdc;
- rdc_u_info_t *urdc;
- rdc_net_dataset_t *dset;
- rdc_net_dataitem_t *ditem;
- int rtype;
- nsc_buf_t *handle;
- nsc_vec_t veclist[2];
- int ret;
- int reserved;
- nsc_size_t fbaleft;
- nsc_size_t mfba;
- nsc_off_t fba;
- nsc_off_t spos;
- int eintr_count;
-
- handle = NULL;
- idx = 0; /* error status */
- dset = NULL;
- ditem = NULL;
- reserved = 0;
- ret = 0;
- mfba = 0;
-
- rtype = RDC_RAW;
- krdc = &rdc_k_info[cd];
- urdc = &rdc_u_info[cd];
-
- eintr_count = 0;
- do {
- ret = _rdc_rsrv_devs(krdc, rtype, RDC_INTERNAL);
- if (ret == EINTR) {
- ++eintr_count;
- delay(2);
- }
- } while ((ret == EINTR) && (eintr_count < MAX_EINTR_COUNT));
- if (ret != 0) {
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!readmaxfba: reserve failed on set %s:%s %d",
- urdc->secondary.intf, urdc->secondary.file,
- ret);
-#endif
- goto out;
- }
- reserved = 1;
- /*
- * create a dataset that we can hang all the buffers from.
- */
- dset = rdc_net_add_set(cd);
- if (dset == NULL) {
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!readmaxfba: Unable to allocate dset on set "
- "%s:%s", urdc->secondary.intf, urdc->secondary.file);
-#endif
- goto out;
- }
- dset->pos = pos;
- dset->fbalen = fbalen;
- ret = nsc_maxfbas(RDC_U_FD(krdc), 0, &mfba);
- if (ret != 0) {
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!readmaxfba: msc_maxfbas failed on set %s:%s "
- "%d", urdc->secondary.intf, urdc->secondary.file, ret);
-#endif
- goto out;
- }
- spos = pos;
- fbaleft = fbalen;
- veclist[1].sv_addr = NULL;
- veclist[1].sv_len = 0;
-
- while (fbaleft > 0) {
- fba = min(mfba, fbaleft);
- if (handle) {
- (void) nsc_free_buf(handle);
- handle = NULL;
- }
- ret = nsc_alloc_buf(RDC_U_FD(krdc), spos, fba,
- nocache|NSC_NODATA, &handle);
- if (ret != 0) {
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!readmaxfba: alloc failed on set"
- "%s:%s %d", urdc->secondary.intf,
- urdc->secondary.file, ret);
-#endif
- goto out;
- }
- ditem = kmem_alloc(sizeof (rdc_net_dataitem_t), KM_NOSLEEP);
- if (ditem == NULL) {
- goto out;
- }
- RDC_DSMEMUSE(sizeof (rdc_net_dataitem_t));
- ditem->len = FBA_SIZE(fba);
- ditem->mlen = ditem->len;
- ditem->dptr = kmem_alloc(ditem->len, KM_SLEEP);
- RDC_DSMEMUSE(ditem->len);
- ditem->next = NULL;
- /*
- * construct a vector list
- */
- veclist[0].sv_addr = ditem->dptr;
- veclist[0].sv_len = ditem->len;
- handle->sb_vec = veclist;
- ret = rdc_combyread(krdc, urdc, handle);
- if (ret != 0) {
- goto out;
- }
- /*
- * place on linked list.
- */
- dset->nitems++;
- if (dset->head == NULL) {
- dset->head = ditem;
- dset->tail = ditem;
- } else {
- dset->tail->next = ditem;
- dset->tail = ditem;
- }
- /*
- * now its linked, clear this so its not freed twice.
- */
- ditem = NULL;
- fbaleft -= fba;
- spos += fba;
- }
- /*
- * all the reads have worked, store the results.
- */
- idx = dset->id;
- rdc_net_put_set(cd, dset);
- dset = NULL;
-out:
- if (handle)
- (void) nsc_free_buf(handle);
- if (reserved)
- _rdc_rlse_devs(krdc, rtype);
- if (dset)
- rdc_net_del_set(cd, dset);
- if (ditem) {
- kmem_free(ditem->dptr, ditem->mlen);
- RDC_DSMEMUSE(-ditem->mlen);
- kmem_free(ditem, sizeof (*ditem));
- RDC_DSMEMUSE(-sizeof (*ditem));
- }
- return (idx);
-}
-
-
-/*
- * perform both a local read, and if multihop, a remote read.
- * return 0 on success, or errno on failure.
- */
-static int
-rdc_combyread(rdc_k_info_t *krdc, rdc_u_info_t *urdc, nsc_buf_t *handle)
-{
- int ret;
- rdc_k_info_t *ktmp;
- rdc_u_info_t *utmp;
-
- /*
- * read it.
- */
- if (krdc->io_kstats) {
- mutex_enter(krdc->io_kstats->ks_lock);
- kstat_runq_enter(KSTAT_IO_PTR(krdc->io_kstats));
- mutex_exit(krdc->io_kstats->ks_lock);
- }
-
- ret = nsc_read(handle, handle->sb_pos, handle->sb_len, NSC_READ);
-
- if (krdc->io_kstats) {
- mutex_enter(krdc->io_kstats->ks_lock);
- kstat_runq_exit(KSTAT_IO_PTR(krdc->io_kstats));
- mutex_exit(krdc->io_kstats->ks_lock);
- }
-
- if (ret != 0) {
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!combyread: read failed on set %s:%s %d",
- urdc->secondary.intf, urdc->secondary.file, ret);
-#endif
- if (!(rdc_get_vflags(urdc) & RDC_VOL_FAILED)) {
- rdc_many_enter(krdc);
- rdc_set_mflags(urdc, RDC_RSYNC_NEEDED);
- rdc_set_flags_log(urdc, RDC_VOL_FAILED,
- "comby read failed");
- rdc_many_exit(krdc);
- rdc_write_state(urdc);
- }
- goto out;
- }
- if (IS_MULTI(krdc) && (ktmp = krdc->multi_next) &&
- (utmp = &rdc_u_info[ktmp->index]) &&
- IS_ENABLED(utmp) &&
- (rdc_get_mflags(utmp) & RDC_RSYNC_NEEDED)) {
- ret = _rdc_remote_read(ktmp, handle, handle->sb_pos,
- handle->sb_len, NSC_READ);
- /*
- * Set NSC_MIXED so
- * that the cache will throw away this
- * buffer when we free it since we have
- * combined data from multiple sources
- * into a single buffer.
- * Currently we don't use the cache for
- * data volumes, so comment this out.
- * handle->sb_flag |= NSC_MIXED;
- */
- if (ret != 0) {
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!combyread: remote read failed on "
- "set %s:%s %d", utmp->secondary.intf,
- utmp->secondary.file, ret);
-#endif
- goto out;
- }
- }
- if (krdc->io_kstats) {
- KSTAT_IO_PTR(krdc->io_kstats)->reads++;
- KSTAT_IO_PTR(krdc->io_kstats)->nread +=
- FBA_SIZE(handle->sb_len);
- }
-out:
- return (ret);
-}
-
-
-/*
- * remove and free all the collected dsets for this set.
- */
-void
-rdc_dump_dsets(int index)
-{
- rdc_k_info_t *krdc;
- rdc_net_dataset_t *dset;
-
- krdc = &rdc_k_info[index];
-tloop:
- mutex_enter(&krdc->dc_sleep);
- while ((dset = krdc->net_dataset) != NULL) {
- if (dset->inuse) {
- /*
- * for the dset to be in use, the
- * service routine r_net_write6() must
- * be active with it. It will free
- * it eventually.
- */
- mutex_exit(&krdc->dc_sleep);
- delay(5);
- goto tloop;
- }
- /*
- * free it.
- */
- rdc_net_free_set(krdc, dset);
- }
- mutex_exit(&krdc->dc_sleep);
-}
-
-#ifdef DEBUG
-void
-rdc_stallzero(int flag)
-{
- static int init = 0;
- static kcondvar_t cv;
- static kmutex_t mu;
-
- if (init == 0) {
- cv_init(&cv, NULL, CV_DRIVER, NULL);
- mutex_init(&mu, NULL, MUTEX_DRIVER, NULL);
- init = 1;
- }
-
- mutex_enter(&mu);
- switch (flag) {
- case 0:
- rdc_stall0 = 0;
- cv_signal(&cv);
- break;
- case 1:
- rdc_stall0 = 1;
- break;
- case 2:
- while (rdc_stall0 == 1)
- cv_wait(&cv, &mu);
- break;
- default:
- cmn_err(CE_PANIC, "Bad flag value passed to rdc_stallzero");
- break;
- }
- mutex_exit(&mu);
-}
-#endif
-
-/*
- * RDC protocol version 5
- */
-static rdc_disptab_t rdc_disptab5[] =
-{
- /* PROC Idempotent */
- { r_net_null, FALSE },
- { rdcsrv_noproc, FALSE },
- { r_net_getsize, FALSE },
- { rdcsrv_noproc, FALSE },
- { r_net_write5, TRUE },
- { r_net_read, FALSE },
- { rdcsrv_noproc, FALSE },
- { r_net_state4, FALSE },
- { r_net_ping4, FALSE },
- { r_net_bmap, FALSE },
- { r_net_bdata, FALSE },
- { rdcsrv_noproc, FALSE },
- { r_net_getstate4, FALSE }
-};
-
-/*
- * RDC protocol version 6
- */
-static rdc_disptab_t rdc_disptab6[] =
-{
- /* PROC Idempotent */
- { r_net_null, FALSE },
- { rdcsrv_noproc, FALSE },
- { r_net_getsize6, FALSE },
- { rdcsrv_noproc, FALSE },
- { r_net_write6, TRUE },
- { r_net_read6, FALSE },
- { rdcsrv_noproc, FALSE },
- { r_net_state4, FALSE },
- { r_net_ping4, FALSE },
- { r_net_bmap6, FALSE },
- { r_net_bdata6, FALSE },
- { rdcsrv_noproc, FALSE },
- { r_net_getstate4, FALSE }
-};
-
-/*
- * RDC protocol version 7
- */
-static rdc_disptab_t rdc_disptab7[] =
-{
- /* PROC Idempotent */
- { r_net_null, FALSE },
- { rdcsrv_noproc, FALSE },
- { r_net_getsize6, FALSE },
- { rdcsrv_noproc, FALSE },
- { r_net_write6, TRUE },
- { r_net_read6, FALSE },
- { rdcsrv_noproc, FALSE },
- { r_net_state, FALSE },
- { r_net_ping7, FALSE },
- { r_net_bmap6, FALSE },
- { r_net_bdata6, FALSE },
- { rdcsrv_noproc, FALSE },
- { r_net_getstate7, FALSE }
-};
-
-static rdcsrv_t rdc_srvtab[] = {
- { rdc_disptab5, sizeof (rdc_disptab5) / sizeof (*rdc_disptab5) },
- { rdc_disptab6, sizeof (rdc_disptab6) / sizeof (*rdc_disptab6) },
- { rdc_disptab7, sizeof (rdc_disptab7) / sizeof (*rdc_disptab7) }
-};
diff --git a/usr/src/uts/common/avs/ns/rdc/rdc_update.h b/usr/src/uts/common/avs/ns/rdc/rdc_update.h
deleted file mode 100644
index 438ff657d2..0000000000
--- a/usr/src/uts/common/avs/ns/rdc/rdc_update.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _RDC_UPDATE_H
-#define _RDC_UPDATE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct rdc_update_s {
- spcs_s_info_t status;
- int protocol; /* semantics of update svc */
- char *volume; /* volume name */
- uchar_t *bitmap; /* set of changes to be made */
- int size; /* size of bitmap in bytes */
- int denied; /* don't do it? */
-} rdc_update_t;
-
- /* semantics of update svc call */
-#define RDC_SVC_ONRETURN 0 /* caller will update on return */
-#define RDC_SVC_VOL_ENABLED 1 /* tell me if a given vol is enabled */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _RDC_UPDATE_H */
diff --git a/usr/src/uts/common/avs/ns/rdc/rdcsrv.c b/usr/src/uts/common/avs/ns/rdc/rdcsrv.c
deleted file mode 100644
index 731fce8728..0000000000
--- a/usr/src/uts/common/avs/ns/rdc/rdcsrv.c
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/ksynch.h>
-#include <sys/cmn_err.h>
-#include <sys/kmem.h>
-#include <sys/stat.h>
-#include <sys/file.h>
-#include <sys/cred.h>
-#include <sys/conf.h>
-#include <sys/modctl.h>
-#include <sys/errno.h>
-
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_k.h>
-#include <sys/unistat/spcs_errors.h>
-
-#ifdef _SunOS_2_6
-/*
- * on 2.6 both dki_lock.h and rpc/types.h define bool_t so we
- * define enum_t here as it is all we need from rpc/types.h
- * anyway and make it look like we included it. Yuck.
- */
-#define _RPC_TYPES_H
-typedef int enum_t;
-#else
-#ifndef DS_DDICT
-#include <rpc/types.h>
-#endif
-#endif /* _SunOS_2_6 */
-
-#ifndef DS_DDICT
-#include <rpc/auth.h>
-#include <rpc/svc.h>
-#include <rpc/xdr.h>
-#else
-#include "../contract.h"
-#endif
-
-#include <sys/ddi.h>
-
-#include <sys/nsc_thread.h>
-#include <sys/nsctl/nsctl.h>
-
-#include <sys/nsctl/nsvers.h>
-
-#include "rdc_io.h"
-#include "rdc_stub.h"
-#include "rdc_ioctl.h"
-#include "rdcsrv.h"
-
-#if defined(_SunOS_5_6) || defined(_SunOS_5_7)
-static void rdcsrv_xprtclose(const SVCXPRT *xprt);
-#else /* SunOS 5.8 or later */
-/*
- * SunOS 5.8 or later.
- *
- * RDC callout table
- *
- * This table is used by svc_getreq to dispatch a request with a given
- * prog/vers pair to an approriate service provider.
- */
-
-static SVC_CALLOUT rdcsrv_sc[] = {
- { RDC_PROGRAM, RDC_VERS_MIN, RDC_VERS_MAX, rdcstub_dispatch }
-};
-
-static SVC_CALLOUT_TABLE rdcsrv_sct = {
- sizeof (rdcsrv_sc) / sizeof (rdcsrv_sc[0]), FALSE, rdcsrv_sc
-};
-#endif /* SunOS 5.8 or later */
-
-static kmutex_t rdcsrv_lock;
-
-static int rdcsrv_dup_error;
-static int rdcsrv_registered;
-static int rdcsrv_closing;
-static int rdcsrv_refcnt;
-long rdc_svc_count = 0;
-static rdcsrv_t *rdcsrv_disptab;
-
-/*
- * Solaris module setup.
- */
-
-extern struct mod_ops mod_miscops;
-
-static struct modlmisc modlmisc = {
- &mod_miscops, /* Type of module */
- "nws:Remote Mirror kRPC:" ISS_VERSION_STR
-};
-
-static struct modlinkage modlinkage = {
- MODREV_1,
- &modlmisc,
- NULL
-};
-
-
-int
-_init(void)
-{
- int rc;
-
- mutex_init(&rdcsrv_lock, NULL, MUTEX_DRIVER, NULL);
-
- if ((rc = mod_install(&modlinkage)) != DDI_SUCCESS)
- mutex_destroy(&rdcsrv_lock);
-
- return (rc);
-}
-
-
-int
-_fini(void)
-{
- int rc;
-
- if ((rc = mod_remove(&modlinkage)) == DDI_SUCCESS)
- mutex_destroy(&rdcsrv_lock);
-
- return (rc);
-}
-
-
-int
-_info(struct modinfo *modinfop)
-{
- return (mod_info(&modlinkage, modinfop));
-}
-
-
-/*
- * RDC kRPC server stub.
- */
-
-void
-rdcsrv_noproc(void)
-{
- ;
-}
-
-
-static int
-rdcsrv_dispdup(struct svc_req *req, SVCXPRT *xprt)
-{
- rdc_disptab_t *disp;
- struct dupreq *dr;
- rdcsrv_t *srvp;
- void (*fn)();
- int dupstat;
-
- srvp = &rdcsrv_disptab[req->rq_vers - RDC_VERS_MIN];
- disp = &srvp->disptab[req->rq_proc];
- fn = disp->dispfn;
-
- dupstat = SVC_DUP(xprt, req, 0, 0, &dr);
-
- switch (dupstat) {
- case DUP_ERROR:
- /* svcerr_systemerr does a freeargs */
- svcerr_systemerr(xprt);
- rdcsrv_dup_error++;
- break;
-
- case DUP_INPROGRESS:
- rdcsrv_dup_error++;
- break;
-
- case DUP_NEW:
- case DUP_DROP:
- (*fn)(xprt, req);
- SVC_DUPDONE(xprt, dr, 0, 0, DUP_DONE);
- break;
-
- case DUP_DONE:
- break;
- }
-
- return (dupstat);
-}
-
-
-/*
- * rdcsrv_dispatch is the dispatcher routine for the RDC RPC protocol
- */
-void
-rdcsrv_dispatch(struct svc_req *req, SVCXPRT *xprt)
-{
- rdc_disptab_t *disp;
- rdcsrv_t *srvp;
-
- mutex_enter(&rdcsrv_lock);
- rdcsrv_refcnt++;
-
- if (!rdcsrv_registered || rdcsrv_closing || !rdcsrv_disptab) {
- mutex_exit(&rdcsrv_lock);
- goto outdisp;
- }
-
- mutex_exit(&rdcsrv_lock);
-
- if ((req->rq_vers < RDC_VERS_MIN) || (req->rq_vers > RDC_VERS_MAX)) {
- svcerr_noproc(xprt);
- cmn_err(CE_NOTE, "!rdcsrv_dispatch: unknown version %d",
- req->rq_vers);
- /* svcerr_noproc does a freeargs on xprt */
- goto done;
- }
-
- srvp = &rdcsrv_disptab[req->rq_vers - RDC_VERS_MIN];
- disp = &srvp->disptab[req->rq_proc];
-
- if (req->rq_proc >= srvp->nprocs ||
- disp->dispfn == rdcsrv_noproc) {
- svcerr_noproc(xprt);
- cmn_err(CE_NOTE, "!rdcsrv_dispatch: bad proc number %d",
- req->rq_proc);
- /* svcerr_noproc does a freeargs on xprt */
- goto done;
- } else if (disp->clone) {
- switch (rdcsrv_dispdup(req, xprt)) {
- case DUP_ERROR:
- goto done;
- /* NOTREACHED */
- case DUP_INPROGRESS:
- goto outdisp;
- /* NOTREACHED */
- default:
- break;
- }
- } else {
- (*disp->dispfn)(xprt, req);
- rdc_svc_count++;
- }
-
-outdisp:
- if (!SVC_FREEARGS(xprt, (xdrproc_t)0, (caddr_t)0))
- cmn_err(CE_NOTE, "!rdcsrv_dispatch: bad freeargs");
-done:
- mutex_enter(&rdcsrv_lock);
- rdcsrv_refcnt--;
- mutex_exit(&rdcsrv_lock);
-}
-
-
-static int
-rdcsrv_create(file_t *fp, rdc_svc_args_t *args, int mode)
-{
- /*LINTED*/
- int rc, error = 0;
- /*LINTED*/
- rpcvers_t vers;
- struct netbuf addrmask;
-
-#if defined(_SunOS_5_6) || defined(_SunOS_5_7)
- SVCXPRT *xprt;
-#else
- SVCMASTERXPRT *xprt;
-#endif
- STRUCT_HANDLE(rdc_svc_args, uap);
-
- STRUCT_SET_HANDLE(uap, mode, args);
-
- addrmask.len = STRUCT_FGET(uap, addrmask.len);
- addrmask.maxlen = STRUCT_FGET(uap, addrmask.maxlen);
- addrmask.buf = kmem_alloc(addrmask.maxlen, KM_SLEEP);
- error = ddi_copyin(STRUCT_FGETP(uap, addrmask.buf), addrmask.buf,
- addrmask.len, mode);
- if (error) {
- kmem_free(addrmask.buf, addrmask.maxlen);
-#ifdef DEBUG
- cmn_err(CE_WARN, "!addrmask copyin failed %p", (void *) args);
-#endif
- return (error);
- }
-
- /*
- * Set rdcstub's dispatch handle to rdcsrv_dispatch
- */
- rdcstub_set_dispatch(rdcsrv_dispatch);
-
- /*
- * Create a transport endpoint and create one kernel thread to run the
- * rdc service loop
- */
-#if defined(_SunOS_5_6) || defined(_SunOS_5_7)
- error = svc_tli_kcreate(fp, RDC_RPC_MAX,
- STRUCT_FGETP(uap, netid), &addrmask, STRUCT_FGET(uap, nthr), &xprt);
-#else
- {
-#if defined(_SunOS_5_8)
- struct svcpool_args p;
- p.id = RDC_SVCPOOL_ID;
- p.maxthreads = STRUCT_FGET(uap, nthr);
- p.redline = 0;
- p.qsize = 0;
- p.timeout = 0;
- p.stksize = 0;
- p.max_same_xprt = 0;
-
- error = svc_pool_create(&p);
- if (error) {
- cmn_err(CE_NOTE,
- "!rdcsrv_create: svc_pool_create failed %d", error);
- return (error);
- }
-#endif
- error = svc_tli_kcreate(fp, RDC_RPC_MAX,
- STRUCT_FGETP(uap, netid), &addrmask,
- &xprt, &rdcsrv_sct, NULL, RDC_SVCPOOL_ID, FALSE);
- }
-#endif
-
- if (error) {
- cmn_err(CE_NOTE, "!rdcsrv_create: svc_tli_kcreate failed %d",
- error);
- return (error);
- }
-
-#if defined(_SunOS_5_6) || defined(_SunOS_5_7)
- if (xprt == NULL) {
- cmn_err(CE_NOTE, "!xprt in rdcsrv_create is NULL");
- } else {
- /*
- * Register a cleanup routine in case the transport gets
- * destroyed. If the registration fails for some reason,
- * it means that the transport is already being destroyed.
- * This shouldn't happen, but it's probably not worth a
- * panic.
- */
- if (!svc_control(xprt, SVCSET_CLOSEPROC,
- (void *)rdcsrv_xprtclose)) {
- cmn_err(
-#ifdef DEBUG
- CE_PANIC,
-#else
- CE_WARN,
-#endif
- "!rdcsrv_create: couldn't set xprt callback");
-
- error = EBADF;
- goto done;
- }
- }
-
- for (vers = RDC_VERS_MIN; vers <= RDC_VERS_MAX; vers++) {
- rc = svc_register(xprt, (ulong_t)RDC_PROGRAM, vers,
- rdcstub_dispatch, 0);
- if (!rc) {
- cmn_err(CE_NOTE,
- "!rdcsrv_create: svc_register(%d, %lu) failed",
- RDC_PROGRAM, vers);
-
- if (!error) {
- error = EBADF;
- }
- }
- }
-#endif /* 5.6 or 5.7 */
-
- if (!error) {
- /* mark as registered with the kRPC subsystem */
- rdcsrv_registered = 1;
- }
-
-done:
- return (error);
-}
-
-
-#if defined(_SunOS_5_6) || defined(_SunOS_5_7)
-/*
- * Callback routine for when a transport is closed.
- */
-static void
-rdcsrv_xprtclose(const SVCXPRT *xprt)
-{
-}
-#endif
-
-
-/*
- * Private interface from the main RDC module.
- */
-
-int
-rdcsrv_load(file_t *fp, rdcsrv_t *disptab, rdc_svc_args_t *args, int mode)
-{
- int rc = 0;
-
- mutex_enter(&rdcsrv_lock);
-
- rc = rdcsrv_create(fp, args, mode);
- if (rc == 0) {
- rdcsrv_disptab = disptab;
- }
-
- mutex_exit(&rdcsrv_lock);
- return (rc);
-}
-
-
-void
-rdcsrv_unload(void)
-{
- mutex_enter(&rdcsrv_lock);
-
- /* Unset rdcstub's dispatch handle */
- rdcstub_unset_dispatch();
-
- rdcsrv_closing = 1;
-
- while (rdcsrv_refcnt > 0) {
- mutex_exit(&rdcsrv_lock);
- delay(drv_usectohz(25));
- mutex_enter(&rdcsrv_lock);
- }
-
- rdcsrv_closing = 0;
- rdcsrv_disptab = 0;
-
- mutex_exit(&rdcsrv_lock);
-}
diff --git a/usr/src/uts/common/avs/ns/rdc/rdcsrv.h b/usr/src/uts/common/avs/ns/rdc/rdcsrv.h
deleted file mode 100644
index cd1fc88906..0000000000
--- a/usr/src/uts/common/avs/ns/rdc/rdcsrv.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _RDCSRV_H
-#define _RDCSRV_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef _KERNEL
-
-
-typedef struct rdc_disptab_s {
- void (*dispfn)();
- int clone;
-} rdc_disptab_t;
-
-typedef struct rdcsrv_s {
- rdc_disptab_t *disptab;
- int nprocs;
-} rdcsrv_t;
-
-extern void rdcsrv_noproc(void);
-extern void rdcsrv_unload(void);
-extern int rdcsrv_load(file_t *, rdcsrv_t *, rdc_svc_args_t *, int);
-
-#endif /* _KERNEL */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _RDCSRV_H */
diff --git a/usr/src/uts/common/avs/ns/sdbc/CACHE_SPEC.txt b/usr/src/uts/common/avs/ns/sdbc/CACHE_SPEC.txt
deleted file mode 100644
index 1769251955..0000000000
--- a/usr/src/uts/common/avs/ns/sdbc/CACHE_SPEC.txt
+++ /dev/null
@@ -1,389 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# $Id: CACHE_SPEC,v 3.6.0.0 1998/01/05 22:55:19 idumois Exp $
-#
-
- "sd" cache layer
- ----------------
-#include <sys/sd/sd.h>
-
-The "sd" layer provides a common interface to the functionality
-described below. It will also allow switching to a direct to disk
-version, so that a new cache module could be loaded.
-The functions are basically the same as those below,
-but named without the leading underscore.
-(ie sd_alloc_buf instead of _sd_alloc_buf)
-
-
- "sdbc" -- storage device block cache (aka blkc)
- -----------------------------------------------
-
-#include "uts/sd/sdbc/sd_cache.h" /* for SDBC interface */
-#include "sys/sd/sd.h" /* for generic SD interface */
-
-(all interaction is in terms of the buf_handle.
-
-Currently buf_handle is declared as:
-
-#define _SD_MAX_BLKS 64
-#define _SD_MAX_FBAS (_SD_MAX_BLKS << FBA_SHFT)
-
-typedef struct _sd_buf_handle {
- int bh_cd; /* actually bh_buf.sb_cd */
- int bh_fba_pos; /* bh_buf.sb_pos */
- int bh_fba_len; /* bh_buf.sb_len */
- int bh_flag; /* bh_buf.sb_flag */
- int bh_error; /* bh_buf.sb_error */
- _sd_vec_t bh_bufvec[_SD_MAX_BLKS]; /* bh_buf.sb_vec */
- void (*bh_disconnect_cb)();
- void (*bh_read_cb)();
- void (*bh_write_cb)();
- ......
-} _sd_buf_handle_t;
-
-
-typedef struct sd_vec_s { /* Scatter gather element */
- unsigned char *sv_addr; /* Virtual address of data */
- unsigned int sv_vme; /* VME address of data */
- int sv_len; /* Data length in bytes */
-} sd_vec_t;
-
-The upper level routines should reference only: handle->bh_error,
-handle->bh_bufvec The bh_bufvec is an array of _sd_vec_t with the
-last item in the array having a NULL bufaddr.
-
-IMPORTANT: The handle should be treated read-only and never be modified.
-
- 1) Multiple accesses to a single file will be supported.
- (Side effect: If a process owning cache blocks of a files attempts
- to allocate overlapping cache blocks, it will be a
- deadlock condition.)
-
- 2) Multiple writes to an allocated block will be supported. It
- is no longer necessary to free and re-allocate between writes.
-
- 3) _SD_NOBLOCK is equivalent of async_io -- the io will be initiated
- if required with the call returning _SD_PENDING. A callback
- (read or write) will be called at io end action.
-
- 4) Disconnect hints to ckd will be provided by the use of
- either psema or thread_bind() when io needs to be initiated.
-
-
-NOTE:
- fba_pos = disk block number, each block being 512 bytes.
- fba_len = len in disk blocks, each block being 512 bytes.
- Thus, 512 bytes = 1 fba_len, 1024 = 2 fba_len etc...
-
-Hints:
- _SD_WRTHRU: write through mode.
- This hint can be set on a node, a device or per access.
- _SD_FORCED_WRTHRU: forced write through (node down or flow control)
- If this hint is cleared, when only one node is up,
- _sd_uncommit() will not work properly, and a second
- failure could result in lost data.
- This is a node hint.
- _SD_NOCACHE: reuse cache blocks immediately instead of keeping
- in lru order.
- This hint can be set on a device or per access.
-
-Interface:
-
-_sd_buf_handle_t *
-_sd_alloc_handle(discon_cb, read_cb, write_cb)
- void (*discon_cb)();
- void (*read_cb)();
- void (*write_cb)();
-
- The callbacks can be NULL if you do not want any callbacks.
- Else, the callbacks will be stored in the handle, and will be
- called at specific points in the cache. (Its up to the
- callback to do what is necessary, including disconnecting
- from the channel)
-
- Usage: for better performance, an application could allocate
- a handle (or as many handles as is required) upfront and
- use it later on in the cache calls.
-
- Not allocating and managing the handles would mean a new
- handle will be allocated and freed during _sd_alloc_buf
- and _sd_freebuf.
-
-int
-_sd_free_handle(handle)
- _sd_buf_handle_t *handle;
-
- Only handles that are allocated through _sd_alloc_handle
- should be freed with this call.
-
-int
-_sd_alloc_buf (cd, fba_pos, fba_len, flag, handle_p)
- int cd;
- int fba_pos;
- int fba_len;
- int flag;
- _sd_buf_handle_t **handle_p;
-
- cd = cache descriptor. Results in an error if this node does
- not own this disk and the other node has not crashed.
- (ie. requests must be routed to the correct node)
- (see fault tolerant aspects discussed elsewhere)
-
- fba_pos = disk position in multiples of 512 byte blocks.
- fba_len = length in multiples of 512 bytes blocks.
- (NOTE: This cannot exceed _SD_MAX_FBAS)
-
- flag = None, one or more of the following (described below):
- _SD_RDBUF | SD_WRBUF | _SD_RDWRBUF | _SD_PINNABLE |
- _SD_NOBLOCK | _SD_NOCACHE | _SD_WRTHRU
-
- handle_p = (*handle_p = handle to be used for this call)
- If *handle_p == NULL, a new handle will be
- allocated. _sd_free_buf will free up any handles
- allocated in this fashion.
- NOTE: Handles allocated in this fashion will not have
- any callbacks registered in them. As such,
- _SD_NOBLOCK flag along with a NULL handle would
- result in the io being lost.
-
- return: Error number if > 0
- possible errors:
- EINVAL if arguments are incorrect or
- cache not initialized or
- device not open.
- E2BIG if this request is a read and such a large
- request cannot be currently satisfied. (break up
- the io or re-issue at a later point)
- EIO or any other errno that the driver might return.
- Note: on error, the handle is not active,
- and also is freed if *handle_p was NULL.
-
- if 0 or less, status will be one of:
- _SD_DONE: buffer is ready, and ready to be used.
- (with the blocks valid if _SD_RDBUF is set)
- _SD_PENDING:
- read callback, if one has been registered in the handle,
- will be called to complete this request.
- _SD_HIT: Same as _SD_DONE, read was satisfied by cache,
- or no blocking required for write buffer.
-
- Note: _SD_RDBUF will issue the read if necessary.
- _SD_WRBUF allocates a network address to reflect to
- mirror node on _sd_write().
- ~_SD_RDBUF allocates buffers but does NOT pre-read;
- use _sd_read() to fill in (portions) as req'd.
-
- Note: flag == (_SD_RDBUF|_SD_WRTHRU|_SD_NOCACHE) will
- clear valid bits (that are not dirty) thus read direct
- from disk, without requiring a hash invalidate.
-
-
-int
-_sd_write (handle, fba_pos, fba_len, flag)
- _sd_buf_handle_t *handle;
- int fba_pos, fba_len;
- int flag;
-{
- handle = handle previously allocated in allocate buf.
- fba_pos and fba_len have to be within the allocated portion.
- int flag. Flag: _SD_NOBLOCK | SD_WRTHRU
-
- Attempting to write to a handle that was not allocated for write
- will return error (EINVAL)
-
- returns: errno if return > 0
- if 0 or less, return will be one of:
- _SD_PENDING: will be returned only if _SD_NOBLOCK is set AND
- either the flag is _SD_WRTHRU or the other node is down,
- or the device/node is in write through mode
- _SD_DONE: is returned if the block has been written to the disk.
- _SD_HIT: write block in cache..
-
-int
-_sd_read (handle, fba_pos, fba_len, flag)
- _sd_buf_handle_t *handle;
- int fba_pos, fba_len;
- int flag;
-
- handle = handle previously allocated in allocate buf.
- fba_pos and fba_len have to be within the allocated portion.
- int flag. Flag: _SD_NOBLOCK
-
- returns: errno if return > 0
- error E2BIG if this request is big and cannot be currently
- satisfied. (break up the io or re-issue at a later point)
-
- if 0 or less, return will be one of:
- _SD_PENDING: will be returned only if _SD_NOBLOCK is set and
- we need to do an io.
- _SD_HIT: is returned if the blocks were satisfied by cache.
- _SD_DONE: some blocks were read from disk.
-
-int
-_sd_uncommit(handle, fba_pos, fba_len, flag)
- _sd_buf_handle_t *handle;
- int fba_pos, fba_len;
- int flag;
-
- handle = handle previously allocated in allocate buf.
- fba_pos and fba_len have to be within the allocated portion.
- flag: reserved for future use.
-
- _sd_uncommit could block and cannot be called from a
- "non-blocking" context.
- (This is under review, from the ckd point of view)
-
- returns 0 (_SD_DONE) else errno;
-
-
-int
-_sd_zero (handle, fba_pos, fba_len, flag)
- _sd_buf_handle_t *handle;
- int fba_pos, fba_len;
- int flag;
-
- handle = handle previously allocated in allocate buf.
- fba_pos and fba_len have to be within the allocated portion.
- zero the buffer described by the handle.
- flag: _SD_NOBLOCK | _SD_WRTHRU
-
- The call commits data to disk.
- This call has characteristics similar to _sd_write.
-
- returns: errno if return > 0
- if 0 or less, return will be one of:
- _SD_DONE
- _SD_PENDING
-
-_sd_copy (handle1, handle2, fba_pos1, fba_pos2, fba_len)
- _sd_buf_handle_t *handle1, handle2;
- int fba_pos1, fba_pos2, fba_len;
-
- Copies relevant data from handle1 to handle2.
- Useful for mirroring, remote dual copy, backup while open,
- in-house tests, etc.
-
- This call does not commit data to disk - you must explicitly
- call _sd_write() on handle2 if that is what you want.
-
- returns: errno if return > 0:
- EIO - if sd module should do a generic bcopy
- others - real error (passed to user)
- if 0 or less, return will be:
- _SD_DONE - sucess
-
-_sd_free_buf(handle)
- _sd_buf_handle_t *handle;
-
- handle = handle previously allocated in allocate buf.
-
- returns 0 (_SD_DONE) else errno;
-
-_sd_open(filename, flag)
- char *filename;
- int flag;
-
- returns a cache descriptor, or negative error number.
- Typically use _sd_attach_cd(cd) before accessing the device.
- Note: if devices is already open, it returns the same cache descriptor.
- Currently there is no reference count; so one _sd_close() closes
- the cache descriptor (in all contexts).
-
-_sd_close(cd)
- int cd;
- Similar to _sd_detach_cd below.
- Note: intended to be called when terminating the cache; and not during
- normal operation. No reference count (see above).
- Returns: 0 success, EIO.
-
-_sd_detach_cd(cd)
- re-reflect any pinned blocks to the other side,
- or wait for writes to flush; and invalidate that device's hash entries,
- and relinquish device responsibility.
- Returns: 0 success, EIO, EAGAIN.
-
-_sd_attach_cd(cd)
- If device has pinned blocks then scan for and re-pin those blocks
- (same idea as "node recovery" process, but per-device);
- and assert device responsibility.
-
-_sd_notify_all_pin(cd)
- rescan list of failed blocks and re-issue the pinned callback to
- simulation.
-
-
-_sd_register_pinned(func)
- void (*func)();
- callback (*func)(cd, fba_pos, fba_len) when disk write fails,
- and _SD_PENDING was specified on alloc.
-
-_sd_register_unpinned(func)
- void (*func)();
- callback (*func)(cd, fba_pos, fba_len) when data previously pinned
- is successfully written to disk.
-
-_sd_register_down(func)
- void (*func)();
- callback (*func)() when health monitor detects the other node went down.
-
-_sd_set_hint(cd, hint)
-_sd_clear_hint(cd, hint)
-_sd_get_cd_hint(cd, &hint)
-_sd_set_node_hint(hint)
-_sd_clear_node_hint(hint)
-_sd_get_node_hint(&hint)
-
- where hint is _SD_NOCACHE and _SD_WRTHRU. (Write through being synchronous
- write and will be the default if the second node dies.)
-
- _SD_NOCACHE: hint indicating that the current access need not be
- cached for later consumption.
-
-
-_sd_discard_pinned(cd, fba_pos, fba_len)
- call from ckd into cache, called when data that was earlier
- on pinned can be discarded from the cache.
-
- returns: 0 or error.
- (error = EINVAL if the discard could not be done)
-
-(note: there is an inherent race between the unpinned callback and
-_sd_discard_pinned which could put the data on disk in an inconsistent
-state)
-
-
-Failover support:
-
-The Nodedown callback will be called, if one has been registered. This
-will happen as soon as the other node has been detected to have gone down,
-or when the cache is disabled on the other node.
-
-The amount of time to for this callback to happen after the node goes down
-is not deterministic.
-
-Access to a mirror node's devices is only valid from the point the
-nodedown callback is called till the other node is determined to be back
-in operation.
-
-Access to mirror node's devices while recovery is in progress will
-block the access till the recovery is complete.
diff --git a/usr/src/uts/common/avs/ns/sdbc/Makefile b/usr/src/uts/common/avs/ns/sdbc/Makefile
deleted file mode 100644
index 3ece00b584..0000000000
--- a/usr/src/uts/common/avs/ns/sdbc/Makefile
+++ /dev/null
@@ -1,55 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# include global definitions
-include ../../../../../Makefile.master
-
-HDRS= sd_bcache.h \
- sd_cache.h \
- sd_conf.h \
- sd_hash.h \
- sdbc_ioctl.h \
- sd_pcu.h \
- sd_trace.h \
- safestore.h
-
-ROOTDIRS= $(ROOT)/usr/include/sys/nsctl
-
-ROOTHDRS= $(HDRS:%=$(ROOTDIRS)/%)
-
-CHECKHDRS= $(HDRS:%.h=%.check)
-
-# install rule
-$(ROOTDIRS)/%: %
- $(INS.file)
-
-.KEEP_STATE:
-
-.PARALLEL: $(CHECKHDRS)
-
-install_h: $(ROOTDIRS) $(ROOTHDRS)
-
-$(ROOTDIRS):
- $(INS.dir)
-
-check: $(CHECKHDRS)
diff --git a/usr/src/uts/common/avs/ns/sdbc/cache_kstats_readme.txt b/usr/src/uts/common/avs/ns/sdbc/cache_kstats_readme.txt
deleted file mode 100644
index 3d73a4559b..0000000000
--- a/usr/src/uts/common/avs/ns/sdbc/cache_kstats_readme.txt
+++ /dev/null
@@ -1,319 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-================================================================================
-
-TITLE: Kstats Specification for SDBC
-
-DATE: 10-28-2002
-
-AUTHOR: Chris Juhasz (chris.juhasz@sun.com)
-
-LOCATION: src/uts/common/ns/sdbc/cache_kstats_readme.txt
-================================================================================
-
-The existing sd_stat cache statistical reporting mechanism has been expanded
-with the kstat library reporting mechanism. The existing mechanism will probably
-eventually be phased out. In general the statistics have fallen
-into two general categories - "global" and "cd." The global stats reflect gross
-behavior over all cached volumes, while "cd" stats reflect behavior particular
-to each cached volume (or cache descriptor).
-
-The sdbc module makes use of two types of kstats. For generic statistic
-reporting, "regular" kstat_named_t type kstats are used. For timing-specific
-reporting, sdbc relies on the kstat_io_t type.
-
-For more information on kstats, see [1] in the References section.
-
-1.0 NAMING:
-===========
-The names for the sdbc kstats are defined in src/uts/common/ns/sdbc/sd_misc.h
-
-2.0 REGULAR KSTATS:
-===================
-The following are kstats of type kstat_named_t, used to gather generic
-statistics.
-
-These make use of the original statistics gathering mechanism for sdbc,
-_sd_stats_t and _sd_shared_t structs, defined in
-src/uts/common/ns/sdbc/sd_bcache.h. The _sd_stats_t structure tracks
-statistics that are global to the entire cache, while the _sd_shared_t struct
-is used to track statistics particular to a cache descriptor (cd).
-
-2.1 GLOBAL KSTATS:
-~~~~~~~~~~~~~~~~~~
-This global kstat represents statistics which reflect the state of the entire
-cache, summed over all cache descriptors.
-
-2.1.1 Field Definitions:
-------------------------
-The "global" kstat corresponds to fields in the _sd_stats_t structure. The
-following table maps the name of the kstat field to its equivalent field in
-the _sd_stats_t structure, also providing a description where appropriate.
-
-KSTAT FIELD _sd_stats_t DESCRIPTION
------------ ----------- -----------
-sdbc_count st_count - number of opens for device
-sdbc_loc_count st_loc_count - number of open devices
-sdbc_rdhits st_rdhits - number of read hits
-sdbc_rdmiss st_rdmiss - number of read misses
-sdbc_wrhits st_wrhits - number of write hits
-sdbc_wrmiss st_wrmiss - number of write misses
-sdbc_blksize st_blksize - cache block size (in bytes)
-
-/* I'm not very sure what the next three fields track--we might take them out */
-sdbc_lru_blocks st_lru_blocks
-sdbc_lru_noreq st_lru_noreq
-sdbc_lru_req st_lru_req
-
-sdbc_wlru_inq st_wlru_inq - number of write blocks
-sdbc_cachesize st_cachesize - cache size (in bytes)
-sdbc_numblocks st_numblocks - cache blocks
-sdbc_num_shared MAXFILES*2 - number of shared structures (one for
- each cached volume)
- This number dictates the maximum
- index size for shared stats and
- names given below.
-sdbc_destaged st_destaged - number of bytes destaged to disk
- (flushed from the cache to disk).
-sdbc_wrcancelns st_wrcancelns - number of write cancellations
- (writes to cached blocks that are
- already dirty).
-sdbc_nodehints --- - node hints (such as wrthru/nowrthru)
-
-All fields are read-only and are of type KSTAT_DATA_ULONG. Note that the
-"sdbc_wrcancelns" and "sdbc_destaged" are new, and have also been added to the
-_sd_stats_t struct.
-
-2.1.2 Naming characteristics:
------------------------------
-module: SDBC_KSTAT_MODULE "sdbc"
-class: SDBC_KSTAT_CLASS "storedge"
-name: SDBC_KSTAT_GSTATS "global"
-instance #: 0
-
-
-2.2 KSTATS (PER CACHE DESCRIPTOR):
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-These "cd" kstats present statistics which reflect the state of a single cache
-descriptor. One of these kstats exists for each open cache descriptor.
-
-2.2.1 Field Definitions:
-------------------------
-The "cd" kstats correspond to fields in the _sd_shared_t structure. The
-following table maps the name of the kstat field to its equivalent field in
-the _sd_shared_t structure, also providing a description where appropriate.
-
-KSTAT FIELD _sd_shared_t DESCRIPTION
------------ ------------ -----------
-sdbc_vol_name sh_filename - last 16 characters of the volume name
-sdbc_alloc sh_alloc - is this allocated?
-sdbc_failed sh_failed - Disk failure status (0=ok,1= /o
- error ,2= open failed)
-sdbc_cd sh_cd - the cache descriptor. (for stats)
-sdbc_cache_read sh_cache_read - Number of FBA's read from cache
-sdbc_cache_write sh_cache_write - Number of FBA's written to cache
-sdbc_disk_read sh_disk_read - Number of FBA's read from disk
-sdbc_disk_write sh_disk_write - Number of FBA's written to disk
-sdbc_filesize sh_filesize - Filesize (in FBA's)
-sdbc_numdirty sh_numdirty - Number of dirty blocks
-sdbc_numio sh_numio - Number of blocks on way to disk
-sdbc_numfail sh_numfail - Number of blocks failed
-sdbc_flushloop sh_flushloop - Loops delayed so far
-sdbc_flag sh_flag - Flags visible to user programs
-sdbc_destaged sh_destaged - number of bytes destaged to disk
- (flushed from the cache to disk).
-sdbc_cdhints --- - cd hints (such as wrthru/nowrthru)
-
-All fields are read-only kstat_named_t kstats, with data type KSTAT_DATA_ULONG.
-The instance number of the kstat corresponds to the cache descriptor number.
-Note that the "sdbc_wrcancelns" and "sdbc_destaged" are new, and have also
-been added to the _sd_shared_t struct.
-
-2.2.2 Naming characteristics:
------------------------------
-module: SDBC_KSTAT_MODULE "sdbc"
-class: SDBC_KSTAT_CLASS "storedge"
-name: SDBC_KSTAT_CDSTATS "cd%d" (%d = < cd number >)
-instance #: < cache descriptor number >
-
-3.0 I/O KSTATS:
-===============
-The sdbc module now contains kstats of type kstat_io_t. These are used to
-track timing through the cache. As with the "regular" kstats, sdbc tracks
-global statistics, as well as those per cache descriptor. Since kstat_io_t
-is a built-in kstat type, all are defined the same way.
-
-3.0.1 Time-Gathering:
----------------------
-These kstat_io_t types provide two built-in time-gathering mechanisms, which it
-refers to as "waitq" and "runq," where "waitq" is intended to be interpreted
-as the amount of time a request spends in its pre-service state, and "runq" the
-amount of time a request spends in its service state. Transitions to the
-runq and the waitq must be made via built-in functions, such as
-kstat_runq_enter() and kstat_runq_exit(). The relevant fields in the
-kstat_io_t structure should not be considered explicitly. (See comment below).
-The iostat(1M) utility may be used to gather timing-related information
-collected through this mechanism.
-
-Please note that sdbc does not use waitq.
-sdbc uses runq as follows:
-
-An I/O request transitions to the runq (both global, and per-cd) upon entering
-the cache through _sd_read(), _sd_write(), or _sd_alloc_buf(). It
-transitions off the runq after the request has been serviced, either by the
-cache, or as the result of disk I/O. Thus, this allows a user to track the
-total time spent in the cache, which includes disk I/O time.
-
-
-3.0.2 kstat_io_t Fields:
-------------------------
-These I/O kstats include the following fields:
-
- u_longlong_t nread; /* number of bytes read */
- u_longlong_t nwritten; /* number of bytes written */
- uint_t reads; /* number of read operations */
- uint_t writes; /* number of write operations */
-
-# The following fields are automatically updated by the built-in
-# kstat_waitq_enter(), kstat_waitq_exit(), kstat_runq_enter() and
-# kstat_runq_exit() functions.
-
- hrtime_t wtime; /* cumulative wait (pre-service) time */
- hrtime_t wlentime; /* cumulative wait length*time product */
- hrtime_t wlastupdate; /* last time wait queue changed */
- hrtime_t rtime; /* cumulative run (service) time */
- hrtime_t rlentime; /* cumulative run length*time product */
- hrtime_t rlastupdate; /* last time run queue changed */
-
- uint_t wcnt; /* count of elements in wait state */
- uint_t rcnt; /* count of elements in run state */
-
-For more information, refer to [2] in the References section.
-
-3.1 GLOBAL IO KSTATS:
-~~~~~~~~~~~~~~~~~~~~~
-sdbc includes "global" I/O kstats which track the timings through the cache as
-a whole, taking into account all cache descriptors. The fields definitions
-are built-in, as explained above.
-
-3.1.1 Naming characteristics:
------------------------------
-module: SDBC_KSTAT_MODULE "sdbc"
-class: "disk"
-name: SDBC_IOKSTAT_GSTATS "gsdbc"
-instance #: 0
-
-3.2 IO KSTATS (PER CACHE DESCRIPTOR):
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-These "cd" I/O kstats present statistics which reflect the state of a single
-cache descriptor. One of these I/O kstats exists for each open cache
-descriptor. The fields definitions are built-in, as explained above.
-
-3.2.1 Naming characteristics:
------------------------------
-module: SDBC_KSTAT_MODULE "sdbc"
-class: "disk"
-name: SDBC_IOKSTAT_STATS "sdbc%d" (%d = < cd number >)
-instance #: < cache descriptor number >
-
-4.0 DYNMEM KSTATS:
-==================
-The sdbc module also a "regular" kstat to track dynamic memory
-allocation in the cache. These are "global" statistics.
-
-Its fields can be divided logically between behavior variables, and statistical
-variable
-
-4.1 Field Definitions:
-~~~~~~~~~~~~~~~~~~~~~~
-
-4.1.1 Behavior Variables:
--------------------------
-sdbc_monitor_dynmem --- D0=monitor thread shutdown in the console window
- D1=print deallocation thread stats to the console
- window
- D2=print more deallocation thread stats to the console
- window
- (usage: setting a value of 6 = 2+4 sets D1 and D2)
-sdbc_max_dyn_list ----- 1 to ?: sets the maximum host/parasite list length
- (A length of 1 prevents any multipage allocations from
- occuring and effectively removes the concept of
- host/parasite.)
-sdbc_cache_aging_ct1 -- 1 to 255: fully aged count (everything but meta and
- holdover)
-sdbc_cache_aging_ct2 -- 1 to 255: fully aged count for meta-data entries
-sdbc_cache_aging_ct3 -- 1 to 255: fully aged count for holdovers
-sdbc_cache_aging_sec1 - 1 to 255: sleep level 1 for 100% to pcnt1 free cache
- entries
-sdbc_cache_aging_sec2 - 1 to 255: sleep level 2 for pcnt1 to pcnt2 free cache
- entries
-sdbc_cache_aging_sec3 - 1 to 255: sleep level 3 for pcnt2 to 0% free cache
- entries
-sdbc_cache_aging_pcnt1- 0 to 100: cache free percent for transition from
- sleep1 to sleep2
-sdbc_cache_aging_pcnt2- 0 to 100: cache free percent for transition from
- sleep2 to sleep3
-sdbc_max_holds_pcnt --- 0 to 100: max percent of cache entries to be maintained
- as holdovers
-
-4.1.2 Statistical Variables:
-----------------------------
-Cache Stats (per wake cycle) (r/w):
-sdbc_alloc_ct --------- total allocations performed
-sdbc_dealloc_ct ------- total deallocations performed
-sdbc_history ---------- current hysterisis flag setting
-sdbc_nodatas ---------- cache entries w/o memory assigned
-sdbc_candidates ------- cache entries ready to be aged or released
-sdbc_deallocs --------- cache entries w/memory deallocated and requeued
-sdbc_hosts ------------ number of host cache entries
-sdbc_pests ------------ number of parasitic cache entries
-sdbc_metas ------------ number of meta-data cache entries
-sdbc_holds ------------ number of holdovers (fully aged w/memory and requeued)
-sdbc_others ----------- number of not [host, pests or metas]
-sdbc_notavail --------- number of cache entries to bypass (nodatas+'in use by
- other processes')
-sdbc_process_directive- D0=1 wake thread
- D1=1 temporaily accelerate aging (set the hysterisis
- flag)
-sdbc_simplect --------- simple count of the number of times the kstat update
- routine has been called (used for debugging)
-
-The behavior fields (along with the "sdbc_process_directive" field) may be both
-read and written. The remaining statistical fields are read-only.
-
-For more information, please refer to [3] in the References section.
-
-4.2 Naming characteristics:
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-module: SDBC_KSTAT_MODULE "sdbc"
-class: SDBC_KSTAT_CLASS "storedge"
-name: SDBC_KSTAT_DYNMEM "dynmem"
-instance #: 0
-
-5.0 REFERENCES FOR FURTHER READING:
-===================================
-1. generic kstat information: kstat(1M), <sys/include/kstat.h>
-2. kstat_io_t information: kstat_io(9S), kstat_queue(9F)
-3. sdbc dynamic memory implementation:
-<ds[3,4]>/src/uts/common/ns/sdbc/dynmem_readme.txt
diff --git a/usr/src/uts/common/avs/ns/sdbc/dynmem_readme.txt b/usr/src/uts/common/avs/ns/sdbc/dynmem_readme.txt
deleted file mode 100644
index d5fba71d7d..0000000000
--- a/usr/src/uts/common/avs/ns/sdbc/dynmem_readme.txt
+++ /dev/null
@@ -1,352 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-TITLE: Dynamic Memory Implementation Overview
-
-DATE: 10/13/2000
-
-AUTHOR: Jim Guerrera (james.guerrera@east)
-
-
-1.0 Dynamic Memory Implementation in the SCM Module
-
-The system memory allocation required by the Storage Cache Manager (SCM)
-has been modified to more fully conform to the requirements of the Solaris
-OS. The previous implementation required that the total memory requirements
-of the package be allocated 'up front' during bootup and was never released.
-The current implementation performs 'on demand' allocations at the time
-memory is required in a piecemeal manner. In addition the requisitioned
-memory will be released back to the system at some later time.
-
-2.0 Implementation
-
-2.1 Memory Allocation
-
-The memory allocation involves modifications primarily to sd_alloc_buf()
-in module sd_bcache.c. When a request is received for cache and system
-resources it is broken down and each piece catagorized both as an
-independent entity and as a member of a group with close neighbors. Cache
-resources comprise cache control entries (ccent), write control entries
-(wctrl for FWC support) and system memory. The current allocation algorithim
-for ccent and wrctl remains the same. The memory allocation has been modified
-and falls into two general catagories - single page and multi-page
-allocations.
-
-2.1.1 A single page allocation means exactly that - the ccent points to and
-owns one page of system memory. If two or more ccent are requisitioned to
-support the caching request then only the first entry in the group actually
-owns the the allocated memory of two or more pages. The secondary entries
-simply point to page boundaries within this larger piece of contiguous memory.
-The first entry is termed a host and the secondaries are termed parasites.
-
-The process for determining what is a host, a parasite or anything else is
-done in three phases. Phase one simply determines whether the caching request
-references a disk area already in cache and marks it as such. If it is not
-in cache it is typed as eligible - i.e. needing memory allocation. Phase
-two scans this list of typed cache entries and based on immediate neighbors
-is catagorized as host, pest or downgraded to other. A host can only exist
-if there is one or more eligible entries immediately following it and it
-itself either starts the list or immediately follows a non-eligible entry.
-If either condition proves false the catagory remains as eligible (i.e.
-needs memory allocation) but the type is cleared to not host (i.e. other).
-The next phase is simply a matter of scanning the cache entry list and
-allocating multipage memory for hosts, single page entries for others or
-simply setting up pointers in the parasitic entries into it's corresponding
-host multipage memory allocation block.
-
-2.1.2 The maximum number of parasitic entries following a host memory
-allocation is adjustable by the system administrator. The details of this
-are under the description of the KSTAT interface (Sec 3.0).
-
-2.2 Memory Deallocation
-
-Memory deallocation is implemented in sd_dealloc_dm() in module sd_io.c.
-This possibly overly complicated routine works as follows:
-
-In general the routine sleeps a specified amount of time then wakes and
-examines the entire centry list. If an entry is available (i.e. not in use
-by another thread and has memory which may be deallocated) it takes
-possession and ages the centry by one tick. It then determines if the
-centry has aged sufficiently to have its memory deallocated and for it to
-be placed at the top of the lru.
-
-2.3 There are two general deallocation schemes in place depending on
-whether the centry is a single page allocation centry or it is a member
-of a host/parasite multipage allocation chain.
-
-2.3.1 The behavior for a single page allocation centry is as follows:
-
-If the given centry is selected as a 'holdover' it will age normally
-however at full aging it will only be placed at the head of the lru.
-It's memory will not be deallocated until a further aging level has
-been reached. The entries selected for this behavior are governed by
-counting the number of these holdovers in existence on each wakeup
-and comparing it to a specified percentage. This comparision is always
-one cycle out of date and will float in the relative vicinity of the
-specified number.
-
-In addition there is a placeholder for centries identified as 'sticky
-meta-data' with its own aging counter. It operates exactly as the holdover
-entries as regards to aging but is absolute - i.e. no percentage governs
-the number of such entries.
-
-2.3.2 The percentage and additional aging count are adjustable by the
-system administrator. The details of this are under the description of
-the KSTAT interface (Sec. 3.0).
-
-2.3.3 The behavior for a host/parasite chain is as follows:
-
-The host/parasite subchain is examined. If all entries are fully aged the
-entire chain is removed - i.e memory is deallocated from the host centry
-and all centry fields are cleared and each entry requeued on to the lru.
-
-There are three sleep times and two percentage levels specifiable by the
-system administrator. A meaningful relationship between these variables
-is:
-
-sleeptime1 >= sleeptime2 >= sleeptime2 and
-100% >= pcntfree1 >= pcntfree2 >= 0%
-
-sleeptime1 is honored between 100% free and pcntfree1. sleeptime2 is
-honored between pcntfree1 and pcntfree2. sleeptime3 is honored between
-pcntfree2 and 0% free. The general thrust here is to automatically
-adjust sleep time to centry load.
-
-In addition there exist an accelerated aging flag which mimics hysterisis
-behavior. If the available centrys fall between pcntfree1 and pcntfree2
-an 8 bit counter is switched on. The effect is to keep the timer value
-at sleeptime2 for 8 cycles even if the number available cache entries
-drifts above pcntfree1. If it falls below pcntfree2 an additional 8 bit
-counter is switched on. This causes the sleep timer to remain at sleeptime3
-for at least 8 cycles even if it floats above pcntfree2 or even pcntfree1.
-The overall effect of this is to accelerate the release of system resources
-under what the thread thinks is a heavy load as measured by the number of
-used cache entries.
-
-3.0 Dynamic Memory Tuning
-
-A number of behavior modification variables are accessible via system calls
-to the kstat library. A sample program exercising the various features can
-be found in ./src/cmd/ns/sdbc/sdbc_dynmem.c. In addition the behavior variable
-identifiers can be placed in the sdbc.conf file and will take effect on bootup.
-There is also a
-number of dynamic memory statistics available to gauge its current state.
-
-3.1 Behavior Variables
-
-sdbc_monitor_dynmem --- D0=monitor thread shutdown in the console window
- D1=print deallocation thread stats to the console
- window
- D2=print more deallocation thread stats to the console
- window
- (usage: setting a value of 6 = 2+4 sets D1 and D2)
-sdbc_max_dyn_list ----- 1 to ?: sets the maximum host/parasite list length
- (A length of 1 prevents any multipage allocations from
- occuring and effectively removes the concept of
- host/parasite.)
-sdbc_cache_aging_ct1 -- 1 to 255: fully aged count (everything but meta and
- holdover)
-sdbc_cache_aging_ct2 -- 1 to 255: fully aged count for meta-data entries
-sdbc_cache_aging_ct3 -- 1 to 255: fully aged count for holdovers
-sdbc_cache_aging_sec1 - 1 to 255: sleep level 1 for 100% to pcnt1 free cache
- entries
-sdbc_cache_aging_sec2 - 1 to 255: sleep level 2 for pcnt1 to pcnt2 free cache
- entries
-sdbc_cache_aging_sec3 - 1 to 255: sleep level 3 for pcnt2 to 0% free cache
- entries
-sdbc_cache_aging_pcnt1- 0 to 100: cache free percent for transition from
- sleep1 to sleep2
-sdbc_cache_aging_pcnt2- 0 to 100: cache free percent for transition from
- sleep2 to sleep3
-sdbc_max_holds_pcnt --- 0 to 100: max percent of cache entries to be maintained
- as holdovers
-
-3.2 Statistical Variables
-
-Cache Stats (per wake cycle) (r/w):
-sdbc_alloc_ct --------- total allocations performed
-sdbc_dealloc_ct ------- total deallocations performed
-sdbc_history ---------- current hysterisis flag setting
-sdbc_nodatas ---------- cache entries w/o memory assigned
-sdbc_candidates ------- cache entries ready to be aged or released
-sdbc_deallocs --------- cache entries w/memory deallocated and requeued
-sdbc_hosts ------------ number of host cache entries
-sdbc_pests ------------ number of parasitic cache entries
-sdbc_metas ------------ number of meta-data cache entries
-sdbc_holds ------------ number of holdovers (fully aged w/memory and requeued)
-sdbc_others ----------- number of not [host, pests or metas]
-sdbc_notavail --------- number of cache entries to bypass (nodatas+'in use by
- other processes')
-sdbc_process_directive- D0=1 wake thread
- D1=1 temporaily accelerate aging (set the hysterisis
- flag)
-sdbc_simplect --------- simple count of the number of times the kstat update
- routine has been called
-
-
-3.3 Range Checks and Limits
-
-Only range limits are checked. Internal inconsistencies are not checked
-(e.g. pcnt2 > pcnt1). Inconsistencies won't break the system you just won't
-get meaningful behavior.
-
-The aging counter and sleep timer limits are arbitrarily limited to a byte
-wide counter. This can be expanded. However max'ing the values under the
-current implementation yields about 18 hours for full aging.
-
-3.4 Kstat Lookup Name
-
-The kstat_lookup() module name is "sdbc:dynmem" with an instance of 0.
-
-3.5 Defaults
-
-Default values are:
-sdbc_max_dyn_list = 8
-sdbc_monitor_dynmem = 0
-sdbc_cache_aging_ct1 = 3
-sdbc_cache_aging_ct2 = 3
-sdbc_cache_aging_ct3 = 3
-sdbc_cache_aging_sec1 = 10
-sdbc_cache_aging_sec2 = 5
-sdbc_cache_aging_sec3 = 1
-sdbc_cache_aging_pcnt1 = 50
-sdbc_cache_aging_pcnt2 = 25
-sdbc_max_holds_pcnt = 0
-
-To make the dynmem act for all intents and purposes like the static model
-beyond the inital startup the appropriate values are:
-sdbc_max_dyn_list = 1,
-sdbc_cache_aging_ct1/2/3=255,
-sdbc_cache_aging_sec1/2/3=255
-The remaining variables are irrelevant.
-
-4.0 KSTAT Implementation for Existing Statistics
-
-The existing cache statistical reporting mechanism has been replaced by
-the kstat library reporting mechanism. In general the statistics fall into
-two general catagories - global and shared. The global stats reflect gross
-behavior over all cached volumes and shared reflects behavior particular
-to each cached volume.
-
-4.1 Global KSTAT lookup_name
-
-The kstat_lookup() module name is "sdbc:gstats" with an instance of 0. The
-identifying ascii strings and associated values matching the sd_stats driver
-structure are:
-
-sdbc_dirty -------- net_dirty
-sdbc_pending ------ net_pending
-sdbc_free --------- net_free
-sdbc_count -------- st_count - number of opens for device
-sdbc_loc_count ---- st_loc_count - number of open devices
-sdbc_rdhits ------- st_rdhits - number of read hits
-sdbc_rdmiss ------- st_rdmiss - number of read misses
-sdbc_wrhits ------- st_wrhits - number of write hits
-sdbc_wrmiss ------- st_wrmiss - number of write misses
-sdbc_blksize ------ st_blksize - cache block size
-sdbc_num_memsize -- SD_MAX_MEM - number of defined blocks
- (currently 6)
-To find the size of each memory blocks append the numbers 0 to 5 to
-'sdbc_memsize'.
-sdbc_memsize0 ----- local memory
-sdbc_memsize1 ----- cache memory
-sdbc_memsize2 ----- iobuf memory
-sdbc_memsize3 ----- hash memory
-sdbc_memsize4 ----- global memory
-sdbc_memsize5 ----- stats memory
-sdbc_total_cmem --- st_total_cmem - memory used by cache structs
-sdbc_total_smem --- st_total_smem - memory used by stat structs
-sdbc_lru_blocks --- st_lru_blocks
-sdbc_lru_noreq ---- st_lru_noreq
-sdbc_lru_req ------ st_lru_req
-sdbc_num_wlru_inq - MAX_CACHE_NET - number of net (currently 4)
-To find the size of the least recently used write cache per net append
-the numbers 0-3 to sdbc_wlru_inq
-sdbc_wlru_inq0 ---- net 0
-sdbc_wlru_inq1 ---- net 1
-sdbc_wlru_inq2 ---- net 2
-sdbc_wlru_inq3 ---- net 3
-sdbc_cachesize ---- st_cachesize - cache size
-sdbc_numblocks ---- st_numblocks - cache blocks
-sdbc_num_shared --- MAXFILES*2 - number of shared structures (one for
- each cached volume)
- This number dictates the maximum
- index size for shared stats and
- names given below.
-sdbc_simplect ----- simple count of the number of times the kstat update routine
- has been called
-
-All fields are read only.
-
-
-4.2 Shared Structures KSTAT lookup_name
-
-The kstat_lookup() module name is "sdbc:shstats" and "sdbc:shname" both with
-an instance of 0. The identifying ascii strings and associated values matching
-the sd_shared driver structure are:
-
-sdbc:shstats module
-sdbc_index ------- structure index number
-sdbc_alloc ------- sh_alloc - is this allocated?
-sdbc_failed ------ sh_failed - Disk failure status (0=ok,1= /o error
- ,2= open failed)
-sdbc_cd ---------- sh_cd - the cache descriptor. (for stats)
-sdbc_cache_read -- sh_cache_read - Number of bytes read from cache
-sdbc_cache_write - sh_cache_write - Number of bytes written to cache
-sdbc_disk_read --- sh_disk_read - Number of bytes read from disk
-sdbc_disk_write -- sh_disk_write - Number of bytes written to disk
-sdbc_filesize ---- sh_filesize - Filesize
-sdbc_numdirty ---- sh_numdirty - Number of dirty blocks
-sdbc_numio ------- sh_numio - Number of blocks on way to disk
-sdbc_numfail ----- sh_numfail - Number of blocks failed
-sdbc_flushloop --- sh_flushloop - Loops delayed so far
-sdbc_flag -------- sh_flag - Flags visible to user programs
-sdbc_simplect ---- simple count of the number of times the kstat update routine
- has been called
-
-sdbc:shname module
-read in as raw bytes and interpreted as a nul terminated assci string.
-
-These two modules operate hand in hand based on information obtained from the
-"sdbc:gstats" module. "sdbc:gstats - sdbc_num_shared" gives the maximum number
-possible of shared devices. It does not tell how many devices are actually
-cached - just the maximum possible. In order to determine the number present
-and retrieve the statistics for each device the user must:
-
-1. open and read "sdbc:shstats"
-2. set the index "sdbc_index" to a starting value (presumably 0)
-3. write the kstat module ( the only item in the module is sdbc_index)
-
-What this does is set a starting index for all subsequent reads.
-
-4. to get the device count and associated statistics the user now simply
-reads each module "sdbc:shstats" and "sdbc:shname" as a group repeatedly -
-the index will auto increment
-
-To reset the index set "sdbc:shstats - sdbc_index" to the required value
-and write the module.
-
-The first entry returning a nul string to "sdbc:shname" signifies no more
-configured devices.
-
diff --git a/usr/src/uts/common/avs/ns/sdbc/safestore.c b/usr/src/uts/common/avs/ns/sdbc/safestore.c
deleted file mode 100644
index e559a2cf6f..0000000000
--- a/usr/src/uts/common/avs/ns/sdbc/safestore.c
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/ksynch.h>
-#include <sys/kmem.h>
-#include <sys/sdt.h>
-
-#include <sys/varargs.h>
-#include <sys/unistat/spcs_s.h>
-
-#include "safestore.h"
-#include "safestore_impl.h"
-#include "sd_trace.h"
-
-typedef struct safestore_modules_s {
- struct safestore_modules_s *ssm_next;
- safestore_ops_t *ssm_module;
-} safestore_modules_t;
-
-safestore_modules_t *ss_modules;
-kmutex_t safestore_mutex;
-int ss_initialized;
-
-/* the safestore module init/deinit functions */
-
-void ss_ram_init();
-void ss_ram_deinit();
-
-/* CSTYLED */
-/**#
- * initialize the safestore subsystem and all safestore
- * modules by calling all safestore modules' initialization functions
- *
- * NOTE: This function must be called with the _sdbc_config_lock held
- *
- * @param none
- * @return void
- *
- */
-void
-sst_init()
-{
- /*
- * initialize the ss modules we know about
- * this results in calls to sst_register_mod()
- */
- if (ss_initialized != SS_INITTED) {
- mutex_init(&safestore_mutex, NULL, MUTEX_DRIVER, NULL);
- ss_ram_init();
- ss_initialized = SS_INITTED;
- }
-
-}
-
-/* CSTYLED */
-/**#
- * deinitialize the safestore subsystem and all safestore modules
- * by calling all safestore modules' deinitialization functions
- *
- * NOTE: This function must be called with the _sdbc_config_lock held
- *
- * @param none
- * @return void
- *
- */
-void
-sst_deinit()
-{
- if (ss_initialized == SS_INITTED) {
- ss_ram_deinit();
- mutex_destroy(&safestore_mutex);
- ss_initialized = 0;
- }
-}
-
-/* BEGIN CSTYLED */
-/**#
- * called by a safestore module to register its ops table
- * for use by clients
- *
- * @param ss_ops structure of safestore functions
- * @return void
- *
- * @see safestore_ops_t{}
- */
-void
-sst_register_mod(safestore_ops_t *ss_ops) /* END CSTYLED */
-{
- safestore_modules_t *new;
-
- new = kmem_alloc(sizeof (*new), KM_SLEEP);
-
- mutex_enter(&safestore_mutex);
- new->ssm_module = ss_ops;
- new->ssm_next = ss_modules;
-
- ss_modules = new;
- mutex_exit(&safestore_mutex);
-}
-
-/* BEGIN CSTYLED */
-/**#
- * called by a safestore module to unregister its ops table
- * @param ss_ops structure of safestore functions
- *
- * @return void
- *
- * @see safestore_ops_t{}
- */
-void
-sst_unregister_mod(safestore_ops_t *ss_ops) /* END CSTYLED */
-{
- safestore_modules_t *ssm, *prev;
- int found = 0;
-
- mutex_enter(&safestore_mutex);
- prev = NULL;
- for (ssm = ss_modules; ssm; prev = ssm, ssm = ssm->ssm_next) {
- if (ssm->ssm_module == ss_ops) {
- if (!prev)
- ss_modules = ssm->ssm_next;
- else
- prev->ssm_next = ssm->ssm_next;
-
- kmem_free(ssm, sizeof (safestore_modules_t));
- ++found;
- break;
- }
- }
- mutex_exit(&safestore_mutex);
-
- if (!found)
- cmn_err(CE_WARN, "ss(sst_unregister_mod) "
- "ss module %p not found", (void *)ss_ops);
-}
-
-/* BEGIN CSTYLED */
-/**#
- * open a safestore module for use by a client
- * @param ss_type specifies a valid media type and transport type.
- * the first module found that supports these reqested type
- * is used. may contain more than one media type or transport
- * type if client has no preference among several types.
- * more than one ss_type may be specified in the call if
- * client has an ordered preference.
- *
- * @return safestore_ops_t * pointer to a valid safestore ops structure
- * if the request is satisfied.
- * NULL otherwise
- *
- * @see safestore_ops_t{}
- * @see SS_M_RAM
- * @see SS_M_NV_SINGLENODE
- * @see SS_M_NV_DUALNODE_NOMIRROR
- * @see SS_M_NV_DUALNODE_MIRROR
- * @see SS_T_STE
- * @see SS_T_RPC
- * @see SS_T_NONE
- */
-safestore_ops_t *
-sst_open(uint_t ss_type, ...) /* END CSTYLED */
-{
- va_list ap;
- uint_t ssop_type;
- safestore_modules_t *ssm;
-
- if ((ss_modules == NULL) || !ss_type)
- return (NULL);
-
- va_start(ap, ss_type);
- mutex_enter(&safestore_mutex);
- do {
- for (ssm = ss_modules; ssm; ssm = ssm->ssm_next) {
- ssop_type = ssm->ssm_module->ssop_type;
- if ((ssop_type & SS_MEDIA_MASK) & ss_type)
- if ((ssop_type & SS_TRANSPORT_MASK) & ss_type) {
- va_end(ap);
- mutex_exit(&safestore_mutex);
- return (ssm->ssm_module);
- }
- }
- } while ((ss_type = va_arg(ap, uint_t)) != 0);
- mutex_exit(&safestore_mutex);
-
- va_end(ap);
- return (NULL);
-}
-
-/* BEGIN CSTYLED */
-/**#
- * close a safestore module. called when client no longer wishes to use
- * a safestore module
- *
- * @param ssp points to a safestore_ops_t obtained from a previous call
- * to sst_open()
- *
- * @return SS_OK if successful
- * SS_ERR otherwise
- */
-/*ARGSUSED*/
-int
-sst_close(safestore_ops_t *ssp) /* END CSTYLED */
-{
- return (SS_OK);
-}
-
-
-/*
- * _sdbc_writeq_configure - configure the given writeq
- * Allocate the lock and sv we need to maintain waiters
- *
- */
-int
-_sdbc_writeq_configure(_sd_writeq_t *wrq)
-{
- int i;
-
- wrq->wq_inq = 0;
- mutex_init(&wrq->wq_qlock, NULL, MUTEX_DRIVER, NULL);
- wrq->wq_qtop = NULL;
- wrq->wq_slp_top = 0;
- wrq->wq_slp_index = 0;
- wrq->wq_slp_inq = 0;
-
- for (i = 0; i < SD_WR_SLP_Q_MAX; i++) {
- wrq->wq_slp[i].slp_wqneed = 0;
- cv_init(&wrq->wq_slp[i].slp_wqcv, NULL, CV_DRIVER, NULL);
- }
-
- return (0);
-}
-
-/*
- * _sdbc_writeq_deconfigure - deconfigure the given writeq
- * Deallocate the lock and sv if present.
- *
- */
-void
-_sdbc_writeq_deconfigure(_sd_writeq_t *wrq)
-{
- int i;
-
- if (wrq) {
- mutex_destroy(&wrq->wq_qlock);
- for (i = 0; i < SD_WR_SLP_Q_MAX; i++) {
- cv_destroy(&wrq->wq_slp[i].slp_wqcv);
- }
- wrq->wq_inq = 0;
- wrq->wq_qtop = NULL;
- }
-
-}
-
-
-int _sd_wblk_sync = 1;
-
-ss_wr_cctl_t *
-ss_alloc_write(int need, int *stall, _sd_writeq_t *q)
-{
- ss_wr_cctl_t *wctl;
- ss_wr_cctl_t *ret;
- int i;
- int aged = 0;
-
- if (_sd_wblk_sync && (q->wq_inq == 0))
- return (NULL); /* do sync write if queue empty */
-
- SDTRACE(ST_ENTER|SDF_WR_ALLOC, SDT_INV_CD, need,
- SDT_INV_BL, q->wq_inq, _SD_NO_NET);
-
- if (need <= 0) {
- cmn_err(CE_WARN, "ss_alloc_write: bogus need value! %d", need);
- return (NULL);
- }
-
- mutex_enter(&(q->wq_qlock));
-retry_wr_get:
- if (q->wq_inq < need) {
- if (!_sd_wblk_sync) {
- unsigned stime;
- stime = nsc_usec();
-
- /*
- * Try to keep requests ordered so large requests
- * are not starved. We can queue 255 write requests,
- * After That go into write-through.
- */
- if (q->wq_slp_inq < SD_WR_SLP_Q_MAX) {
- q->wq_slp_inq++;
- /* give preference to aged requests */
- if (aged) {
- WQ_SVWAIT_TOP(q, need);
- } else {
- WQ_SVWAIT_BOTTOM(q, need);
- }
- aged++;
- } else {
- mutex_exit(&(q->wq_qlock));
- return (NULL);
- }
-
- SDTRACE(ST_INFO|SDF_WR_ALLOC,
- SDT_INV_CD, need, SDT_INV_BL, q->wq_inq,
- (nsc_usec()-stime));
- (void) (*stall)++;
- goto retry_wr_get;
- }
- ret = NULL;
- } else {
-get_wctl:
- wctl = q->wq_qtop;
- ret = wctl;
- DTRACE_PROBE1(alloc_write,
- ss_wr_cctl_t *, wctl);
- for (i = 1; i < need; ++i) {
- wctl = wctl->wc_next;
- DTRACE_PROBE1(alloc_write_cont,
- ss_wr_cctl_t *, wctl);
- }
-
- q->wq_qtop = wctl->wc_next;
- wctl->wc_next = NULL;
- q->wq_inq -= need;
- }
- mutex_exit(&(q->wq_qlock));
-
- SDTRACE(ST_EXIT|SDF_WR_ALLOC, SDT_INV_CD, need,
- SDT_INV_BL, q->wq_inq, _SD_NO_NET);
- return (ret);
-}
-
-/*
- * ss_release_write - put a write block back in the writeq.
- *
- * ARGUMENTS:
- * wctl - Write control block to be release.
- * q - write q to put the wctl
- *
- * RETURNS: NONE
- */
-
-void
-ss_release_write(ss_wr_cctl_t *wctl, _sd_writeq_t *q)
-{
-
- SDTRACE(ST_ENTER|SDF_WR_FREE, SDT_INV_CD, 0, SDT_INV_BL, q->wq_inq,
- _SD_NO_NET);
-
- DTRACE_PROBE1(release_write,
- ss_wr_cctl_t *, wctl);
-
-#if defined(_SD_DEBUG)
- if (wctl->wc_gl_info->sci_dirty) {
- SDALERT(SDF_WR_FREE, wctl->wc_gl_info->sci_cd,
- 0, wctl->wc_gl_info->sci_fpos,
- wctl->wc_gl_info->sci_dirty, 0);
- }
-#endif
- mutex_enter(&q->wq_qlock);
-
- wctl->wc_next = q->wq_qtop;
- q->wq_qtop = wctl;
- q->wq_inq++;
- if (WQ_NEED_SIG(q)) {
- q->wq_slp_inq--;
- WQ_SVSIG(q);
- }
- mutex_exit(&q->wq_qlock);
- SDTRACE(ST_EXIT|SDF_WR_FREE, SDT_INV_CD, 0, SDT_INV_BL, q->wq_inq,
- _SD_NO_NET);
-}
diff --git a/usr/src/uts/common/avs/ns/sdbc/safestore.h b/usr/src/uts/common/avs/ns/sdbc/safestore.h
deleted file mode 100644
index a25e3c794b..0000000000
--- a/usr/src/uts/common/avs/ns/sdbc/safestore.h
+++ /dev/null
@@ -1,655 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SD_SAFESTORE_H
-#define _SD_SAFESTORE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/nsc_thread.h>
-#ifdef DS_DDICT
-#include <sys/nsctl/contract.h>
-#endif
-#include <sys/nsctl/nsctl.h>
-#if defined(_KERNEL) || defined(_KMEMUSER)
-
-/* CSTYLED */
-/**$
- * token for a volume directory stream
- */
-typedef struct ss_vdir_s {
- intptr_t opaque[6];
-} ss_vdir_t;
-
-/* CSTYLED */
-/**$
- * token for a cache entry directory stream
- */
-typedef struct ss_cdir_s {
- intptr_t opaque[6];
-}ss_cdir_t;
-
-/* CSTYLED */
-/**$
- * token for a volume
- */
-typedef struct ss_vol_s {
- intptr_t opaque;
-}ss_vol_t;
-
-/* CSTYLED */
-/**$
- * token for cache entry block and dirty bits
- */
-typedef struct s_resource_s {
- intptr_t opaque;
-} ss_resource_t;
-
-/* CSTYLED */
-/**$
- * token for a list of cache safestore resources
- */
-typedef struct ss_resourcelist_s {
- intptr_t opaque;
-}ss_resourcelist_t;
-
-
-/* CSTYLED */
-/**$
- * cache entry directory stream type specifier
- *
- * @field ck_type specifies all cache entries, cache entries for volume, node
- * @field ck_vol volume token if ck_type is CDIR_VOL
- * @field ck_node node id if ck_type is node CDIR_NODE
- */
-typedef struct ss_cdirkey_s {
- uint_t ck_type; /* discriminator: see type defines below */
- union {
- ss_vol_t *ck_vol;
- uint_t ck_node;
- } cdk_u;
-} ss_cdirkey_t;
-
-/* centry directory stream types */
-#define CDIR_ALL 0
-#define CDIR_VOL 1
-#define CDIR_NODE 2
-
-/* BEGIN CSTYLED */
-/**$
- * exported cache entry info
- *
- * @field sc_cd the cache descriptor, associates this entry with a volume
- * @field sc_fpos file position in cache blocks
- * @field sc_dirty dirty bits, one for each fba in the cache block
- * @field sc_flag flags
- * @field sc_res safestore resource token for this cache entry
- * @see ss_voldata_t{}
- */
-typedef struct ss_centry_info_s {
- int sc_cd; /* Cache descriptor */
- nsc_off_t sc_fpos; /* File position */
- int sc_dirty; /* Dirty mask */
- int sc_flag; /* CC_PINNABLE | CC_PINNED */
- ss_resource_t *sc_res; /* token for this centry */
-} ss_centry_info_t;
-/* END CSTYLED */
-
-
-/* CSTYLED */
-/**$
- * volume directory stream type specifier
- *
- * @field vk_type specifies all volume entries, entries for volume, node
- * @field vk_vol volume token if vk_type is VDIR_VOL
- * @field vk_node node id if vk_type is node VDIR_NODE
- */
-typedef struct ss_vdirkey_s {
- uint_t vk_type; /* discriminator: see type defines below */
- union {
- ss_vol_t *vk_vol;
- uint_t vk_node;
- } cdk_u;
-} ss_vdirkey_t;
-
-/* volume directory stream types */
-#define VDIR_ALL 0
-#define VDIR_VOL 1
-#define VDIR_NODE 2
-
-/* CSTYLED */
-/**$
- * exported volume entry info
- *
- * @field sv_cd the cache descriptor
- * @field sv_vol the safestore volume token for this volume
- * @field sv_pinned volume has pinned blocks, holds node id
- * @field sv_attached node which has attached this volume
- * @field sv_volname path name
- * @field sv_devidsz length of device id, the sv_devid
- * @field sv_devid unique id for physical, i.e. non-volume-managed volumes
- */
-typedef struct ss_voldata_s {
- int sv_cd; /* NOTE may need dual node map info */
- ss_vol_t *sv_vol; /* volume token for this vol entry */
- int sv_pinned; /* Device has failed/pinned blocks */
- int sv_attached; /* Node which has device attached */
- char sv_volname[NSC_MAXPATH]; /* Filename */
- int sv_devidsz; /* unique dev id length */
- uchar_t sv_devid[NSC_MAXPATH]; /* wwn id - physical devs only */
-} ss_voldata_t;
-
-/* safestore media types */
-
-/* CSTYLED */
-/**%
- * safestore in RAM, useful but not very safe
- */
-#define SS_M_RAM 0x00000001
-
-/* CSTYLED */
-/**%
- * safestore in NVRAM on a single node
- */
-#define SS_M_NV_SINGLENODE 0x00000002
-
-/* CSTYLED */
-/**%
- * safestore in NVRAM on a dual node system. all data is store remotely.
- */
-#define SS_M_NV_DUALNODE_NOMIRROR 0x00000004
-
-/* CSTYLED */
-/**%
- * safestore in NVRAM on a dual node system. data is mirrored on both nodes.
- */
-#define SS_M_NV_DUALNODE_MIRROR 0x00000008
-
-
-/* safestore data and metadata transport types */
-
-/* CSTYLED */
-/**%
- * data is transferred using STE connection
- */
-#define SS_T_STE 0x00010000
-
-/* CSTYLED */
-/**%
- * data is transferred using RPC
- */
-#define SS_T_RPC 0x00020000
-
-/* CSTYLED */
-/**%
- * no transport -- (single node)
- */
-#define SS_T_NONE 0x08000000
-
-#define SS_MEDIA_MASK 0x0000ffff
-#define SS_TRANSPORT_MASK 0xffff0000
-
-#define _SD_NO_NET 0
-#define _SD_NO_NETADDR 0
-#define _SD_NO_HOST -1
-#define _SD_NO_CD -1
-
-/* config settings */
-#define SS_UNCONFIGURED 0
-#define SS_INITTED 1
-#define SS_CONFIGURED 2
-
-/* error return for safestore ops */
-#define SS_ERR -1
-#define SS_OK 0
-#define SS_EOF 1
-
-/* config flag */
-#define SS_GENPATTERN 1
-
-/*
- * convenience macros. should they be implemented in ss_ctl()?
- */
-
-/* is safestore on a single node? */
-#define SAFESTORE_LOCAL(ssp) ((ssp) && (ssp->ssop_type & SS_T_NONE))
-
-/* is safestore really safe or is it just RAM? */
-#define SAFESTORE_SAFE(ssp) ((ssp) && !(ssp->ssop_type & SS_M_RAM))
-
-/* is recovery needed with this safestore module? */
-#define SAFESTORE_RECOVERY(ssp) ((ssp) && \
- (ssp->ssop_flags & SS_RECOVERY_NEEDED))
-
-/* CSTYLED */
-/**$
- * configuration structure provided by safestore client
- *
- * @field ssc_configured set by safestore module to indicate config completed
- * @field ssc_ss_psize safestore internal page size, set by ss module
- * @field ssc_client_psize callers page size
- * @field ssc_wsize cache size in bytes: amount of data that can be safestored
- * @field ssc_maxfiles maximum number of volumes
- * @field ssc_pattern initialization pattern if any
- * @field ssc_flag use ssc_pattern if this is SS_GENPATTERN
- */
-typedef struct ss_common_config_s {
- uint_t ssc_configured;
- uint_t ssc_ss_psize; /* safestore internal page size */
- uint_t ssc_client_psize; /* client page size */
- uint_t ssc_wsize; /* Write cache size in bytes */
- int ssc_maxfiles; /* max files */
- uint_t ssc_pattern; /* initialization pattern */
- uint_t ssc_flag;
-} ss_common_config_t;
-
-/* BEGIN CSTYLED */
-/**$
- * safestore operations structure
- *
- * @field ssop_name description of this module.
- * @field ssop_type media type OR'd with transport type
- * @field ssop_flags SS_RECOVERY_NEEDED
- * @field ssop_configure configure the module
- * @field ssop_deconfigure deconfigure the module
- * @field ssop_getvdir get a volume directory stream according to type
- * @field ssop_getvdirent get next entry in a volume directory stream
- * @field ssop_getvol get the data for a volume
- * @field ssop_setvol set the data for a volume
- * @field ssop_getcdir get cache entry directory stream according to type
- * @field ssop_getcdirent get next cache entry in stream
- * @field ssop_allocresource allocate safestore resources from free list
- * @field ssop_deallocresource deallocate, i.e. free, a safestore resource
- * @field ssop_getresource get next resource in resource list
- * @field ssop_getcentry get metadata for a cache entry
- * @field ssop_setcentry set the metadata for a cache entry
- * @field ssop_read_cblock read the actual data for a cache entry
- * @field ssop_write_cblock write the data for a cache entry
- * @field ssop_ctl module entry point for everything else, e.g. stats
- *
- * @see ss_vdirkey_t{}
- * @see ss_voldata_t{}
- * @see ss_cdirkey_t{}
- * @see ss_resourcelist_t{}
- * @see ss_resource_t{}
- * @see ss_centry_info_t{}
- */
-typedef struct safestore_ops_s {
- char *ssop_name;
- uint_t ssop_type; /* media type OR'd with transport type */
- uint_t ssop_flags; /* recovery needed, etc */
- int (* ssop_configure)(ss_common_config_t *, spcs_s_info_t);
- int (* ssop_deconfigure)(int);
- int (* ssop_getvdir)(const ss_vdirkey_t *, ss_vdir_t *);
- int (* ssop_getvdirent)(const ss_vdir_t *, ss_voldata_t *);
- int (* ssop_getvol)(ss_voldata_t *);
- int (* ssop_setvol)(const ss_voldata_t *);
- int (* ssop_getcdir)(const ss_cdirkey_t *, ss_cdir_t *);
- int (* ssop_getcdirent)(ss_cdir_t *, ss_centry_info_t *);
- int (* ssop_allocresource)(int, int *, ss_resourcelist_t **);
- void (* ssop_deallocresource)(ss_resource_t *);
- int (* ssop_getresource)(ss_resourcelist_t **, ss_resource_t **);
- int (* ssop_getcentry)(ss_centry_info_t *);
- int (* ssop_setcentry)(const ss_centry_info_t *);
- int (* ssop_read_cblock)(const ss_resource_t *, void *, int, int);
- int (* ssop_write_cblock)(const ss_resource_t *,
- const void *, int, int);
- int (* ssop_ctl)(uint_t, uintptr_t);
-} safestore_ops_t;
-/* END CSTYLED */
-
-/* ssop_flags */
-/*
- * no writes permitted when this bit is set in ssop flags field
- * (single node nvram mostly)
- */
-#define SS_RECOVERY_NEEDED 1
-
-/* safestore operations */
-
-/* BEGIN CSTYLED */
-/**#
- * SSOP_CONFIGURE() configure a safestore module
- * @param ssp a safestore_ops_t pointer obtained from sst_open()
- * @param cfg a pointer to ss_common_config_t, initialized by caller
- * @param kstatus unistat spcs_s_info_t
- * @return SS_OK successful, errno otherwise
- *
- * @see safestore_ops_t{}
- * @see sst_open()
- * @see ss_common_config_t{}
- */
-#define SSOP_CONFIGURE(ssp, cfg, kstatus) \
- ((ssp)->ssop_configure(cfg, kstatus))
-
-/**#
- * SSOP_DECONFIGURE deconfigure a safestore module
- * @param ssp a safestore_ops_t pointer obtained from sst_open()
- * @param dirty integer flag, if set it signifies there is pinned data
- * @return SS_OK success, SS_ERR otherwise
- *
- * @see safestore_ops_t{}
- */
-#define SSOP_DECONFIGURE(ssp, dirty) ((ssp)->ssop_deconfigure(dirty))
-
-
-/* volume directory functions */
-
-/**#
- * SSOP_GETVDIR get a volume directory stream according to type
- * @param ssp a safestore_ops_t pointer obtained from sst_open()
- * @param key pointer to ss_vdirkey_t initialized by caller
- * @param vdir pointer to ss_vdir_t owned by caller
- * @return SS_OK success, SS_ERR otherwise
- *
- * @see safestore_ops_t{}
- * @see ss_vdirkey_t{}
- * @see ss_vdir_t{}
- */
-#define SSOP_GETVDIR(ssp, key, vdir) ((ssp)->ssop_getvdir(key, vdir))
-
-/**#
- * SSOP_GETVDIRENT get next volume in a volume directory stream
- * @param ssp a safestore_ops_t pointer obtained from sst_open()
- * @param vdir pointer to a properly initialized ss_vdir_t obtained
- * from a successsful SSOP_GETVDIR() call
- * @param voldata pointer to ss_voldata_t owned by caller, filled
- * in with valid data on successful return
- * @return SS_OK success
- * SS_EOF if no more elements in stream,
- * SS_ERR otherwise
- *
- * @see safestore_ops_t{}
- * @see sst_open()
- * @see ss_vdir_t{}
- * @see ss_voldata_t{}
- * @see SSOP_GETVDIR()
- */
-#define SSOP_GETVDIRENT(ssp, vdir, voldata) \
- ((ssp)->ssop_getvdirent(vdir, voldata))
-
-/* volume accessor functions */
-
-/**#
- * SSOP_GETVOL get the volume data for a particular volume
- * @param ssp a safestore_ops_t pointer obtained from sst_open()
- * @param voldata pointer to ss_voldata_t owned by caller, field sv_vol
- * must be initialized with a valid ss_vol_t, normally
- * obtained from a successful SSOP_GETVDIRENT() call.
- * the rest of the structure is filled with valid volume data
- * on successful return
- * @return SS_OK if data read successfully
- * SS_ERR otherwise
- * @see safestore_ops_t{}
- * @see sst_open()
- * @see ss_voldata_t{}
- * @see ss_vol_t{}
- * @see SSOP_GETVDIRENT()
- */
-#define SSOP_GETVOL(ssp, voldata) ((ssp)->ssop_getvol(voldata))
-
-
-/**#
- * SSOP_SETVOL set the volume data for a particular volume
- * @param ssp a safestore_ops_t pointer obtained from sst_open()
- * @param voldata pointer to ss_voldata_t owned by caller, field sv_vol
- * must be initialized with a valid ss_vol_t, obtained from
- * a successful SSOP_GETVDIRENT() call. the remaining
- * fields of the structure are written to safestore
- * @return SS_OK if data saved successfully
- * SS_ERR otherwise
- * @see safestore_ops_t{}
- * @see sst_open()
- * @see ss_voldata_t{}
- * @see ss_vol_t{}
- * @see SSOP_GETVDIRENT()
- */
-#define SSOP_SETVOL(ssp, voldata) ((ssp)->ssop_setvol(voldata))
-
-/* centry directory functions */
-
-/**#
- * SSOP_GETCDIR get a cache entry stream accroding to type
- * @param ssp a safestore_ops_t pointer obtained from sst_open()
- * @param key pointer to a ss_cdirkey_t initialized by caller
- * @param cdir pointer to ss_cdir_t owned by caller
- * @return SS_OK success, SS_ERR otherwise
- *
- * @see safestore_ops_t{}
- * @see sst_open()
- * @see ss_cdirkey_t{}
- * @ see ss_cdir_t{}
- */
-#define SSOP_GETCDIR(ssp, key, cdir) \
- ((ssp)->ssop_getcdir(key, cdir))
-
-/**#
- * SSOP_GETCDIRENT get next cache entry in a cache entry stream
- * @param ssp a safestore_ops_t pointer obtained from sst_open()
- * @param cdir pointer to valid ss_cdirkey_t obtained from a
- * successsful SSOP_GETCDIR call
- * @param voldata pointer to ss_voldata_t owned by caller, filled
- * in with valid data on successful return
- * @return SS_OK success
- * SS_EOF if no more elements in stream,
- * SS_ERR otherwise
- *
- * @see safestore_ops_t{}
- * @see sst_open()
- * @see ss_vdirkey_t{}
- * @see ss_voldata_t{}
- * @see SSOP_GETVDIR()
- */
-#define SSOP_GETCDIRENT(ssp, cdir, centry) \
- ((ssp)->ssop_getcdirent(cdir, centry))
-
-/* cache entry alloc functions */
-
-/**#
- * SSOP_ALLOCRESOURCE allocate safestore resources from the free list
- * @param ssp a safestore_ops_t pointer obtained from sst_open()
- * @param count number of resources, that is data blocks, needed
- * @param stall integer pointer to stall count, no blocks available. used only
- * when _sd_wblk_sync === 0
- * @param reslist pointer to pointer to ss_resourcelist_t. points to valid
- * resource list on successful return
- * @return SS_OK success
- * SS_ERR otherwise
- *
- * @see safestore_ops_t{}
- * @see ss_resourcelist_t{}
- * @see SSOP_DEALLOCRESOURCE()
- * @see SSOP_GETRESOURCE()
- */
-#define SSOP_ALLOCRESOURCE(ssp, count, stall, reslist) \
- ((ssp)->ssop_allocresource(count, stall, reslist))
-
-/**#
- * SSOP_DEALLOCRESOURCE deallocate, i.e. release, a single safestore resource
- * @param ssp a safestore_ops_t pointer obtained from sst_open()
- * @param res pointer to ss_resource_t to be released
- * @return void
- *
- * @see safestore_ops_t{}
- * @see ss_resource_t{}
- * @see SSOP_ALLOCRESOURCE()
- * @see SSOP_GETRESOURCE()
- */
-#define SSOP_DEALLOCRESOURCE(ssp, res) \
- ((ssp)->ssop_deallocresource(res))
-
-/**#
- * SSOP_GETRESOURCE get the next safestore resource in a list
- * @param ssp a safestore_ops_t pointer obtained from sst_open()
- * @param reslist pointer to pointer to ss_resourcelist_t obtained from
- * a successful call to SSOP_ALLOCRESOURCE()
- * @param res pointer to pointer to ss_resource_t. points to a valid
- * on successful resource
- * @return SS_OK success
- * SS_EOF if no more resources in list
- * SS_ERR otherwise
- *
- * @see safestore_ops_t{}
- * @see ss_resourcelist_t{}
- * @see ss_resource_t{}
- * @see SSOP_ALLOCRESOURCE()
- * @see SSOP_DEALLOCRESOURCE()
- */
-#define SSOP_GETRESOURCE(ssp, reslist, res) \
- ((ssp)->ssop_getresource(reslist, res))
-
-/* centry accessor functions */
-
-
-/**#
- * SSOP_GETCENTRY read cache entry metadata for a particular cache entry
- * @param ssp a safestore_ops_t pointer obtained from sst_open()
- * @param centry_info pointer to ss_centry_info_t owned by caller.
- * field sc_res must point to a valid ss_resource_t
- * obtained from a successful call to SSOP_GETRESOURCE().
- * the rest of the structure is filled with valid
- * metadata on successful return
- * @return SS_OK if data was read successfully
- * SS_ERR otherwise
- *
- * @see safestore_ops_t{}
- * @see sst_open()
- * @see ss_centry_info_t
- * @see ss_resource_t{}
- * @see SSOP_GETRESOURCE()
- */
-#define SSOP_GETCENTRY(ssp, centry_info) \
- ((ssp)->ssop_getcentry(centry_info))
-
-/**#
- * SSOP_SETCENTRY write cache entry metadata for a particular cache entry
- * @param ssp a safestore_ops_t pointer obtained from sst_open()
- * @param centry_info pointer to ss_centry_info_t owned by caller.
- * field sc_res must point to a valid ss_resource_t
- * obtained from a successful call to SSOP_GETRESOURCE().
- * the remaining fields of the structured are written
- * to safestore.
- * @return SS_OK if data was written successfully
- * SS_ERR otherwise
- *
- * @see safestore_ops_t{}
- * @see sst_open()
- * @see ss_centry_info_t{}
- * @see ss_resource_t{}
- * @see SSOP_GETRESOURCE()
- */
-#define SSOP_SETCENTRY(ssp, centry_info) \
- ((ssp)->ssop_setcentry(centry_info))
-
-/* cache data block read/write and ctl */
-
-
-/**#
- * SSOP_READ_CBLOCK read cache data for a particular cache entry
- * @param ssp a safestore_ops_t pointer obtained from sst_open()
- * @param resource pointer to ss_resource_t obtained from a successful
- * call to SSOP_GETRESOURCE().
- * @param buf buffer to hold the data
- * @param nbyte number of bytes to read
- * @param srcoffset byte location from beginning of the cache block
- * represented by resource to read the data from
- *
- * @return SS_OK if data was read successfully
- * SS_ERR otherwise
- *
- * @see safestore_ops_t{}
- * @see sst_open()
- * @see ss_resource_t{}
- * @see SSOP_GETRESOURCE()
- */
-#define SSOP_READ_CBLOCK(ssp, resource, buf, nbyte, srcoffset) \
- ((ssp)->ssop_read_cblock(resource, buf, nbyte, srcoffset))
-/**#
- * SSOP_WRITE_CBLOCK write cache data for a particular cache entry
- * @param ssp a safestore_ops_t pointer obtained from sst_open()
- * @param resource pointer to ss_resource_t obtained from a successful
- * call to SSOP_GETRESOURCE().
- * @param buf buffer to hold the data
- * @param nbyte number of bytes to write
- * @param destoffset byte location from beginning the cache block
- * represented by resource to write the data to
- *
- * @return SS_OK if data was read successfully
- * SS_ERR otherwise
- *
- * @see safestore_ops_t{}
- * @see sst_open()
- * @see ss_resource_t{}
- * @see SSOP_GETRESOURCE()
- */
-#define SSOP_WRITE_CBLOCK(ssp, resource, buf, nbyte, destoffset) \
- ((ssp)->ssop_write_cblock(resource, buf, nbyte, destoffset))
-
-/**#
- * SSOP_CTL perform a safestore control function
- * @param cmd integer specifying the command to execute, e.g. SSIOC_STATS.
- * some commands may be specific to a safestore module type
- * @param arg a uintptr_t that has additional information that is
- * needed by the safestore module to perform the command. it
- * may be an int or a pionter to a module specifc structure.
- * @return SS_OK success
- * errno otherwise
- */
-#define SSOP_CTL(ssp, cmd, arg) ((ssp)->ssop_ctl(cmd, arg))
-
-/* END CSTYLED */
-
-/* general control definitions supported by safestore modules */
-
-#define SSCTL(x) (('S'<< 16)|('S'<< 8)|(x))
-
-#define SSIOC_STATS SSCTL(1)
-#define SSIOC_SETFLAG SSCTL(2)
-
-/* structure definitions */
-
-typedef struct ssioc_stats_s {
- int wq_inq; /* write queue count */
-} ssioc_stats_t;
-
-extern void sst_init();
-extern void sst_register_mod(safestore_ops_t *);
-extern void sst_unregister_mod(safestore_ops_t *);
-extern safestore_ops_t *sst_open(uint_t, ...);
-extern int sst_close(safestore_ops_t *);
-
-extern safestore_ops_t *sdbc_safestore;
-
-extern int _sd_centry_shift;
-
-#endif /* _KERNEL */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SD_SAFESTORE_H */
diff --git a/usr/src/uts/common/avs/ns/sdbc/safestore_impl.h b/usr/src/uts/common/avs/ns/sdbc/safestore_impl.h
deleted file mode 100644
index bc623446d0..0000000000
--- a/usr/src/uts/common/avs/ns/sdbc/safestore_impl.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SD_SAFESTORE_IMPL_H
-#define _SD_SAFESTORE_IMPL_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef _KERNEL
-
-/* ss config stages */
-#define SD_WR_SLP_Q_MAX 256
-
-/*
- * Global fields for cache LRU entry. Fault tolerant structure in RMS.
- */
-
-#define INCX(x) (x = (x + 1 + SD_WR_SLP_Q_MAX) % SD_WR_SLP_Q_MAX)
-#define DECX(x) (x = (x - 1 + SD_WR_SLP_Q_MAX) % SD_WR_SLP_Q_MAX)
-
-typedef struct _sd_wr_slp_queue {
- kcondvar_t slp_wqcv;
- int slp_wqneed;
-} _sd_wr_slp_queue_t;
-
-typedef struct _sd_wr_queue {
- struct ss_wr_cctl *wq_qtop; /* Top of write control blocks */
- kmutex_t wq_qlock; /* allocation spinlock */
- int wq_inq; /* number of write blocks available in q */
- int wq_nentries; /* total Number of write blocks in q */
- unsigned int wq_slp_top;
- unsigned int wq_slp_index;
- unsigned int wq_slp_inq;
- _sd_wr_slp_queue_t wq_slp[SD_WR_SLP_Q_MAX];
-} _sd_writeq_t;
-
-#define WQ_SET_NEED(q, need, i) { \
- (q->wq_slp[i].slp_wqneed = need); \
-}
-
-#define WQ_SVWAIT_BOTTOM(q, need) \
-{ \
- int ix = q->wq_slp_index; \
- INCX(q->wq_slp_index); \
- WQ_SET_NEED(q, need, ix); \
- cv_wait(&q->wq_slp[ix].slp_wqcv, &q->wq_qlock); \
- mutex_exit(&q->wq_qlock); \
-}
-
-#define WQ_SVWAIT_TOP(q, need) \
-{ \
- DECX(q->wq_slp_top); \
- WQ_SET_NEED(q, need, q->wq_slp_top); \
- cv_wait(&q->wq_slp[q->wq_slp_top].slp_wqcv, &q->wq_qlock);\
- mutex_exit(&q->wq_qlock); \
-}
-
-#define WQ_NEED_SIG(q) \
- (q->wq_slp_inq && (q->wq_slp[q->wq_slp_top].slp_wqneed <= q->wq_inq))
-
-#define WQ_SVSIG(q) \
-{ \
- int tp = q->wq_slp_top; \
- INCX(q->wq_slp_top); \
- q->wq_slp[tp].slp_wqneed = 0; \
- cv_signal(&q->wq_slp[tp].slp_wqcv); \
-}
-
-/*
- * cache entry information
- * note -- this structure is a identical to the first 4 words of
- * the exported ss_centry_info_t. internal copies depened on this
- * fact. changes to this structure may require changes to the
- * *getcentry() and *setcentry() functions.
- *
- */
-typedef struct ss_centry_info_impl_s {
- int sci_cd; /* Cache descriptor */
- nsc_off_t sci_fpos; /* File position */
- int sci_dirty; /* Dirty mask */
- int sci_flag; /* CC_PINNABLE | CC_PINNED */
-} ss_centry_info_impl_t;
-
-/*
- * The write control structure has information about the remote page that
- * will mirror a write.
- */
-typedef struct ss_wr_cctl {
- struct ss_wr_cctl *wc_next; /* chaining queue entries */
- caddr_t wc_addr; /* points to data address */
- ss_centry_info_impl_t *wc_gl_info; /* information for the page */
- unsigned char wc_flag; /* flag */
-} ss_wr_cctl_t;
-
-/* volume information */
-typedef struct ss_voldata_impl_s {
- char svi_volname[NSC_MAXPATH]; /* Filename in RMS for failover */
- int svi_cd; /* NOTE may need dual node map info */
- int svi_pinned; /* Device has failed/pinned blocks */
- int svi_attached; /* Node which has device attached */
- int svi_devidsz; /* unique dev id length */
- uchar_t svi_devid[NSC_MAXPATH]; /* wwn id - physical devs only */
- int svi_reserved[13]; /* Reserved global space */
-} ss_voldata_impl_t;
-
-extern int _sd_fill_pattern(caddr_t addr, uint_t pat, uint_t size);
-extern int _sdbc_writeq_configure(_sd_writeq_t *);
-extern void _sdbc_writeq_deconfigure(_sd_writeq_t *);
-extern void ss_release_write(ss_wr_cctl_t *, _sd_writeq_t *);
-extern ss_wr_cctl_t *ss_alloc_write(int, int *, _sd_writeq_t *);
-
-#endif /* _KERNEL */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SD_SAFESTORE_IMPL_H */
diff --git a/usr/src/uts/common/avs/ns/sdbc/safestore_ram.c b/usr/src/uts/common/avs/ns/sdbc/safestore_ram.c
deleted file mode 100644
index 25cee4f1ac..0000000000
--- a/usr/src/uts/common/avs/ns/sdbc/safestore_ram.c
+++ /dev/null
@@ -1,614 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * RAM Safe Store Module
- */
-
-#include <sys/types.h>
-#include <sys/ksynch.h>
-#include <sys/kmem.h>
-#include <sys/cmn_err.h>
-#include <sys/errno.h>
-
-#include <sys/nsc_thread.h>
-#include "sd_cache.h"
-#include "sd_trace.h"
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_k.h>
-#include <sys/unistat/spcs_errors.h>
-
-#include "safestore.h"
-#include "safestore_impl.h"
-#include "safestore_ram.h"
-
-extern void _sd_print(int level, char *fmt, ...);
-
-static int ss_ram_configure(ss_common_config_t *, spcs_s_info_t);
-static int ss_ram_deconfigure(int);
-static int ss_ram_getvdir(const ss_vdirkey_t *, ss_vdir_t *);
-static int ss_ram_getvdirent(const ss_vdir_t *, ss_voldata_t *);
-static int ss_ram_getvol(ss_voldata_t *);
-static int ss_ram_setvol(const ss_voldata_t *);
-static int ss_ram_getcdir(const ss_cdirkey_t *, ss_cdir_t *);
-static int ss_ram_getcdirent(ss_cdir_t *, ss_centry_info_t *);
-static int ss_ram_allocresource(int, int *, ss_resourcelist_t **);
-static void ss_ram_deallocresource(ss_resource_t *);
-static int ss_ram_getresource(ss_resourcelist_t **, ss_resource_t **);
-static int ss_ram_getcentry(ss_centry_info_t *);
-static int ss_ram_setcentry(const ss_centry_info_t *);
-static int ss_ram_cblock_read(const ss_resource_t *, void *, int, int);
-static int ss_ram_cblock_write(const ss_resource_t *, const void *, int, int);
-static int ss_ram_ctl(uint_t, uintptr_t);
-
-
-safestore_ops_t ss_ram_ops = {
- "safestore_ram",
- SS_M_RAM | SS_T_NONE,
- 0,
- ss_ram_configure,
- ss_ram_deconfigure,
- ss_ram_getvdir,
- ss_ram_getvdirent,
- ss_ram_getvol,
- ss_ram_setvol,
- ss_ram_getcdir,
- ss_ram_getcdirent,
- ss_ram_allocresource,
- ss_ram_deallocresource,
- ss_ram_getresource,
- ss_ram_getcentry,
- ss_ram_setcentry,
- ss_ram_cblock_read,
- ss_ram_cblock_write,
- ss_ram_ctl
-};
-
-static void ss_ram_vol_deconfigure();
-static int ss_ram_vol_configure(int);
-static int ss_ram_wctl_configure();
-static void ss_ram_wctl_deconfigure(void);
-static int ss_ram_deconfigure_locked();
-
-static kmutex_t ss_ram_config_lock;
-
-static ss_common_config_t ss_ramcommon_config;
-static ss_ram_config_t ss_ram_config;
-
-static char default_cblock [8192];
-
-
-#define MEGABYTE (1024*1024)
-
-void
-ss_ram_init()
-{
- mutex_init(&ss_ram_config_lock, NULL, MUTEX_DRIVER, NULL);
- bzero(&ss_ram_config, sizeof (ss_ram_config_t));
- bzero(&ss_ramcommon_config, sizeof (ss_common_config_t));
- sst_register_mod(&ss_ram_ops);
-
- ss_ram_config.ss_configured = SS_INITTED;
-}
-
-void
-ss_ram_deinit()
-{
- mutex_destroy(&ss_ram_config_lock);
- sst_unregister_mod(&ss_ram_ops);
-}
-
-
-/* ARGSUSED */
-static int
-ss_ram_configure(ss_common_config_t *clientptr, spcs_s_info_t kstatus)
-{
-
- if (clientptr->ssc_wsize == 0) /* choose a default? */
- return (EINVAL);
-
- mutex_enter(&ss_ram_config_lock);
-
- /* read in the parameters */
- bcopy(clientptr, &ss_ramcommon_config, sizeof (ss_common_config_t));
-
- /* set the page size */
- ss_ramcommon_config.ssc_ss_psize = BLK_SIZE(1);
-
- /* initialize client page size if not set */
- if (ss_ramcommon_config.ssc_client_psize == 0)
- ss_ramcommon_config.ssc_client_psize =
- ss_ramcommon_config.ssc_ss_psize;
-
- /* setup volume directory */
- if (ss_ram_vol_configure(clientptr->ssc_maxfiles)) {
- (void) ss_ram_deconfigure_locked();
- mutex_exit(&ss_ram_config_lock);
- return (SDBC_ENONETMEM);
- }
-
- /* setup write q */
- if (ss_ram_wctl_configure()) {
- (void) ss_ram_deconfigure_locked();
- mutex_exit(&ss_ram_config_lock);
- return (SDBC_ENONETMEM);
- }
-
- if (ss_ramcommon_config.ssc_flag & SS_GENPATTERN) {
- (void) _sd_fill_pattern(default_cblock,
- ss_ramcommon_config.ssc_pattern,
- sizeof (default_cblock));
- }
-
- ss_ram_config.ss_configured = SS_CONFIGURED;
- /* update client */
- bcopy(&ss_ramcommon_config, clientptr, sizeof (ss_common_config_t));
-
- mutex_exit(&ss_ram_config_lock);
- return (SS_OK);
-}
-
-/* acquires the ss_ram_config_lock and calls ss_ram_deconfigure_locked() */
-/* ARGSUSED */
-static int
-ss_ram_deconfigure(int dirty)
-{
- int rc;
-
- if (ss_ram_config.ss_configured != SS_CONFIGURED)
- return (SS_ERR);
-
- mutex_enter(&ss_ram_config_lock);
- rc = ss_ram_deconfigure_locked();
- mutex_exit(&ss_ram_config_lock);
-
- return (rc);
-}
-
-/*
- * internal use only
- * caller should acquire config lock before calling this function
- */
-static int
-ss_ram_deconfigure_locked()
-{
- ss_ram_wctl_deconfigure();
- ss_ram_vol_deconfigure();
-
- ss_ram_config.ss_configured = 0;
- return (SS_OK);
-}
-
-static int
-ss_ram_getvdir(const ss_vdirkey_t *key, ss_vdir_t *vdir)
-{
- ss_ram_vdir_t *ram_vdir = (ss_ram_vdir_t *)vdir;
- int rc = SS_OK;
-
- if ((key == NULL) || (vdir == NULL))
- return (SS_ERR);
-
- switch (key->vk_type) {
- case VDIR_ALL:
- ram_vdir->rv_type = VDIR_ALL;
- ram_vdir->rv_u.rv_all.rv_current =
- ss_ram_config.sn_volumes;
- ram_vdir->rv_u.rv_all.rv_end =
- ss_ram_config.sn_volumes +
- ss_ramcommon_config.ssc_maxfiles;
- break;
- case VDIR_VOL:
- case VDIR_NODE:
- default:
- rc = SS_ERR;
- break;
- }
-
- return (rc);
-}
-
-
-static int
-ss_ram_getvdirent(const ss_vdir_t *vdir, ss_voldata_t *vol)
-{
- int rc = SS_OK;
-
- ss_ram_vdir_t *ram_vdir = (ss_ram_vdir_t *)vdir;
-
- if (vol == NULL)
- return (SS_ERR);
-
- if (vdir == NULL)
- return (SS_ERR);
-
- switch (ram_vdir->rv_type) {
- case VDIR_ALL:
- if (ram_vdir->rv_u.rv_all.rv_current ==
- ram_vdir->rv_u.rv_all.rv_end) {
- rc = SS_EOF;
- } else {
- /* stuff client copy with token */
- vol->sv_vol = (ss_vol_t *)
- ram_vdir->rv_u.rv_all.rv_current++;
-
- /* get the volume data */
- rc = ss_ram_getvol(vol);
- }
- break;
- case VDIR_VOL:
- case VDIR_NODE:
- default:
- rc = SS_ERR;
- break;
- }
-
- return (rc);
-}
-
-static int
-ss_ram_getvol(ss_voldata_t *voldata)
-{
- ss_voldata_impl_t *ramvoldata;
-
- if (voldata == NULL)
- return (SS_ERR);
-
- /* get the pointer to the volume entry */
- ramvoldata = (ss_voldata_impl_t *)voldata->sv_vol;
-
- if (ramvoldata == NULL)
- return (SS_ERR);
-
- /* stuff the client structure from the ram entry */
- voldata->sv_cd = ramvoldata->svi_cd;
- voldata->sv_pinned = ramvoldata->svi_pinned;
- voldata->sv_attached = ramvoldata->svi_attached;
- voldata->sv_devidsz = ramvoldata->svi_devidsz;
-
- bcopy(ramvoldata->svi_volname, voldata->sv_volname,
- sizeof (voldata->sv_volname));
-
- bcopy(ramvoldata->svi_devid, voldata->sv_devid,
- sizeof (voldata->sv_devid));
- return (SS_OK);
-}
-
-static int
-ss_ram_setvol(const ss_voldata_t *voldata)
-{
- ss_voldata_impl_t *ramvoldata;
-
- if (voldata == NULL)
- return (SS_ERR);
-
- /* get the pointer to the volume entry */
- ramvoldata = (ss_voldata_impl_t *)voldata->sv_vol;
-
- if (ramvoldata == NULL)
- return (SS_ERR);
-
- /* load the volume entry from the client structure */
- ramvoldata->svi_cd = voldata->sv_cd;
- ramvoldata->svi_pinned = voldata->sv_pinned;
- ramvoldata->svi_attached = voldata->sv_attached;
- ramvoldata->svi_devidsz = voldata->sv_devidsz;
- bcopy(voldata->sv_volname, ramvoldata->svi_volname,
- sizeof (ramvoldata->svi_volname));
-
- bcopy(voldata->sv_devid, ramvoldata->svi_devid,
- sizeof (ramvoldata->svi_devid));
- return (SS_OK);
-}
-
-static int
-ss_ram_getcdir(const ss_cdirkey_t *key, ss_cdir_t *cdir)
-{
- ss_ram_cdir_t *ram_cdir = (ss_ram_cdir_t *)cdir;
- int rc = 0;
-
- if ((key == NULL) || (cdir == NULL))
- return (SS_ERR);
-
- switch (key->ck_type) {
- case CDIR_ALL:
- { int blocks;
-
- blocks = ss_ramcommon_config.ssc_wsize /
- ss_ramcommon_config.ssc_client_psize;
-
- ram_cdir->rc_type = CDIR_ALL;
- ram_cdir->rc_u.rc_all.rc_current =
- ss_ram_config.sn_wr_cctl;
- ram_cdir->rc_u.rc_all.rc_end =
- ss_ram_config.sn_wr_cctl + blocks;
- }
- break;
- case CDIR_VOL:
- case CDIR_NODE:
- default:
- rc = SS_ERR;
- break;
- }
-
- return (rc);
-}
-
-static int
-ss_ram_getcdirent(ss_cdir_t *cdir, ss_centry_info_t *centry)
-{
- int rc = SS_OK;
-
- ss_ram_cdir_t *ram_cdir = (ss_ram_cdir_t *)cdir;
-
- if (centry == NULL)
- return (SS_ERR);
-
- if (cdir == NULL)
- return (SS_ERR);
-
- switch (ram_cdir->rc_type) {
- case CDIR_ALL:
- if (ram_cdir->rc_u.rc_all.rc_current ==
- ram_cdir->rc_u.rc_all.rc_end) {
- rc = SS_EOF;
- } else {
- /* stuff client copy with token */
- centry->sc_res = (ss_resource_t *)
- ram_cdir->rc_u.rc_all.rc_current++;
-
- /* get the centry data */
- rc = ss_ram_getcentry(centry);
- }
- break;
- case CDIR_VOL:
- case CDIR_NODE:
- default:
- rc = SS_ERR;
- break;
- }
-
- return (rc);
-}
-
-static int
-ss_ram_allocresource(int need, int *stall, ss_resourcelist_t **reslist)
-{
- if (reslist == NULL)
- return (SS_ERR);
-
- *reslist = ((ss_resourcelist_t *)ss_alloc_write(need, stall,
- &(ss_ram_config.sn_wr_queue)));
- if (*reslist == NULL) /* do sync write */
- return (SS_ERR);
-
- return (SS_OK);
-}
-
-static void
-ss_ram_deallocresource(ss_resource_t *res)
-{
- ss_release_write((ss_wr_cctl_t *)res, &(ss_ram_config.sn_wr_queue));
-}
-
-static int
-ss_ram_getresource(ss_resourcelist_t **reslist, ss_resource_t **res)
-{
- if ((res == NULL) || (reslist == NULL)) {
- return (SS_ERR);
- }
-
- if (*reslist == NULL)
- return (SS_EOF);
-
- *res = (ss_resource_t *)(*reslist);
- *reslist = (ss_resourcelist_t *)
- ((ss_wr_cctl_t *)(*reslist))->wc_next;
-
- return (SS_OK);
-}
-
-static int
-ss_ram_getcentry(ss_centry_info_t *centry)
-{
- ss_wr_cctl_t *wctl;
- ss_centry_info_impl_t *ramcentry = (ss_centry_info_impl_t *)centry;
-
- if (centry == NULL)
- return (SS_ERR);
- else
- wctl = (ss_wr_cctl_t *)centry->sc_res;
-
- if (wctl == NULL)
- return (SS_ERR);
-
- if (wctl->wc_gl_info)
- bcopy(wctl->wc_gl_info, ramcentry,
- sizeof (ss_centry_info_impl_t));
- else
- return (SS_ERR);
-
- return (SS_OK);
-}
-
-static int
-ss_ram_setcentry(const ss_centry_info_t *centry)
-{
- ss_wr_cctl_t *wctl;
- ss_centry_info_impl_t *ramcentry = (ss_centry_info_impl_t *)centry;
-
- if (centry == NULL)
- return (SS_ERR);
- else
- wctl = (ss_wr_cctl_t *)centry->sc_res;
-
- if (wctl == NULL)
- return (SS_ERR);
-
- if (wctl->wc_gl_info)
- bcopy(ramcentry, wctl->wc_gl_info,
- sizeof (ss_centry_info_impl_t));
- else
- return (SS_ERR);
-
- return (SS_OK);
-}
-
-
-static int
-ss_ram_cblock_read(const ss_resource_t *res, void *buf,
- int count, int srcoffset)
-{
- if ((res == NULL) || (buf == NULL))
- return (SS_ERR);
-
- if ((srcoffset < 0) ||
- (srcoffset > ss_ramcommon_config.ssc_client_psize))
- return (SS_ERR);
-
- bcopy(default_cblock + srcoffset, buf, count);
-
- return (SS_OK);
-}
-
-static int
-ss_ram_cblock_write(const ss_resource_t *res,
- const void *buf, int count, int destoffset)
-{
- if ((res == NULL) || (buf == NULL))
- return (SS_ERR);
-
- if ((destoffset < 0) ||
- (destoffset > ss_ramcommon_config.ssc_client_psize))
- return (SS_ERR);
-
- bcopy(buf, default_cblock + destoffset, count);
-
- return (SS_OK);
-}
-
-static int
-ss_ram_ctl(uint_t cmd, uintptr_t arg)
-{
- int rc = SS_OK;
-
- switch (cmd) {
- case SSIOC_STATS:
- ((ssioc_stats_t *)arg)->wq_inq =
- ss_ram_config.sn_wr_queue.wq_inq;
- break;
- default:
- cmn_err(CE_WARN, "ss_nvs_ctl: cmd %x not supported",
- cmd);
- rc = ENOTTY;
- break;
- }
-
- return (rc);
-}
-
-static int
-ss_ram_vol_configure(int maxvols)
-{
- if ((ss_ram_config.sn_volumes = kmem_zalloc(maxvols *
- sizeof (ss_voldata_impl_t), KM_NOSLEEP)) == NULL)
- return (-1);
-
- return (0);
-}
-
-static void
-ss_ram_vol_deconfigure()
-{
- int maxvols = ss_ramcommon_config.ssc_maxfiles;
-
- if (ss_ram_config.sn_volumes)
- kmem_free(ss_ram_config.sn_volumes,
- maxvols * sizeof (ss_voldata_impl_t));
-}
-
-static int
-ss_ram_wctl_configure()
-{
- int blocks;
- ss_wr_cctl_t *wentry;
- static ss_centry_info_impl_t *gl;
- int i;
-
- blocks = ss_ramcommon_config.ssc_wsize /
- ss_ramcommon_config.ssc_client_psize;
-
- if ((ss_ram_config.sn_wr_cctl = (ss_wr_cctl_t *)
- kmem_zalloc(blocks * sizeof (ss_wr_cctl_t), KM_NOSLEEP))
- == NULL) {
- return (-1);
- }
-
- if ((ss_ram_config.sn_gl_centry_info = (ss_centry_info_impl_t *)
- kmem_zalloc(blocks * sizeof (ss_centry_info_impl_t),
- KM_NOSLEEP)) == NULL) {
- return (-1);
- }
-
- /*
- * Mini-DSP: no write/ft area
- * (ie forced_wrthru clear)
- */
-
- if (_sdbc_writeq_configure(&(ss_ram_config.sn_wr_queue)) != 0)
- return (-1);
-
- gl = ss_ram_config.sn_gl_centry_info;
-
- wentry = ss_ram_config.sn_wr_cctl;
- for (i = 0; i < blocks; ++i, ++wentry) {
- wentry->wc_gl_info = gl++;
- ss_release_write(wentry, &(ss_ram_config.sn_wr_queue));
- }
-
- ss_ram_config.sn_wr_queue.wq_nentries = blocks;
-
- return (0);
-}
-
-static void
-ss_ram_wctl_deconfigure()
-{
- int blocks;
-
- _sdbc_writeq_deconfigure(&(ss_ram_config.sn_wr_queue));
-
- blocks = ss_ramcommon_config.ssc_wsize /
- ss_ramcommon_config.ssc_client_psize;
-
- if (ss_ram_config.sn_wr_cctl) {
- kmem_free(ss_ram_config.sn_wr_cctl,
- blocks * sizeof (ss_wr_cctl_t));
- }
-
- if (ss_ram_config.sn_gl_centry_info) {
- kmem_free(ss_ram_config.sn_gl_centry_info,
- blocks * sizeof (ss_centry_info_impl_t));
- }
-}
diff --git a/usr/src/uts/common/avs/ns/sdbc/safestore_ram.h b/usr/src/uts/common/avs/ns/sdbc/safestore_ram.h
deleted file mode 100644
index 4367a92ec0..0000000000
--- a/usr/src/uts/common/avs/ns/sdbc/safestore_ram.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SD_SAFESTORE_RAM_H
-#define _SD_SAFESTORE_RAM_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef _KERNEL
-
-typedef struct ss_ram_config_s {
- uint_t ss_configured; /* configured bit */
- ss_voldata_impl_t *sn_volumes; /* volume directory */
- struct ss_wr_cctl *sn_wr_cctl; /* the write control blocks */
- ss_centry_info_impl_t *sn_gl_centry_info; /* dirty bits */
- struct _sd_wr_queue sn_wr_queue; /* the write queue */
-} ss_ram_config_t;
-
-/* internal volume directory stream struct must be same size as ss_vdir_t */
-typedef struct ss_ram_vdir_s {
- intptr_t rv_type; /* stream type */
- union {
- struct {
- ss_voldata_impl_t *rv_current;
- ss_voldata_impl_t *rv_end;
- } rv_all;
-
- struct {
- intptr_t v[5];
- } rv_vol;
-
- struct {
- intptr_t n[5];
- } rv_node;
- } rv_u;
-} ss_ram_vdir_t;
-
-/* internal centry stream struct must be same size as ss_cdir_t */
-typedef struct ss_ram_cdir_t_s {
- intptr_t rc_type; /* stream type */
- union {
- struct {
- ss_wr_cctl_t *rc_current;
- ss_wr_cctl_t *rc_end;
- } rc_all;
-
- struct {
- intptr_t v[5];
- } rc_vol;
-
- struct {
- intptr_t n[5];
- } rc_node;
- } rc_u;
-}ss_ram_cdir_t;
-
-typedef ss_wr_cctl_t *ss_ram_resource_t;
-typedef ss_wr_cctl_t *ss_ram_resourcelist_t;
-
-#endif /* _KERNEL */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SD_SAFESTORE_RAM_H */
diff --git a/usr/src/uts/common/avs/ns/sdbc/sd_bcache.c b/usr/src/uts/common/avs/ns/sdbc/sd_bcache.c
deleted file mode 100644
index c3d32ae08a..0000000000
--- a/usr/src/uts/common/avs/ns/sdbc/sd_bcache.c
+++ /dev/null
@@ -1,7484 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/ksynch.h>
-#include <sys/cmn_err.h>
-#include <sys/errno.h>
-#include <sys/kmem.h>
-#include <sys/cred.h>
-#include <sys/buf.h>
-#include <sys/ddi.h>
-
-#include <sys/nsc_thread.h>
-#include <sys/nsctl/nsctl.h>
-
-#include <sys/sdt.h> /* dtrace is S10 or later */
-
-#include "sd_bcache.h"
-#include "sd_trace.h"
-#include "sd_io.h"
-#include "sd_bio.h"
-#include "sd_ft.h"
-#include "sd_misc.h"
-#include "sd_pcu.h"
-
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_k.h>
-#include <sys/unistat/spcs_errors.h>
-#include <sys/nsctl/safestore.h>
-#ifndef DS_DDICT
-#include <sys/ddi_impldefs.h>
-#endif
-
-
-/*
- * kstat interface
- */
-
-static kstat_t *sdbc_global_stats_kstat;
-static int sdbc_global_stats_update(kstat_t *ksp, int rw);
-
-typedef struct {
- kstat_named_t ci_sdbc_count;
- kstat_named_t ci_sdbc_loc_count;
- kstat_named_t ci_sdbc_rdhits;
- kstat_named_t ci_sdbc_rdmiss;
- kstat_named_t ci_sdbc_wrhits;
- kstat_named_t ci_sdbc_wrmiss;
- kstat_named_t ci_sdbc_blksize;
- kstat_named_t ci_sdbc_lru_blocks;
-#ifdef DEBUG
- kstat_named_t ci_sdbc_lru_noreq;
- kstat_named_t ci_sdbc_lru_req;
-#endif
- kstat_named_t ci_sdbc_wlru_inq;
- kstat_named_t ci_sdbc_cachesize;
- kstat_named_t ci_sdbc_numblocks;
- kstat_named_t ci_sdbc_num_shared;
- kstat_named_t ci_sdbc_wrcancelns;
- kstat_named_t ci_sdbc_destaged;
- kstat_named_t ci_sdbc_nodehints;
-} sdbc_global_stats_t;
-
-static sdbc_global_stats_t sdbc_global_stats = {
- {SDBC_GKSTAT_COUNT, KSTAT_DATA_ULONG},
- {SDBC_GKSTAT_LOC_COUNT, KSTAT_DATA_ULONG},
- {SDBC_GKSTAT_RDHITS, KSTAT_DATA_ULONG},
- {SDBC_GKSTAT_RDMISS, KSTAT_DATA_ULONG},
- {SDBC_GKSTAT_WRHITS, KSTAT_DATA_ULONG},
- {SDBC_GKSTAT_WRMISS, KSTAT_DATA_ULONG},
- {SDBC_GKSTAT_BLKSIZE, KSTAT_DATA_ULONG},
- {SDBC_GKSTAT_LRU_BLOCKS, KSTAT_DATA_ULONG},
-#ifdef DEBUG
- {SDBC_GKSTAT_LRU_NOREQ, KSTAT_DATA_ULONG},
- {SDBC_GKSTAT_LRU_REQ, KSTAT_DATA_ULONG},
-#endif
- {SDBC_GKSTAT_WLRU_INQ, KSTAT_DATA_ULONG},
- {SDBC_GKSTAT_CACHESIZE, KSTAT_DATA_ULONG},
- {SDBC_GKSTAT_NUMBLOCKS, KSTAT_DATA_ULONG},
- {SDBC_GKSTAT_NUM_SHARED, KSTAT_DATA_ULONG},
- {SDBC_GKSTAT_WRCANCELNS, KSTAT_DATA_ULONG},
- {SDBC_GKSTAT_DESTAGED, KSTAT_DATA_ULONG},
- {SDBC_GKSTAT_NODEHINTS, KSTAT_DATA_ULONG},
-};
-
-static kstat_t **sdbc_cd_kstats;
-static kstat_t **sdbc_cd_io_kstats;
-static kmutex_t *sdbc_cd_io_kstats_mutexes;
-static kstat_t *sdbc_global_io_kstat;
-static kmutex_t sdbc_global_io_kstat_mutex;
-static int sdbc_cd_stats_update(kstat_t *ksp, int rw);
-static int cd_kstat_add(int cd);
-static int cd_kstat_remove(int cd);
-
-typedef struct {
- kstat_named_t ci_sdbc_vol_name;
- kstat_named_t ci_sdbc_failed;
- kstat_named_t ci_sdbc_cd;
- kstat_named_t ci_sdbc_cache_read;
- kstat_named_t ci_sdbc_cache_write;
- kstat_named_t ci_sdbc_disk_read;
- kstat_named_t ci_sdbc_disk_write;
- kstat_named_t ci_sdbc_filesize;
- kstat_named_t ci_sdbc_numdirty;
- kstat_named_t ci_sdbc_numio;
- kstat_named_t ci_sdbc_numfail;
- kstat_named_t ci_sdbc_destaged;
- kstat_named_t ci_sdbc_wrcancelns;
- kstat_named_t ci_sdbc_cdhints;
-} sdbc_cd_stats_t;
-
-static sdbc_cd_stats_t sdbc_cd_stats = {
- {SDBC_CDKSTAT_VOL_NAME, KSTAT_DATA_CHAR},
- {SDBC_CDKSTAT_FAILED, KSTAT_DATA_ULONG},
- {SDBC_CDKSTAT_CD, KSTAT_DATA_ULONG},
- {SDBC_CDKSTAT_CACHE_READ, KSTAT_DATA_ULONG},
- {SDBC_CDKSTAT_CACHE_WRITE, KSTAT_DATA_ULONG},
- {SDBC_CDKSTAT_DISK_READ, KSTAT_DATA_ULONG},
- {SDBC_CDKSTAT_DISK_WRITE, KSTAT_DATA_ULONG},
-#ifdef NSC_MULTI_TERABYTE
- {SDBC_CDKSTAT_FILESIZE, KSTAT_DATA_UINT64},
-#else
- {SDBC_CDKSTAT_FILESIZE, KSTAT_DATA_ULONG},
-#endif
- {SDBC_CDKSTAT_NUMDIRTY, KSTAT_DATA_ULONG},
- {SDBC_CDKSTAT_NUMIO, KSTAT_DATA_ULONG},
- {SDBC_CDKSTAT_NUMFAIL, KSTAT_DATA_ULONG},
- {SDBC_CDKSTAT_DESTAGED, KSTAT_DATA_ULONG},
- {SDBC_CDKSTAT_WRCANCELNS, KSTAT_DATA_ULONG},
- {SDBC_CDKSTAT_CDHINTS, KSTAT_DATA_ULONG},
-};
-
-#ifdef DEBUG
-/*
- * dynmem kstat interface
- */
-static kstat_t *sdbc_dynmem_kstat_dm;
-static int simplect_dm;
-static int sdbc_dynmem_kstat_update_dm(kstat_t *ksp, int rw);
-
-typedef struct {
- kstat_named_t ci_sdbc_monitor_dynmem;
- kstat_named_t ci_sdbc_max_dyn_list;
- kstat_named_t ci_sdbc_cache_aging_ct1;
- kstat_named_t ci_sdbc_cache_aging_ct2;
- kstat_named_t ci_sdbc_cache_aging_ct3;
- kstat_named_t ci_sdbc_cache_aging_sec1;
- kstat_named_t ci_sdbc_cache_aging_sec2;
- kstat_named_t ci_sdbc_cache_aging_sec3;
- kstat_named_t ci_sdbc_cache_aging_pcnt1;
- kstat_named_t ci_sdbc_cache_aging_pcnt2;
- kstat_named_t ci_sdbc_max_holds_pcnt;
-
- kstat_named_t ci_sdbc_alloc_ct;
- kstat_named_t ci_sdbc_dealloc_ct;
- kstat_named_t ci_sdbc_history;
- kstat_named_t ci_sdbc_nodatas;
- kstat_named_t ci_sdbc_candidates;
- kstat_named_t ci_sdbc_deallocs;
- kstat_named_t ci_sdbc_hosts;
- kstat_named_t ci_sdbc_pests;
- kstat_named_t ci_sdbc_metas;
- kstat_named_t ci_sdbc_holds;
- kstat_named_t ci_sdbc_others;
- kstat_named_t ci_sdbc_notavail;
-
- kstat_named_t ci_sdbc_process_directive;
-
- kstat_named_t ci_sdbc_simplect;
-} sdbc_dynmem_dm_t;
-
-static sdbc_dynmem_dm_t sdbc_dynmem_dm = {
- {SDBC_DMKSTAT_MONITOR_DYNMEM, KSTAT_DATA_ULONG},
- {SDBC_DMKSTAT_MAX_DYN_LIST, KSTAT_DATA_ULONG},
- {SDBC_DMKSTAT_CACHE_AGING_CT1, KSTAT_DATA_ULONG},
- {SDBC_DMKSTAT_CACHE_AGING_CT2, KSTAT_DATA_ULONG},
- {SDBC_DMKSTAT_CACHE_AGING_CT3, KSTAT_DATA_ULONG},
- {SDBC_DMKSTAT_CACHE_AGING_SEC1, KSTAT_DATA_ULONG},
- {SDBC_DMKSTAT_CACHE_AGING_SEC2, KSTAT_DATA_ULONG},
- {SDBC_DMKSTAT_CACHE_AGING_SEC3, KSTAT_DATA_ULONG},
- {SDBC_DMKSTAT_CACHE_AGING_PCNT1, KSTAT_DATA_ULONG},
- {SDBC_DMKSTAT_CACHE_AGING_PCNT2, KSTAT_DATA_ULONG},
- {SDBC_DMKSTAT_MAX_HOLDS_PCNT, KSTAT_DATA_ULONG},
- {SDBC_DMKSTAT_ALLOC_CNT, KSTAT_DATA_ULONG},
- {SDBC_DMKSTAT_DEALLOC_CNT, KSTAT_DATA_ULONG},
- {SDBC_DMKSTAT_HISTORY, KSTAT_DATA_ULONG},
- {SDBC_DMKSTAT_NODATAS, KSTAT_DATA_ULONG},
- {SDBC_DMKSTAT_CANDIDATES, KSTAT_DATA_ULONG},
- {SDBC_DMKSTAT_DEALLOCS, KSTAT_DATA_ULONG},
- {SDBC_DMKSTAT_HOSTS, KSTAT_DATA_ULONG},
- {SDBC_DMKSTAT_PESTS, KSTAT_DATA_ULONG},
- {SDBC_DMKSTAT_METAS, KSTAT_DATA_ULONG},
- {SDBC_DMKSTAT_HOLDS, KSTAT_DATA_ULONG},
- {SDBC_DMKSTAT_OTHERS, KSTAT_DATA_ULONG},
- {SDBC_DMKSTAT_NOTAVAIL, KSTAT_DATA_ULONG},
- {SDBC_DMKSTAT_PROCESS_DIRECTIVE, KSTAT_DATA_ULONG},
- {SDBC_DMKSTAT_SIMPLECT, KSTAT_DATA_ULONG}
-};
-#endif
-
-/* End of dynmem kstats */
-
-#ifdef DEBUG
-int *dmchainpull_table; /* dmchain wastage stats */
-#endif
-
-/*
- * dynmem process vars
- */
-extern _dm_process_vars_t dynmem_processing_dm;
-
-/* metadata for volumes */
-ss_voldata_t *_sdbc_gl_file_info;
-
-size_t _sdbc_gl_file_info_size;
-
-/* metadata for cache write blocks */
-static ss_centry_info_t *_sdbc_gl_centry_info;
-
-/* wblocks * sizeof(ss_centry_info_t) */
-static size_t _sdbc_gl_centry_info_size;
-
-static int _SD_DELAY_QUEUE = 1;
-static int sdbc_allocb_inuse, sdbc_allocb_lost, sdbc_allocb_hit;
-static int sdbc_allocb_pageio1, sdbc_allocb_pageio2;
-static int sdbc_centry_hit, sdbc_centry_inuse, sdbc_centry_lost;
-static int sdbc_dmchain_not_avail;
-static int sdbc_allocb_deallocd;
-static int sdbc_centry_deallocd;
-static int sdbc_check_cot;
-static int sdbc_ra_hash; /* 1-block read-ahead fails due to hash hit */
-static int sdbc_ra_none; /* 1-block read-ahead fails due to "would block" */
-
-
-/*
- * Set the following variable to 1 to enable pagelist io mutual
- * exclusion on all _sd_alloc_buf() operations.
- *
- * This is set to ON to prevent front end / back end races between new
- * NSC_WRTHRU io operations coming in through _sd_alloc_buf(), and
- * previously written data being flushed out to disk by the sdbc
- * flusher at the back end.
- * -- see bugtraq 4287564
- * -- Simon Crosland, Mon Nov 8 16:34:09 GMT 1999
- */
-static int sdbc_pageio_always = 1;
-
-int sdbc_use_dmchain = 0; /* start time switch for dm chaining */
-int sdbc_prefetch1 = 1; /* do 1-block read-ahead */
-/*
- * if sdbc_static_cache is 1 allocate all cache memory at startup.
- * deallocate only at shutdown.
- */
-int sdbc_static_cache = 1;
-
-#ifdef DEBUG
-/*
- * Pagelist io mutual exclusion debug facility.
- */
-#define SDBC_PAGEIO_OFF 0 /* no debug */
-#define SDBC_PAGEIO_RDEV 1 /* force NSC_PAGEIO for specified dev */
-#define SDBC_PAGEIO_RAND 2 /* randomly force NSC_PAGEIO */
-#define SDBC_PAGEIO_ALL 3 /* always force NSC_PAGEIO */
-static int sdbc_pageio_debug = SDBC_PAGEIO_OFF;
-static dev_t sdbc_pageio_rdev = (dev_t)-1;
-#endif
-
-/*
- * INF SD cache global data
- */
-
-_sd_cd_info_t *_sd_cache_files;
-_sd_stats_t *_sd_cache_stats;
-kmutex_t _sd_cache_lock;
-
-_sd_hash_table_t *_sd_htable;
-_sd_queue_t _sd_lru_q;
-
-_sd_cctl_t *_sd_cctl[_SD_CCTL_GROUPS];
-int _sd_cctl_groupsz;
-
-_sd_net_t _sd_net_config;
-
-extern krwlock_t sdbc_queue_lock;
-
-unsigned int _sd_node_hint;
-
-#define _SD_LRU_Q (&_sd_lru_q)
-int BLK_FBAS; /* number of FBA's in a cache block */
-int CACHE_BLOCK_SIZE; /* size in bytes of a cache block */
-int CBLOCKS;
-_sd_bitmap_t BLK_FBA_BITS;
-static int sdbc_prefetch_valid_cnt;
-static int sdbc_prefetch_busy_cnt;
-static int sdbc_prefetch_trailing;
-static int sdbc_prefetch_deallocd;
-static int sdbc_prefetch_pageio1;
-static int sdbc_prefetch_pageio2;
-static int sdbc_prefetch_hit;
-static int sdbc_prefetch_lost;
-static int _sd_prefetch_opt = 1; /* 0 to disable & use _prefetch_sb_vec[] */
-static nsc_vec_t _prefetch_sb_vec[_SD_MAX_BLKS + 1];
-
-_sd_bitmap_t _fba_bits[] = {
- 0x0000, 0x0001, 0x0003, 0x0007,
- 0x000f, 0x001f, 0x003f, 0x007f,
- 0x00ff,
-#if defined(_SD_8K_BLKSIZE)
- 0x01ff, 0x03ff, 0x07ff,
- 0x0fff, 0x1fff, 0x3fff, 0x7fff,
- 0xffff,
-#endif
-};
-
-
-static int _sd_ccsync_cnt = 256;
-static _sd_cctl_sync_t *_sd_ccent_sync;
-
-nsc_io_t *sdbc_io;
-
-#ifdef _MULTI_DATAMODEL
-_sd_stats32_t *_sd_cache_stats32 = NULL;
-#endif
-
-
-#ifdef DEBUG
-int cmn_level = CE_PANIC;
-#else
-int cmn_level = CE_WARN;
-#endif
-
-/*
- * Forward declare all statics that are used before defined to enforce
- * parameter checking
- * Some (if not all) of these could be removed if the code were reordered
- */
-
-static void _sdbc_stats_deconfigure(void);
-static int _sdbc_stats_configure(int cblocks);
-static int _sdbc_lruq_configure(_sd_queue_t *);
-static void _sdbc_lruq_deconfigure(void);
-static int _sdbc_mem_configure(int cblocks, spcs_s_info_t kstatus);
-static void _sdbc_mem_deconfigure(int cblocks);
-static void _sd_ins_queue(_sd_queue_t *, _sd_cctl_t *centry);
-static int _sd_flush_cd(int cd);
-static int _sd_check_buffer_alloc(int cd, nsc_off_t fba_pos, nsc_size_t fba_len,
- _sd_buf_handle_t **hp);
-static int _sd_doread(_sd_buf_handle_t *handle, _sd_cctl_t *cc_ent,
- nsc_off_t fba_pos, nsc_size_t fba_len, int flag);
-static void _sd_async_read_ea(blind_t xhandle, nsc_off_t fba_pos,
- nsc_size_t fba_len, int error);
-static void _sd_async_write_ea(blind_t xhandle, nsc_off_t fba_pos,
- nsc_size_t fba_len, int error);
-static void _sd_queue_write(_sd_buf_handle_t *handle, nsc_off_t fba_pos,
- nsc_size_t fba_len);
-static int _sd_remote_store(_sd_cctl_t *cc_ent, nsc_off_t fba_pos,
- nsc_size_t fba_len);
-static int _sd_copy_direct(_sd_buf_handle_t *handle1, _sd_buf_handle_t *handle2,
- nsc_off_t fba_pos1, nsc_off_t fba_pos2, nsc_size_t fba_len);
-static int _sd_sync_write(_sd_buf_handle_t *handle, nsc_off_t fba_pos,
- nsc_size_t fba_len, int flag);
-static int _sd_sync_write2(_sd_buf_handle_t *wr_handle, nsc_off_t wr_st_pos,
- nsc_size_t fba_len, int flag, _sd_buf_handle_t *rd_handle,
- nsc_off_t rd_st_pos);
-static int sdbc_fd_attach_cd(blind_t xcd);
-static int sdbc_fd_detach_cd(blind_t xcd);
-static int sdbc_fd_flush_cd(blind_t xcd);
-static int _sdbc_gl_centry_configure(spcs_s_info_t);
-static int _sdbc_gl_file_configure(spcs_s_info_t);
-static void _sdbc_gl_centry_deconfigure(void);
-static void _sdbc_gl_file_deconfigure(void);
-static int sdbc_doread_prefetch(_sd_cctl_t *cc_ent, nsc_off_t fba_pos,
- nsc_size_t fba_len);
-static _sd_bitmap_t update_dirty(_sd_cctl_t *cc_ent, sdbc_cblk_fba_t st_off,
- sdbc_cblk_fba_t st_len);
-static int _sd_prefetch_buf(int cd, nsc_off_t fba_pos, nsc_size_t fba_len,
- int flag, _sd_buf_handle_t *handle, int locked);
-
-/* dynmem support */
-static int _sd_setup_category_on_type(_sd_cctl_t *header);
-static int _sd_setup_mem_chaining(_sd_cctl_t *header, int flag);
-
-static int sdbc_check_cctl_cot(_sd_cctl_t *);
-
-static int sdbc_dmqueues_configure();
-static void sdbc_dmqueues_deconfigure();
-static _sd_cctl_t *sdbc_get_dmchain(int, int *, int);
-static int sdbc_dmchain_avail(_sd_cctl_t *);
-void sdbc_requeue_dmchain(_sd_queue_t *, _sd_cctl_t *, int, int);
-static void sdbc_ins_dmqueue_back(_sd_queue_t *, _sd_cctl_t *);
-void sdbc_ins_dmqueue_front(_sd_queue_t *, _sd_cctl_t *);
-void sdbc_remq_dmchain(_sd_queue_t *, _sd_cctl_t *);
-static void sdbc_clear_dmchain(_sd_cctl_t *, _sd_cctl_t *);
-void sdbc_requeue_head_dm_try(_sd_cctl_t *);
-static _sd_cctl_t *sdbc_alloc_dmc(int, nsc_off_t, nsc_size_t, int *,
- sdbc_allocbuf_t *, int);
-static _sd_cctl_t *sdbc_alloc_lru(int, nsc_off_t, int *, int);
-static _sd_cctl_t *sdbc_alloc_from_dmchain(int, nsc_off_t, sdbc_allocbuf_t *,
- int);
-static void sdbc_centry_init_dm(_sd_cctl_t *);
-static int sdbc_centry_memalloc_dm(_sd_cctl_t *, int, int);
-static void sdbc_centry_alloc_end(sdbc_allocbuf_t *);
-
-
-
-
-/* _SD_DEBUG */
-#if defined(_SD_DEBUG) || defined(DEBUG)
-static int _sd_cctl_valid(_sd_cctl_t *);
-#endif
-
-static
-nsc_def_t _sdbc_fd_def[] = {
- "Attach", (uintptr_t)sdbc_fd_attach_cd, 0,
- "Detach", (uintptr_t)sdbc_fd_detach_cd, 0,
- "Flush", (uintptr_t)sdbc_fd_flush_cd, 0,
- 0, 0, 0
-};
-
-
-/*
- * _sdbc_cache_configure - initialize cache blocks, queues etc.
- *
- * ARGUMENTS:
- * cblocks - Number of cache blocks
- *
- * RETURNS:
- * 0 on success.
- * SDBC_EENABLEFAIL or SDBC_EMEMCONFIG on failure.
- *
- */
-
-
-
-int
-_sdbc_cache_configure(int cblocks, spcs_s_info_t kstatus)
-{
- CBLOCKS = cblocks;
-
- _sd_cache_files = (_sd_cd_info_t *)
- kmem_zalloc(sdbc_max_devs * sizeof (_sd_cd_info_t),
- KM_SLEEP);
-
- if (_sdbc_stats_configure(cblocks))
- return (SDBC_EENABLEFAIL);
-
- if (sdbc_use_dmchain) {
- if (sdbc_dmqueues_configure())
- return (SDBC_EENABLEFAIL);
- } else {
- if (_sdbc_lruq_configure(_SD_LRU_Q))
- return (SDBC_EENABLEFAIL);
- }
-
-
- if (_sdbc_mem_configure(cblocks, kstatus))
- return (SDBC_EMEMCONFIG);
-
- CACHE_BLOCK_SIZE = BLK_SIZE(1);
- BLK_FBAS = FBA_NUM(CACHE_BLOCK_SIZE);
- BLK_FBA_BITS = _fba_bits[BLK_FBAS];
-
- sdbc_allocb_pageio1 = 0;
- sdbc_allocb_pageio2 = 0;
- sdbc_allocb_hit = 0;
- sdbc_allocb_inuse = 0;
- sdbc_allocb_lost = 0;
- sdbc_centry_inuse = 0;
- sdbc_centry_lost = 0;
- sdbc_centry_hit = 0;
- sdbc_centry_deallocd = 0;
- sdbc_dmchain_not_avail = 0;
- sdbc_allocb_deallocd = 0;
-
- sdbc_prefetch_valid_cnt = 0;
- sdbc_prefetch_busy_cnt = 0;
- sdbc_prefetch_trailing = 0;
- sdbc_prefetch_deallocd = 0;
- sdbc_prefetch_pageio1 = 0;
- sdbc_prefetch_pageio2 = 0;
- sdbc_prefetch_hit = 0;
- sdbc_prefetch_lost = 0;
-
- sdbc_check_cot = 0;
- sdbc_prefetch1 = 1;
- sdbc_ra_hash = 0;
- sdbc_ra_none = 0;
-
- return (0);
-}
-
-/*
- * _sdbc_cache_deconfigure - cache is being deconfigured. Release any
- * memory that we acquired during the configuration process and return
- * to the unconfigured state.
- *
- * NOTE: all users of the cache should be inactive at this point,
- * i.e. we are unregistered from sd and all cache daemons/threads are
- * gone.
- *
- */
-void
-_sdbc_cache_deconfigure(void)
-{
- /* CCIO shutdown must happen before memory is free'd */
-
- if (_sd_cache_files) {
- kmem_free(_sd_cache_files,
- sdbc_max_devs * sizeof (_sd_cd_info_t));
- _sd_cache_files = (_sd_cd_info_t *)NULL;
- }
-
-
- BLK_FBA_BITS = 0;
- BLK_FBAS = 0;
- CACHE_BLOCK_SIZE = 0;
- _sdbc_mem_deconfigure(CBLOCKS);
- _sdbc_gl_centry_deconfigure();
- _sdbc_gl_file_deconfigure();
-
- if (sdbc_use_dmchain)
- sdbc_dmqueues_deconfigure();
- else
- _sdbc_lruq_deconfigure();
- _sdbc_stats_deconfigure();
-
- CBLOCKS = 0;
-}
-
-
-/*
- * _sdbc_stats_deconfigure - cache is being deconfigured turn off
- * stats. This could seemingly do more but we leave most of the
- * data intact until cache is configured again.
- *
- */
-static void
-_sdbc_stats_deconfigure(void)
-{
- int i;
-
-#ifdef DEBUG
- if (sdbc_dynmem_kstat_dm) {
- kstat_delete(sdbc_dynmem_kstat_dm);
- sdbc_dynmem_kstat_dm = NULL;
- }
-#endif
-
- if (sdbc_global_stats_kstat) {
- kstat_delete(sdbc_global_stats_kstat);
- sdbc_global_stats_kstat = NULL;
- }
-
- if (sdbc_cd_kstats) {
- for (i = 0; i < sdbc_max_devs; i++) {
- if (sdbc_cd_kstats[i]) {
- kstat_delete(sdbc_cd_kstats[i]);
- sdbc_cd_kstats[i] = NULL;
- }
- }
- kmem_free(sdbc_cd_kstats, sizeof (kstat_t *) * sdbc_max_devs);
- sdbc_cd_kstats = NULL;
- }
-
- if (sdbc_global_io_kstat) {
- kstat_delete(sdbc_global_io_kstat);
- mutex_destroy(&sdbc_global_io_kstat_mutex);
- sdbc_global_io_kstat = NULL;
- }
-
- if (sdbc_cd_io_kstats) {
- for (i = 0; i < sdbc_max_devs; i++) {
- if (sdbc_cd_io_kstats[i]) {
- kstat_delete(sdbc_cd_io_kstats[i]);
- sdbc_cd_io_kstats[i] = NULL;
- }
- }
- kmem_free(sdbc_cd_io_kstats, sizeof (kstat_t *) *
- sdbc_max_devs);
- sdbc_cd_io_kstats = NULL;
- }
-
- if (sdbc_cd_io_kstats_mutexes) {
- /* mutexes are already destroyed in cd_kstat_remove() */
- kmem_free(sdbc_cd_io_kstats_mutexes,
- sizeof (kmutex_t) * sdbc_max_devs);
- sdbc_cd_io_kstats_mutexes = NULL;
- }
-
-
- if (_sd_cache_stats) {
- kmem_free(_sd_cache_stats,
- sizeof (_sd_stats_t) +
- (sdbc_max_devs - 1) * sizeof (_sd_shared_t));
- _sd_cache_stats = NULL;
- }
-#ifdef _MULTI_DATAMODEL
- if (_sd_cache_stats32) {
- kmem_free(_sd_cache_stats32, sizeof (_sd_stats32_t) +
- (sdbc_max_devs - 1) * sizeof (_sd_shared_t));
- _sd_cache_stats32 = NULL;
- }
-#endif
-}
-
-static int
-_sdbc_stats_configure(int cblocks)
-{
-
- _sd_cache_stats = kmem_zalloc(sizeof (_sd_stats_t) +
- (sdbc_max_devs - 1) * sizeof (_sd_shared_t), KM_SLEEP);
- _sd_cache_stats->st_blksize = (int)BLK_SIZE(1);
- _sd_cache_stats->st_cachesize = cblocks * BLK_SIZE(1);
- _sd_cache_stats->st_numblocks = cblocks;
- _sd_cache_stats->st_wrcancelns = 0;
- _sd_cache_stats->st_destaged = 0;
-#ifdef _MULTI_DATAMODEL
- _sd_cache_stats32 = kmem_zalloc(sizeof (_sd_stats32_t) +
- (sdbc_max_devs - 1) * sizeof (_sd_shared_t), KM_SLEEP);
-#endif
-
- /* kstat implementation - global stats */
- sdbc_global_stats_kstat = kstat_create(SDBC_KSTAT_MODULE, 0,
- SDBC_KSTAT_GSTATS, SDBC_KSTAT_CLASS, KSTAT_TYPE_NAMED,
- sizeof (sdbc_global_stats)/sizeof (kstat_named_t),
- KSTAT_FLAG_VIRTUAL|KSTAT_FLAG_WRITABLE);
-
- if (sdbc_global_stats_kstat != NULL) {
- sdbc_global_stats_kstat->ks_data = &sdbc_global_stats;
- sdbc_global_stats_kstat->ks_update = sdbc_global_stats_update;
- sdbc_global_stats_kstat->ks_private = _sd_cache_stats;
- kstat_install(sdbc_global_stats_kstat);
- } else {
- cmn_err(CE_WARN, "!sdbc: gstats kstat failed");
- }
-
- /* global I/O kstats */
- sdbc_global_io_kstat = kstat_create(SDBC_KSTAT_MODULE, 0,
- SDBC_IOKSTAT_GSTATS, "disk", KSTAT_TYPE_IO, 1, 0);
-
- if (sdbc_global_io_kstat) {
- mutex_init(&sdbc_global_io_kstat_mutex, NULL, MUTEX_DRIVER,
- NULL);
- sdbc_global_io_kstat->ks_lock =
- &sdbc_global_io_kstat_mutex;
- kstat_install(sdbc_global_io_kstat);
- }
-
- /*
- * kstat implementation - cd stats
- * NOTE: one kstat instance for each open cache descriptor
- */
- sdbc_cd_kstats = kmem_zalloc(sizeof (kstat_t *) * sdbc_max_devs,
- KM_SLEEP);
-
- /*
- * kstat implementation - i/o kstats per cache descriptor
- * NOTE: one I/O kstat instance for each cd
- */
- sdbc_cd_io_kstats = kmem_zalloc(sizeof (kstat_t *) * sdbc_max_devs,
- KM_SLEEP);
-
- sdbc_cd_io_kstats_mutexes = kmem_zalloc(sizeof (kmutex_t) *
- sdbc_max_devs, KM_SLEEP);
-
-#ifdef DEBUG
- /* kstat implementation - dynamic memory stats */
- sdbc_dynmem_kstat_dm = kstat_create(SDBC_KSTAT_MODULE, 0,
- SDBC_KSTAT_DYNMEM, SDBC_KSTAT_CLASS, KSTAT_TYPE_NAMED,
- sizeof (sdbc_dynmem_dm)/sizeof (kstat_named_t),
- KSTAT_FLAG_VIRTUAL|KSTAT_FLAG_WRITABLE);
-
- if (sdbc_dynmem_kstat_dm != NULL) {
- sdbc_dynmem_kstat_dm->ks_data = &sdbc_dynmem_dm;
- sdbc_dynmem_kstat_dm->ks_update = sdbc_dynmem_kstat_update_dm;
- sdbc_dynmem_kstat_dm->ks_private = &dynmem_processing_dm;
- kstat_install(sdbc_dynmem_kstat_dm);
- } else {
- cmn_err(CE_WARN, "!sdbc: dynmem kstat failed");
- }
-#endif
-
- return (0);
-}
-
-/*
- * sdbc_dmqueues_configure()
- * initialize the queues of dynamic memory chains.
- */
-
-_sd_queue_t *sdbc_dm_queues;
-static int max_dm_queues;
-
-
-static int
-sdbc_dmqueues_configure()
-{
- int i;
-
- /*
- * CAUTION! this code depends on max_dyn_list not changing
- * if it does change behavior may be incorrect, as cc_alloc_size_dm
- * depends on max_dyn_list and indexes to dmqueues are derived from
- * cc_alloc_size_dm.
- * see _sd_setup_category_on_type() and _sd_dealloc_dm()
- * TODO: prevent max_dyn_list from on-the-fly modification (easy) or
- * allow for on-the-fly changes to number of dm queues (hard).
- */
- max_dm_queues = dynmem_processing_dm.max_dyn_list;
-
- ++max_dm_queues; /* need a "0" queue for centrys with no memory */
-
- sdbc_dm_queues = (_sd_queue_t *)
- kmem_zalloc(max_dm_queues * sizeof (_sd_queue_t), KM_SLEEP);
-
-#ifdef DEBUG
- dmchainpull_table = (int *)kmem_zalloc(max_dm_queues *
- max_dm_queues * sizeof (int), KM_SLEEP);
-#endif
-
- for (i = 0; i < max_dm_queues; ++i) {
- (void) _sdbc_lruq_configure(&sdbc_dm_queues[i]);
- sdbc_dm_queues[i].sq_dmchain_cblocks = i;
- }
-
- return (0);
-}
-
-static void
-sdbc_dmqueues_deconfigure()
-{
- /* CAUTION! this code depends on max_dyn_list not changing */
-
- if (sdbc_dm_queues)
- kmem_free(sdbc_dm_queues, max_dm_queues * sizeof (_sd_queue_t));
- sdbc_dm_queues = NULL;
- max_dm_queues = 0;
-}
-
-#define GOOD_LRUSIZE(q) ((q->sq_inq >= 0) || (q->sq_inq <= CBLOCKS))
-
-/*
- * _sdbc_lruq_configure - initialize the lru queue
- *
- * ARGUMENTS: NONE
- * RETURNS: 0
- *
- */
-
-static int
-_sdbc_lruq_configure(_sd_queue_t *_sd_lru)
-{
-
- _sd_lru->sq_inq = 0;
-
- mutex_init(&_sd_lru->sq_qlock, NULL, MUTEX_DRIVER, NULL);
-
- _sd_lru->sq_qhead.cc_next = _sd_lru->sq_qhead.cc_prev
- = &(_sd_lru->sq_qhead);
- return (0);
-}
-
-/*
- * _sdbc_lruq_deconfigure - deconfigure the lru queue
- *
- * ARGUMENTS: NONE
- *
- */
-
-static void
-_sdbc_lruq_deconfigure(void)
-{
- _sd_queue_t *_sd_lru;
-
- _sd_lru = _SD_LRU_Q;
-
- mutex_destroy(&_sd_lru->sq_qlock);
- bzero(_sd_lru, sizeof (_sd_queue_t));
-
-}
-
-/*
- * _sdbc_mem_configure - initialize the cache memory.
- * Create and initialize the hash table.
- * Create cache control blocks and fill them with relevent
- * information and enqueue onto the lru queue.
- * Initialize the Write control blocks (blocks that contain
- * information as to where the data will be mirrored)
- * Initialize the Fault tolerant blocks (blocks that contain
- * information about the mirror nodes dirty writes)
- *
- * ARGUMENTS:
- * cblocks - Number of cache blocks.
- * RETURNS: 0
- *
- */
-static int
-_sdbc_mem_configure(int cblocks, spcs_s_info_t kstatus)
-{
- int num_blks, i, blk;
- _sd_cctl_t *centry;
- _sd_net_t *netc;
- _sd_cctl_t *prev_entry_dm, *first_entry_dm;
-
- if ((_sd_htable = _sdbc_hash_configure(cblocks)) == NULL) {
- spcs_s_add(kstatus, SDBC_ENOHASH);
- return (-1);
- }
-
- _sd_cctl_groupsz = (cblocks / _SD_CCTL_GROUPS) +
- ((cblocks % _SD_CCTL_GROUPS) != 0);
-
- for (i = 0; i < _SD_CCTL_GROUPS; i++) {
- _sd_cctl[i] = (_sd_cctl_t *)
- nsc_kmem_zalloc(_sd_cctl_groupsz * sizeof (_sd_cctl_t),
- KM_SLEEP, sdbc_cache_mem);
-
- if (_sd_cctl[i] == NULL) {
- spcs_s_add(kstatus, SDBC_ENOCB);
- return (-1);
- }
- }
-
- _sd_ccent_sync = (_sd_cctl_sync_t *)
- nsc_kmem_zalloc(_sd_ccsync_cnt * sizeof (_sd_cctl_sync_t),
- KM_SLEEP, sdbc_local_mem);
-
- if (_sd_ccent_sync == NULL) {
- spcs_s_add(kstatus, SDBC_ENOCCTL);
- return (-1);
- }
-
- for (i = 0; i < _sd_ccsync_cnt; i++) {
- mutex_init(&_sd_ccent_sync[i]._cc_lock, NULL, MUTEX_DRIVER,
- NULL);
- cv_init(&_sd_ccent_sync[i]._cc_blkcv, NULL, CV_DRIVER, NULL);
- }
-
- blk = 0;
-
- netc = &_sd_net_config;
-
- num_blks = (netc->sn_cpages * (int)netc->sn_psize)/BLK_SIZE(1);
-
- prev_entry_dm = 0;
- first_entry_dm = 0;
- for (i = 0; i < num_blks; i++, blk++) {
- centry = _sd_cctl[(blk/_sd_cctl_groupsz)] +
- (blk%_sd_cctl_groupsz);
- centry->cc_sync = &_sd_ccent_sync[blk % _sd_ccsync_cnt];
- centry->cc_next = centry->cc_prev = NULL;
- centry->cc_dirty_next = centry->cc_dirty_link = NULL;
- centry->cc_await_use = centry->cc_await_page = 0;
- centry->cc_inuse = centry->cc_pageio = 0;
- centry->cc_flag = 0;
- centry->cc_iocount = 0;
- centry->cc_valid = 0;
-
- if (!first_entry_dm)
- first_entry_dm = centry;
- if (prev_entry_dm)
- prev_entry_dm->cc_link_list_dm = centry;
- prev_entry_dm = centry;
- centry->cc_link_list_dm = first_entry_dm;
- centry->cc_data = 0;
- centry->cc_write = NULL;
- centry->cc_dirty = 0;
-
- {
- _sd_queue_t *q;
- if (sdbc_use_dmchain) {
- q = &sdbc_dm_queues[0];
- centry->cc_cblocks = 0;
- } else
- q = _SD_LRU_Q;
-
- _sd_ins_queue(q, centry);
- }
-
- }
-
- if (_sdbc_gl_centry_configure(kstatus) != 0)
- return (-1);
-
- if (_sdbc_gl_file_configure(kstatus) != 0)
- return (-1);
-
- return (0);
-}
-
-/*
- * _sdbc_gl_file_configure()
- * allocate and initialize space for the global filename data.
- *
- */
-static int
-_sdbc_gl_file_configure(spcs_s_info_t kstatus)
-{
- ss_voldata_t *fileinfo;
- ss_voldata_t tempfinfo;
- ss_vdir_t vdir;
- ss_vdirkey_t key;
- int err = 0;
-
- _sdbc_gl_file_info_size = safestore_config.ssc_maxfiles *
- sizeof (ss_voldata_t);
-
- if ((_sdbc_gl_file_info = kmem_zalloc(_sdbc_gl_file_info_size,
- KM_NOSLEEP)) == NULL) {
- spcs_s_add(kstatus, SDBC_ENOSFNV);
- return (-1);
- }
-
- /* setup the key to get a directory stream of all volumes */
- key.vk_type = CDIR_ALL;
-
- fileinfo = _sdbc_gl_file_info;
-
- /*
- * if coming up after a crash, "refresh" the host
- * memory copy from safestore.
- */
- if (_sdbc_warm_start()) {
-
- if (SSOP_GETVDIR(sdbc_safestore, &key, &vdir)) {
- cmn_err(CE_WARN, "!sdbc(_sdbc_gl_file_configure): "
- "cannot read safestore");
- return (-1);
- }
-
-
- /*
- * cycle through the vdir getting volume data
- * and volume tokens
- */
-
- while ((err = SSOP_GETVDIRENT(sdbc_safestore, &vdir, fileinfo))
- == SS_OK) {
- ++fileinfo;
- }
-
- if (err != SS_EOF) {
- /*
- * fail to configure since
- * recovery is not possible.
- */
- spcs_s_add(kstatus, SDBC_ENOREFRESH);
- return (-1);
- }
-
- } else { /* normal initialization, not a warm start */
-
- /*
- * if this fails, continue: cache will start
- * in writethru mode
- */
-
- if (SSOP_GETVDIR(sdbc_safestore, &key, &vdir)) {
- cmn_err(CE_WARN, "!sdbc(_sdbc_gl_file_configure): "
- "cannot read safestore");
- return (-1);
- }
-
- /*
- * cycle through the vdir getting just the volume tokens
- * and initializing volume entries
- */
-
- while ((err = SSOP_GETVDIRENT(sdbc_safestore, &vdir,
- &tempfinfo)) == 0) {
- /*
- * initialize the host memory copy of the
- * global file region. this means setting the
- * _pinned and _attached fields to _SD_NO_HOST
- * because the default of zero conflicts with
- * the min nodeid of zero.
- */
- fileinfo->sv_vol = tempfinfo.sv_vol;
- fileinfo->sv_pinned = _SD_NO_HOST;
- fileinfo->sv_attached = _SD_NO_HOST;
- fileinfo->sv_cd = _SD_NO_CD;
-
- /* initialize the directory entry */
- if ((err = SSOP_SETVOL(sdbc_safestore, fileinfo))
- == SS_ERR) {
- cmn_err(CE_WARN,
- "!sdbc(_sdbc_gl_file_configure): "
- "volume entry write failure %p",
- (void *)fileinfo->sv_vol);
- break;
- }
-
- ++fileinfo;
- }
-
- /* coming up clean, continue in w-t mode */
- if (err != SS_EOF)
- cmn_err(CE_WARN, "!sdbc(_sdbc_gl_file_configure) "
- "unable to init safe store volinfo");
- }
-
- return (0);
-}
-
-static void
-_sdbc_gl_centry_deconfigure(void)
-{
- if (_sdbc_gl_centry_info)
- kmem_free(_sdbc_gl_centry_info, _sdbc_gl_centry_info_size);
-
- _sdbc_gl_centry_info = NULL;
- _sdbc_gl_centry_info_size = 0;
-}
-
-static int
-_sdbc_gl_centry_configure(spcs_s_info_t kstatus)
-{
-
- int wblocks;
- ss_centry_info_t *cinfo;
- ss_cdirkey_t key;
- ss_cdir_t cdir;
- int err = 0;
-
-
- wblocks = safestore_config.ssc_wsize / BLK_SIZE(1);
- _sdbc_gl_centry_info_size = sizeof (ss_centry_info_t) * wblocks;
-
- if ((_sdbc_gl_centry_info = kmem_zalloc(_sdbc_gl_centry_info_size,
- KM_NOSLEEP)) == NULL) {
- cmn_err(CE_WARN, "!sdbc(_sdbc_gl_centry_configure) "
- "alloc failed for gl_centry_info region");
-
- _sdbc_gl_centry_deconfigure();
- return (-1);
- }
-
- /*
- * synchronize the centry info area with safe store
- */
-
- /* setup the key to get a directory stream of all centrys */
- key.ck_type = CDIR_ALL;
-
- cinfo = _sdbc_gl_centry_info;
-
- if (_sdbc_warm_start()) {
-
- if (SSOP_GETCDIR(sdbc_safestore, &key, &cdir)) {
- cmn_err(CE_WARN, "!sdbc(_sdbc_gl_centry_configure): "
- "cannot read safestore");
- return (-1);
- }
-
-
- /*
- * cycle through the cdir getting resource
- * tokens and reading centrys
- */
-
- while ((err = SSOP_GETCDIRENT(sdbc_safestore, &cdir, cinfo))
- == 0) {
- ++cinfo;
- }
-
- if (err != SS_EOF) {
- /*
- * fail to configure since
- * recovery is not possible.
- */
- _sdbc_gl_centry_deconfigure();
- spcs_s_add(kstatus, SDBC_EGLDMAFAIL);
- return (-1);
- }
-
- } else {
-
- if (SSOP_GETCDIR(sdbc_safestore, &key, &cdir)) {
- cmn_err(CE_WARN, "!sdbc(_sdbc_gl_centry_configure): "
- "cannot read safestore");
- return (-1);
- }
-
- /*
- * cycle through the cdir getting resource
- * tokens and initializing centrys
- */
-
- while ((err = SSOP_GETCDIRENT(sdbc_safestore, &cdir, cinfo))
- == 0) {
- cinfo->sc_cd = -1;
- cinfo->sc_fpos = -1;
-
- if ((err = SSOP_SETCENTRY(sdbc_safestore, cinfo))
- == SS_ERR) {
- cmn_err(CE_WARN,
- "!sdbc(_sdbc_gl_centry_configure): "
- "cache entry write failure %p",
- (void *)cinfo->sc_res);
- break;
- }
-
- ++cinfo;
- }
-
- /* coming up clean, continue in w-t mode */
- if (err != SS_EOF) {
- cmn_err(CE_WARN, "!sdbc(sdbc_gl_centry_configure) "
- "_sdbc_gl_centry_info initialization failed");
- }
- }
-
- return (0);
-}
-
-
-static void
-_sdbc_gl_file_deconfigure(void)
-{
-
- if (_sdbc_gl_file_info)
- kmem_free(_sdbc_gl_file_info, _sdbc_gl_file_info_size);
-
- _sdbc_gl_file_info = NULL;
-
- _sdbc_gl_file_info_size = 0;
-}
-
-
-/*
- * _sdbc_mem_deconfigure - deconfigure the cache memory.
- * Release any memory/locks/sv's acquired during _sdbc_mem_configure.
- *
- * ARGUMENTS:
- * cblocks - Number of cache blocks.
- *
- */
-/* ARGSUSED */
-static void
-_sdbc_mem_deconfigure(int cblocks)
-{
- int i;
-
- if (_sd_ccent_sync) {
- for (i = 0; i < _sd_ccsync_cnt; i++) {
- mutex_destroy(&_sd_ccent_sync[i]._cc_lock);
- cv_destroy(&_sd_ccent_sync[i]._cc_blkcv);
- }
- nsc_kmem_free(_sd_ccent_sync,
- _sd_ccsync_cnt * sizeof (_sd_cctl_sync_t));
- }
- _sd_ccent_sync = NULL;
-
- for (i = 0; i < _SD_CCTL_GROUPS; i++) {
- if (_sd_cctl[i] != NULL) {
- nsc_kmem_free(_sd_cctl[i],
- _sd_cctl_groupsz * sizeof (_sd_cctl_t));
- _sd_cctl[i] = NULL;
- }
- }
- _sd_cctl_groupsz = 0;
-
- _sdbc_hash_deconfigure(_sd_htable);
- _sd_htable = NULL;
-
-}
-
-
-#if defined(_SD_DEBUG) || defined(DEBUG)
-static int
-_sd_cctl_valid(_sd_cctl_t *addr)
-{
- _sd_cctl_t *end;
- int i, valid;
-
- valid = 0;
- for (i = 0; i < _SD_CCTL_GROUPS; i++) {
- end = _sd_cctl[i] + _sd_cctl_groupsz;
- if (addr >= _sd_cctl[i] && addr < end) {
- valid = 1;
- break;
- }
- }
-
- return (valid);
-}
-#endif
-
-
-/*
- * _sd_ins_queue - insert centry into LRU queue
- * (during initialization, locking not required)
- */
-static void
-_sd_ins_queue(_sd_queue_t *q, _sd_cctl_t *centry)
-{
- _sd_cctl_t *q_head;
-
- ASSERT(_sd_cctl_valid(centry));
-
- q_head = &q->sq_qhead;
- centry->cc_prev = q_head;
- centry->cc_next = q_head->cc_next;
- q_head->cc_next->cc_prev = centry;
- q_head->cc_next = centry;
- q->sq_inq++;
-
- ASSERT(GOOD_LRUSIZE(q));
-}
-
-
-
-void
-_sd_requeue(_sd_cctl_t *centry)
-{
- _sd_queue_t *q = _SD_LRU_Q;
-
- /* was FAST */
- mutex_enter(&q->sq_qlock);
-#if defined(_SD_DEBUG)
- if (1) {
- _sd_cctl_t *cp, *cn, *qp;
- cp = centry->cc_prev;
- cn = centry->cc_next;
- qp = (q->sq_qhead).cc_prev;
- if (!_sd_cctl_valid(centry) ||
- (cp != &(q->sq_qhead) && !_sd_cctl_valid(cp)) ||
- (cn != &(q->sq_qhead) && !_sd_cctl_valid(cn)) ||
- !_sd_cctl_valid(qp))
- cmn_err(CE_PANIC,
- "_sd_requeue %x prev %x next %x qp %x",
- centry, cp, cn, qp);
- }
-#endif
- centry->cc_prev->cc_next = centry->cc_next;
- centry->cc_next->cc_prev = centry->cc_prev;
- centry->cc_next = &(q->sq_qhead);
- centry->cc_prev = q->sq_qhead.cc_prev;
- q->sq_qhead.cc_prev->cc_next = centry;
- q->sq_qhead.cc_prev = centry;
- centry->cc_seq = q->sq_seq++;
- /* was FAST */
- mutex_exit(&q->sq_qlock);
- (q->sq_req_stat)++;
-
-}
-
-void
-_sd_requeue_head(_sd_cctl_t *centry)
-{
- _sd_queue_t *q = _SD_LRU_Q;
-
- /* was FAST */
- mutex_enter(&q->sq_qlock);
-#if defined(_SD_DEBUG)
- if (1) {
- _sd_cctl_t *cp, *cn, *qn;
- cp = centry->cc_prev;
- cn = centry->cc_next;
- qn = (q->sq_qhead).cc_prev;
- if (!_sd_cctl_valid(centry) ||
- (cp != &(q->sq_qhead) && !_sd_cctl_valid(cp)) ||
- (cn != &(q->sq_qhead) && !_sd_cctl_valid(cn)) ||
- !_sd_cctl_valid(qn))
- cmn_err(CE_PANIC,
- "_sd_requeue_head %x prev %x next %x qn %x",
- centry, cp, cn, qn);
- }
-#endif
- centry->cc_prev->cc_next = centry->cc_next;
- centry->cc_next->cc_prev = centry->cc_prev;
- centry->cc_prev = &(q->sq_qhead);
- centry->cc_next = q->sq_qhead.cc_next;
- q->sq_qhead.cc_next->cc_prev = centry;
- q->sq_qhead.cc_next = centry;
- centry->cc_seq = q->sq_seq++;
- centry->cc_flag &= ~CC_QHEAD;
- /* was FAST */
- mutex_exit(&q->sq_qlock);
-}
-
-
-
-/*
- * _sd_open - Open a file.
- *
- * ARGUMENTS:
- * filename - Name of the file to be opened.
- * flag - Flag associated with open.
- * (currently used to determine a ckd device)
- * RETURNS:
- * cd - the cache descriptor.
- */
-
-int
-_sd_open(char *filename, int flag)
-{
- int cd;
-
- if (!_sd_cache_initialized) {
- cmn_err(CE_WARN, "!sdbc(_sd_open) cache not initialized");
- return (-EINVAL);
- }
- cd = _sd_open_cd(filename, -1, flag);
- SDTRACE(SDF_OPEN, (cd < 0) ? SDT_INV_CD : cd, 0, SDT_INV_BL, 0, cd);
-
- return (cd);
-}
-
-
-static int
-_sd_open_io(char *filename, int flag, blind_t *cdp, nsc_iodev_t *iodev)
-{
- _sd_cd_info_t *cdi;
- int cd;
- int rc = 0;
-
- if ((cd = _sd_open(filename, flag)) >= 0) {
-
- cdi = &(_sd_cache_files[cd]);
- cdi->cd_iodev = iodev;
- nsc_set_owner(cdi->cd_rawfd, cdi->cd_iodev);
-
- *cdp = (blind_t)(unsigned long)cd;
- } else
- rc = -cd;
-
- return (rc);
-}
-
-
-
-int
-_sd_open_cd(char *filename, const int cd, const int flag)
-{
- int new_cd, rc = 0, alloc_cd = -1;
- ss_voldata_t *cdg;
- int preexists = 0;
- _sd_cd_info_t *cdi;
- int failover_open, open_failed;
- major_t devmaj;
- minor_t devmin;
-
- if (_sdbc_shutdown_in_progress)
- return (-EIO);
-
- if (strlen(filename) > (NSC_MAXPATH-1))
- return (-ENAMETOOLONG);
-
- /*
- * If the cd is >= 0, then this is a open for a specific cd.
- * This happens when the mirror node crashes, and we attempt to
- * reopen the files with the same cache descriptors as existed on
- * the other node
- */
-
-retry_open:
- failover_open = 0;
- open_failed = 0;
- if (cd >= 0) {
- failover_open++;
- cdi = &(_sd_cache_files[cd]);
- mutex_enter(&_sd_cache_lock);
- if (cdi->cd_info == NULL)
- cdi->cd_info = &_sd_cache_stats->st_shared[cd];
- else if (cdi->cd_info->sh_alloc &&
- strcmp(cdi->cd_info->sh_filename, filename)) {
- cmn_err(CE_WARN, "!sdbc(_sd_open_cd) cd %d mismatch",
- cd);
- mutex_exit(&_sd_cache_lock);
- return (-EEXIST);
- }
-
- if (cdi->cd_info->sh_failed != 2) {
- if (cdi->cd_info->sh_alloc != 0)
- preexists = 1;
- else {
- cdi->cd_info->sh_alloc = CD_ALLOC_IN_PROGRESS;
- (void) strcpy(cdi->cd_info->sh_filename,
- filename);
- if (_sd_cache_stats->st_count < sdbc_max_devs)
- _sd_cache_stats->st_count++;
- }
- }
-
- mutex_exit(&_sd_cache_lock);
- alloc_cd = cd;
-
- goto known_cd;
- }
-
- new_cd = 0;
- mutex_enter(&_sd_cache_lock);
-
- for (cdi = &(_sd_cache_files[new_cd]),
- cdg = _sdbc_gl_file_info + new_cd;
- new_cd < (sdbc_max_devs); new_cd++, cdi++, cdg++) {
- if (strlen(cdg->sv_volname) != 0)
- if (strcmp(cdg->sv_volname, filename))
- continue;
-
- if (cdi->cd_info == NULL)
- cdi->cd_info = &_sd_cache_stats->st_shared[new_cd];
-
- if (cdi->cd_info->sh_failed != 2) {
- if (cdi->cd_info->sh_alloc != 0)
- preexists = 1;
- else {
- if (cd == -2) {
- mutex_exit(&_sd_cache_lock);
- return (-1);
- }
- cdi->cd_info->sh_alloc = CD_ALLOC_IN_PROGRESS;
- (void) strcpy(cdi->cd_info->sh_filename,
- filename);
- (void) strcpy(cdg->sv_volname, filename);
-
- cdg->sv_cd = new_cd;
- /* update safestore */
- SSOP_SETVOL(sdbc_safestore, cdg);
- if (_sd_cache_stats->st_count < sdbc_max_devs)
- _sd_cache_stats->st_count++;
- cdi->cd_flag = 0;
- }
- }
- alloc_cd = new_cd;
- break;
- }
-
- mutex_exit(&_sd_cache_lock);
-
- if (alloc_cd == -1)
- return (-ENOSPC);
-
-known_cd:
- /*
- * If preexists: someone else is attempting to open this file as
- * well. Do only one open, but block everyone else here till the
- * open is completed.
- */
- if (preexists) {
- while (cdi->cd_info->sh_alloc == CD_ALLOC_IN_PROGRESS) {
- delay(drv_usectohz(20000));
- }
- if ((cdi->cd_info->sh_alloc != CD_ALLOCATED))
- goto retry_open;
- return (alloc_cd);
- }
-
- if (!(cdi->cd_rawfd =
- nsc_open(filename, NSC_SDBC_ID|NSC_DEVICE, _sdbc_fd_def,
- (blind_t)(unsigned long)alloc_cd, &rc)) ||
- !nsc_getval(cdi->cd_rawfd, "DevMaj", (int *)&devmaj) ||
- !nsc_getval(cdi->cd_rawfd, "DevMin", (int *)&devmin)) {
- if (cdi->cd_rawfd) {
- (void) nsc_close(cdi->cd_rawfd);
- cdi->cd_rawfd = NULL;
- }
- /*
- * take into account that there may be pinned data on a
- * device that can no longer be opened
- */
- open_failed++;
- if (!(cdi->cd_info->sh_failed) && !failover_open) {
- cdi->cd_info->sh_alloc = 0;
- mutex_enter(&_sd_cache_lock);
- _sd_cache_stats->st_count--;
- mutex_exit(&_sd_cache_lock);
- if (!rc)
- rc = EIO;
- return (-rc);
- }
- }
-
- cdi->cd_strategy = nsc_get_strategy(devmaj);
- cdi->cd_crdev = makedevice(devmaj, devmin);
- cdi->cd_desc = alloc_cd;
- cdi->cd_dirty_head = cdi->cd_dirty_tail = NULL;
- cdi->cd_io_head = cdi->cd_io_tail = NULL;
- cdi->cd_hint = 0;
-#ifdef DEBUG
- /* put the dev_t in the ioerr_inject_table */
- _sdbc_ioj_set_dev(alloc_cd, cdi->cd_crdev);
-#endif
-
- cdi->cd_global = (_sdbc_gl_file_info + alloc_cd);
- if (open_failed) {
- cdi->cd_info->sh_failed = 2;
- } else if (cdi->cd_info->sh_failed != 2)
- if ((cdi->cd_global->sv_pinned == _SD_SELF_HOST) &&
- !failover_open)
- cdi->cd_info->sh_failed = 1;
- else
- cdi->cd_info->sh_failed = 0;
-
- cdi->cd_flag |= flag;
- mutex_init(&cdi->cd_lock, NULL, MUTEX_DRIVER, NULL);
-
-#ifndef _SD_NOTRACE
- (void) _sdbc_tr_configure(alloc_cd);
-#endif
- cdi->cd_info->sh_alloc = CD_ALLOCATED;
- cdi->cd_global = (_sdbc_gl_file_info + alloc_cd);
- cdi->cd_info->sh_cd = (unsigned short) alloc_cd;
- mutex_enter(&_sd_cache_lock);
- _sd_cache_stats->st_loc_count++;
- mutex_exit(&_sd_cache_lock);
-
- if (cd_kstat_add(alloc_cd) < 0) {
- cmn_err(CE_WARN, "!Could not create kstats for cache descriptor"
- " %d", alloc_cd);
- }
-
-
- return (open_failed ? -EIO : alloc_cd);
-}
-
-
-/*
- * _sd_close - Close a cache descriptor.
- *
- * ARGUMENTS:
- * cd - the cache descriptor to be closed.
- * RETURNS:
- * 0 on success.
- * Error otherwise.
- *
- * Note: Under Construction.
- */
-
-int
-_sd_close(int cd)
-{
- int rc;
- _sd_cd_info_t *cdi = &(_sd_cache_files[cd]);
-
- if (!FILE_OPENED(cd)) {
- rc = EINVAL;
- goto out;
- }
-
- SDTRACE(ST_ENTER|SDF_CLOSE, cd, 0, SDT_INV_BL, 0, 0);
-
- mutex_enter(&_sd_cache_lock);
- if ((cdi->cd_info->sh_alloc == 0) ||
- (cdi->cd_info->sh_alloc & CD_CLOSE_IN_PROGRESS)) {
- mutex_exit(&_sd_cache_lock);
- SDTRACE(ST_EXIT|SDF_CLOSE, cd, 0, SDT_INV_BL, 0, EINVAL);
- rc = EINVAL;
- goto out;
- }
- cdi->cd_info->sh_alloc |= CD_CLOSE_IN_PROGRESS;
- mutex_exit(&_sd_cache_lock);
-
- /*
- * _sd_flush_cd() will return -1 for the case where pinned
- * data is present, but has been transfered to the mirror
- * node. In this case it is safe to close the device as
- * though _sd_flush_cd() had returned 0.
- */
-
- rc = _sd_flush_cd(cd);
- if (rc == -1)
- rc = 0;
-
- if (rc != 0) {
- mutex_enter(&_sd_cache_lock);
- if ((rc == EAGAIN) &&
- (cdi->cd_global->sv_pinned == _SD_NO_HOST)) {
- cdi->cd_global->sv_pinned = _SD_SELF_HOST;
- SSOP_SETVOL(sdbc_safestore, cdi->cd_global);
- }
-
- cdi->cd_info->sh_alloc &= ~CD_CLOSE_IN_PROGRESS;
- mutex_exit(&_sd_cache_lock);
- SDTRACE(ST_EXIT|SDF_CLOSE, cd, 0, SDT_INV_BL,
- _SD_CD_WBLK_USED(cd), rc);
- goto out;
- }
-
- rc = nsc_close(cdi->cd_rawfd);
- if (rc) {
- mutex_enter(&_sd_cache_lock);
- cdi->cd_info->sh_alloc &= ~CD_CLOSE_IN_PROGRESS;
- mutex_exit(&_sd_cache_lock);
- SDTRACE(ST_EXIT|SDF_CLOSE, cd, 0, SDT_INV_BL, 0, rc);
- goto out;
- }
- mutex_enter(&_sd_cache_lock);
- _sd_cache_stats->st_loc_count--;
- mutex_exit(&_sd_cache_lock);
-
- if (cd_kstat_remove(cd) < 0) {
- cmn_err(CE_WARN, "!Could not remove kstat for cache descriptor "
- "%d", cd);
- }
-
- cdi->cd_info->sh_alloc = 0;
- cdi->cd_info->sh_failed = 0;
- /* cdi->cd_info = NULL; */
- cdi->cd_flag = 0;
- SDTRACE(ST_EXIT|SDF_CLOSE, cd, 0, SDT_INV_BL, 0, NSC_DONE);
- rc = NSC_DONE;
- goto out;
-
-out:
- return (rc);
-}
-
-
-static int
-_sd_close_io(blind_t xcd)
-{
- _sd_cd_info_t *cdi;
- int cd = (int)(unsigned long)xcd;
- int rc = 0;
-
- if ((rc = _sd_close((int)cd)) == NSC_DONE) {
- cdi = &(_sd_cache_files[cd]);
- cdi->cd_iodev = NULL;
- }
-
- return (rc);
-}
-
-
-/*
- * _sdbc_remote_store_pinned - reflect pinned/failed blocks for cd
- * to our remote mirror. Returns count of blocks reflected or -1 on error.
- *
- */
-int
-_sdbc_remote_store_pinned(int cd)
-{
- int cnt = 0;
- _sd_cd_info_t *cdi = &(_sd_cache_files[cd]);
- _sd_cctl_t *cc_ent, *cc_list;
-
- ASSERT(cd >= 0);
- if (cdi->cd_info->sh_failed) {
-
- if (cdi->cd_global->sv_pinned == _SD_NO_HOST) {
- cdi->cd_global->sv_pinned = _SD_SELF_HOST;
- SSOP_SETVOL(sdbc_safestore, cdi->cd_global);
- }
-
- mutex_enter(&cdi->cd_lock);
- cc_ent = cc_list = cdi->cd_fail_head;
- while (cc_ent) {
- cnt++;
-
- /* is this always necessary? jgk */
-
- if (SSOP_WRITE_CBLOCK(sdbc_safestore,
- cc_ent->cc_write->sc_res, cc_ent->cc_data,
- CACHE_BLOCK_SIZE, 0)) {
- mutex_exit(&cdi->cd_lock);
- return (-1);
- }
-
- /* update the cache block metadata */
- CENTRY_SET_FTPOS(cc_ent);
- cc_ent->cc_write->sc_flag = cc_ent->cc_flag;
-
- cc_ent->cc_write->sc_dirty = CENTRY_DIRTY(cc_ent);
-
- SSOP_SETCENTRY(sdbc_safestore, cc_ent->cc_write);
-
- cc_ent = cc_ent->cc_dirty_next;
- if (!cc_ent)
- cc_ent = cc_list = cc_list->cc_dirty_link;
- }
- mutex_exit(&cdi->cd_lock);
- }
-
- return (cnt);
-}
-
-/*
- * _sd_flush_cd()
- * reflect pinned blocks to mirrored node
- * wait for dirty blocks to be flushed
- * returns:
- * EIO I/O failure, or pinned blocks and no mirror
- * EAGAIN Hang: count of outstanding writes isn't decreasing
- * -1 pinned blocks, reflected to mirror
- * 0 success
- */
-static int
-_sd_flush_cd(int cd)
-{
- int rc;
-
- if ((rc = _sd_wait_for_flush(cd)) == 0)
- return (0);
-
- /*
- * if we timed out simply return otherwise
- * it must be an i/o type of error
- */
- if (rc == EAGAIN)
- return (rc);
-
- if (_sd_is_mirror_down())
- return (EIO); /* already failed, no mirror */
-
- /* flush any pinned/failed blocks to mirror */
- if (_sdbc_remote_store_pinned(cd) >= 0)
- /*
- * At this point it looks like we have blocks on the
- * failed list and taking up space on this node but
- * no longer have responsibility for the blocks.
- * These blocks will in fact be freed from the cache
- * and the failed list when the mirror picks them up
- * from safe storage and then calls _sd_cd_discard_mirror
- * which will issue an rpc telling us to finish up.
- *
- * Should the other node die before sending the rpc then
- * we are safe with these blocks simply waiting on the
- * failed list.
- */
- return (-1);
- else
- return (rc);
-}
-
-/*
- * _sdbc_io_attach_cd -- set up for client access to device, reserve raw device
- *
- * ARGUMENTS:
- * cd - the cache descriptor to attach.
- *
- * RETURNS:
- * 0 on success.
- * Error otherwise.
- */
-int
-_sdbc_io_attach_cd(blind_t xcd)
-{
- int rc = 0;
- _sd_cd_info_t *cdi;
- int cd = (int)(unsigned long)xcd;
-
- SDTRACE(ST_ENTER|SDF_ATTACH, cd, 0, SDT_INV_BL, 0, 0);
- if (!_sd_cache_initialized ||
- _sdbc_shutdown_in_progress ||
- !FILE_OPENED(cd)) {
- SDTRACE(ST_EXIT|SDF_ATTACH, cd, 0, SDT_INV_BL, 0, EINVAL);
-
- DTRACE_PROBE(_sdbc_io_attach_cd_end1);
-
- return (EINVAL);
- }
- cdi = &(_sd_cache_files[cd]);
-
- /*
- * check if disk is failed without raw device open. If it is,
- * it has to be recovered using _sd_disk_online
- */
-
- if (cdi->cd_global->sv_pinned == _SD_SELF_HOST) {
- _sd_print(3,
- "_sdbc_io_attach_cd: pinned data. returning EINVAL");
-
- DTRACE_PROBE(_sdbc_io_attach_cd_end2);
-
- return (EINVAL);
- }
-
- if ((cdi->cd_info == NULL) || (cdi->cd_info->sh_failed)) {
- DTRACE_PROBE1(_sdbc_io_attach_cd_end3,
- struct _sd_shared *, cdi->cd_info);
-
- return (EINVAL);
- }
-
-#if defined(_SD_FAULT_RES)
- /* wait for node recovery to finish */
- if (_sd_node_recovery)
- (void) _sd_recovery_wait();
-#endif
-
- /* this will provoke a sdbc_fd_attach_cd call .. */
-
- rc = nsc_reserve(cdi->cd_rawfd, NSC_MULTI);
- SDTRACE(ST_EXIT|SDF_ATTACH, cd, 0, SDT_INV_BL, 0, rc);
-
- return (rc);
-}
-
-/*
- * sdbc_fd_attach_cd -- setup cache for access to raw device underlying cd.
- * This is provoked by some piece of sdbc doing a reserve on the raw device.
- *
- * ARGUMENTS:
- * cd - the cache descriptor to attach.
- *
- * RETURNS:
- * 0 on success.
- * Error otherwise.
- */
-static int
-sdbc_fd_attach_cd(blind_t xcd)
-{
- int rc = 0;
- int cd = (int)(unsigned long)xcd;
- _sd_cd_info_t *cdi;
-
- if (!_sd_cache_initialized || !FILE_OPENED(cd)) {
- SDTRACE(ST_INFO|SDF_ATTACH, cd, 0, SDT_INV_BL, 0, EINVAL);
-
- DTRACE_PROBE(sdbc_fd_attach_cd_end1);
-
- return (EINVAL);
- }
- cdi = &(_sd_cache_files[cd]);
-
-#if defined(_SD_FAULT_RES)
- /* retrieve pinned/failed data */
- if (!_sd_node_recovery) {
- (void) _sd_repin_cd(cd);
- }
-#endif
-
- rc = nsc_partsize(cdi->cd_rawfd, &cdi->cd_info->sh_filesize);
- if (rc != 0) {
- SDTRACE(ST_INFO|SDF_ATTACH, cd, 0, SDT_INV_BL, 0, rc);
-
- DTRACE_PROBE(sdbc_fd_attach_cd_end3);
-
- return (rc);
- }
-
- cdi->cd_global->sv_attached = _SD_SELF_HOST;
-
- SSOP_SETVOL(sdbc_safestore, cdi->cd_global);
-
- mutex_enter(&_sd_cache_lock);
- cdi->cd_info->sh_flag |= CD_ATTACHED;
- mutex_exit(&_sd_cache_lock);
-
- return (0);
-}
-
-/*
- * _sdbc_io_detach_cd -- release raw device
- * Called when a cache client is being detached from this cd.
- *
- * ARGUMENTS:
- * cd - the cache descriptor to detach.
- * RETURNS:
- * 0 on success.
- * Error otherwise.
- */
-int
-_sdbc_io_detach_cd(blind_t xcd)
-{
- int cd = (int)(unsigned long)xcd;
- _sd_cd_info_t *cdi;
-
-
- SDTRACE(ST_ENTER|SDF_DETACH, cd, 0, SDT_INV_BL, 0, 0);
- if (!_sd_cache_initialized || !FILE_OPENED(cd)) {
- SDTRACE(ST_EXIT|SDF_DETACH, cd, 0, SDT_INV_BL, 0, EINVAL);
-
- DTRACE_PROBE(_sdbc_io_detach_cd_end1);
-
- return (EINVAL);
- }
-
-#if defined(_SD_FAULT_RES)
- if (_sd_node_recovery)
- (void) _sd_recovery_wait();
-#endif
- /* relinquish responsibility for device */
- cdi = &(_sd_cache_files[cd]);
- if (!(cdi->cd_rawfd) || !nsc_held(cdi->cd_rawfd)) {
- cmn_err(CE_WARN, "!sdbc(_sdbc_detach_cd)(%d) not attached", cd);
- SDTRACE(ST_EXIT|SDF_DETACH, cd, 0, SDT_INV_BL, 0, EPROTO);
- DTRACE_PROBE1(_sdbc_io_detach_cd_end2,
- nsc_fd_t *, cdi->cd_rawfd);
-
- return (EPROTO);
- }
- /* this will provoke/allow a call to sdbc_fd_detach_cd */
- nsc_release(cdi->cd_rawfd);
-
- SDTRACE(ST_EXIT|SDF_DETACH, cd, 0, SDT_INV_BL, 0, 0);
-
- return (0);
-}
-
-/*
- * _sdbc_detach_cd -- flush dirty writes to disk, release raw device
- * Called when raw device is being detached from this cd.
- *
- * ARGUMENTS:
- * cd - the cache descriptor to detach.
- * rd_only - non-zero if detach is for read access.
- * RETURNS:
- * 0 on success.
- * Error otherwise.
- */
-static int
-sdbc_detach_cd(blind_t xcd, int rd_only)
-{
- int rc;
- int cd = (int)(unsigned long)xcd;
- _sd_cd_info_t *cdi;
-
- SDTRACE(ST_INFO|SDF_DETACH, cd, 0, SDT_INV_BL, 0, 0);
-
- if (!_sd_cache_initialized || !FILE_OPENED(cd)) {
- SDTRACE(ST_INFO|SDF_DETACH, cd, 0, SDT_INV_BL, 0, EINVAL);
-
- DTRACE_PROBE(sdbc_detach_cd_end1);
-
- return (EINVAL);
- }
-
-
- rc = _sd_flush_cd(cd);
- if (rc > 0) {
- SDTRACE(ST_INFO|SDF_DETACH, cd, 0, SDT_INV_BL, 0, rc);
-
- DTRACE_PROBE(sdbc_detach_cd_end2);
-
- return (rc);
- }
-
- if (!rd_only) {
- _sd_hash_invalidate_cd(cd);
- cdi = &(_sd_cache_files[cd]);
-
- if (cdi->cd_global->sv_attached == _SD_SELF_HOST) {
- cdi->cd_global->sv_attached = _SD_NO_HOST;
- SSOP_SETVOL(sdbc_safestore, cdi->cd_global);
- } else {
- cmn_err(CE_WARN,
- "!sdbc(_sdbc_detach_cd) (%d) attached by node %d",
- cd, cdi->cd_global->sv_attached);
- SDTRACE(SDF_DETACH, cd, 0, SDT_INV_BL, 0, EPROTO);
-
- DTRACE_PROBE1(sdbc_detach_cd_end3,
- int, cdi->cd_global->sv_attached);
-
- return (EPROTO);
- }
-
- mutex_enter(&_sd_cache_lock);
- cdi->cd_info->sh_flag &= ~CD_ATTACHED;
- mutex_exit(&_sd_cache_lock);
- }
-
- SDTRACE(ST_INFO|SDF_DETACH, cd, 0, SDT_INV_BL, 0, 0);
-
- return (0);
-}
-
-/*
- * _sdbc_fd_detach_cd -- flush dirty writes to disk, release raw device
- * Called when raw device is being detached from this cd.
- *
- * ARGUMENTS:
- * xcd - the cache descriptor to detach.
- * RETURNS:
- * 0 on success.
- * Error otherwise.
- */
-static int
-sdbc_fd_detach_cd(blind_t xcd)
-{
- return (sdbc_detach_cd(xcd, 0));
-}
-
-/*
- * sdbc_fd_flush_cd - raw device "xcd" is being detached and needs
- * flushing. We only need to flush we don't need to hash invalidate
- * this file.
- */
-static int
-sdbc_fd_flush_cd(blind_t xcd)
-{
- return (sdbc_detach_cd(xcd, 1));
-}
-
-/*
- * _sd_get_pinned - re-issue PINNED callbacks for cache device
- *
- * ARGUMENTS:
- * cd - the cache descriptor to reissue pinned calbacks from.
- * RETURNS:
- * 0 on success.
- * Error otherwise.
- */
-int
-_sd_get_pinned(blind_t xcd)
-{
- _sd_cd_info_t *cdi;
- _sd_cctl_t *cc_list, *cc_ent;
- int cd = (int)(unsigned long)xcd;
-
- cdi = &_sd_cache_files[cd];
-
- if (cd < 0 || cd >= sdbc_max_devs) {
- DTRACE_PROBE(_sd_get_pinned_end1);
- return (EINVAL);
- }
-
- if (!FILE_OPENED(cd)) {
- DTRACE_PROBE(_sd_get_pinned_end2);
- return (0);
- }
-
- mutex_enter(&cdi->cd_lock);
-
- if (!cdi->cd_info->sh_failed) {
- mutex_exit(&cdi->cd_lock);
-
- DTRACE_PROBE(_sd_get_pinned_end3);
- return (0);
- }
-
- cc_ent = cc_list = cdi->cd_fail_head;
- while (cc_ent) {
- if (CENTRY_PINNED(cc_ent))
- nsc_pinned_data(cdi->cd_iodev,
- BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent)), BLK_FBAS);
- cc_ent = cc_ent->cc_dirty_next;
- if (!cc_ent)
- cc_ent = cc_list = cc_list->cc_dirty_link;
- }
-
- mutex_exit(&cdi->cd_lock);
-
- return (0);
-}
-
-/*
- * _sd_allocate_buf - allocate a vector of buffers for io.
- * *This call has been replaced by _sd_alloc_buf*
- */
-
-_sd_buf_handle_t *
-_sd_allocate_buf(int cd, nsc_off_t fba_pos, nsc_size_t fba_len, int flag,
- int *sts)
-{
- _sd_buf_handle_t *handle = NULL;
-
- *sts = _sd_alloc_buf((blind_t)(unsigned long)cd, fba_pos, fba_len,
- flag, &handle);
- if (*sts == NSC_HIT)
- *sts = NSC_DONE;
- return (handle);
-}
-
-
-/*
- * _sd_prefetch_buf - _sd_alloc_buf w/flag = NSC_RDAHEAD|NSC_RDBUF
- * no 'bufvec' (data is not read by caller)
- * skip leading valid or busy entries (data available sooner)
- * truncate on busy block (to avoid deadlock)
- * release trailing valid entries, adjust length before starting I/O.
- */
-static int
-_sd_prefetch_buf(int cd, nsc_off_t fba_pos, nsc_size_t fba_len, int flag,
- _sd_buf_handle_t *handle, int locked)
-{
- _sd_cd_info_t *cdi;
- nsc_off_t cblk; /* position of temp cache block */
- sdbc_cblk_fba_t st_cblk_len; /* FBA len of starting cache block */
- sdbc_cblk_fba_t end_cblk_len; /* FBA len of ending cache block */
- sdbc_cblk_fba_t st_cblk_off; /* FBA offset into starting cblock */
- nsc_off_t io_pos; /* offset in FBA's */
- nsc_size_t fba_orig_len;
- int sts, stall;
- _sd_cctl_t *centry = NULL;
- _sd_cctl_t *lentry = NULL;
- _sd_cctl_t *ioent = NULL;
- _sd_cctl_t *last_ioent = NULL;
- sdbc_allocbuf_t alloc_tok = {0};
- int this_entry_type = 0;
- nsc_size_t request_blocks = 0; /* number of cache blocks required */
- int pageio;
-
- handle->bh_flag |= NSC_HACTIVE;
- ASSERT(cd >= 0);
- cdi = &_sd_cache_files[cd];
-
- /* prefetch: truncate if req'd */
- if (fba_len > sdbc_max_fbas)
- fba_len = sdbc_max_fbas;
- if ((fba_pos + fba_len) > cdi->cd_info->sh_filesize) {
- if (fba_pos >= cdi->cd_info->sh_filesize) {
- sts = EIO;
- goto done;
- }
- fba_len = cdi->cd_info->sh_filesize - fba_pos;
- }
-
- fba_orig_len = fba_len;
-
- _SD_SETUP_HANDLE(handle, cd, fba_pos, fba_len, flag);
- handle->bh_centry = NULL;
-
- cblk = FBA_TO_BLK_NUM(fba_pos);
- st_cblk_off = BLK_FBA_OFF(fba_pos);
- st_cblk_len = BLK_FBAS - st_cblk_off;
-
- /*
- * count number of blocks on chain that is required
- */
- if ((nsc_size_t)st_cblk_len >= fba_len) {
- st_cblk_len = (sdbc_cblk_fba_t)fba_len;
- end_cblk_len = 0;
- } else {
- end_cblk_len = BLK_FBA_OFF(fba_pos + fba_len);
- }
-
- request_blocks = 1; /* at least one */
-
- /* middle piece */
- request_blocks += (fba_len - (st_cblk_len + end_cblk_len)) >>
- BLK_FBA_SHFT;
-
- if (end_cblk_len)
- ++request_blocks;
-
- stall = 0;
- do {
- pageio = ((flag & NSC_PAGEIO) != 0 || sdbc_pageio_always != 0);
-cget:
- if (centry = (_sd_cctl_t *)
- _sd_hash_search(cd, cblk, _sd_htable)) {
-try:
- /* prefetch: skip leading valid blocks */
- if ((ioent == NULL) &&
- SDBC_VALID_BITS(st_cblk_off, st_cblk_len, centry)) {
-skip:
- sdbc_prefetch_valid_cnt++;
- --request_blocks;
- lentry = centry;
- centry = NULL;
- cblk++;
- fba_len -= st_cblk_len;
- st_cblk_off = 0;
- st_cblk_len = (sdbc_cblk_fba_t)
- ((fba_len > (nsc_size_t)BLK_FBAS) ?
- BLK_FBAS : fba_len);
- continue;
- }
-
- if (SET_CENTRY_INUSE(centry)) {
- /*
- * prefetch: skip leading busy
- * or truncate at busy block
- */
- if (ioent == NULL)
- goto skip;
- sdbc_prefetch_busy_cnt++;
- fba_orig_len -= fba_len;
- fba_len = 0;
- centry = lentry; /* backup */
- break;
- }
-
- /*
- * bug 4529671
- * now that we own the centry make sure that
- * it is still good. it could have been processed
- * by _sd_dealloc_dm() in the window between
- * _sd_hash_search() and SET_CENTRY_INUSE().
- */
- if ((_sd_cctl_t *)
- _sd_hash_search(cd, cblk, _sd_htable) != centry) {
- sdbc_prefetch_deallocd++;
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!prefetch centry %p cd %d cblk %" NSC_SZFMT
- " fba_len %" NSC_SZFMT " lost to dealloc?! "
- "cc_data %p",
- (void *)centry, cd, cblk, fba_orig_len,
- (void *)centry->cc_data);
-#endif
-
- CLEAR_CENTRY_INUSE(centry);
- continue;
- }
-
- if (CC_CD_BLK_MATCH(cd, cblk, centry)) {
- /*
- * Do pagelist io mutual exclusion
- * before messing with the centry.
- */
- if (pageio && SET_CENTRY_PAGEIO(centry)) {
- /* flusher not done with pageio */
- /*
- * prefetch: skip leading busy
- * or truncate at busy block
- */
- CLEAR_CENTRY_INUSE(centry);
- if (ioent == NULL)
- goto skip;
- sdbc_prefetch_pageio1++;
- fba_orig_len -= fba_len;
- fba_len = 0;
- centry = lentry; /* backup */
- break;
-
- }
-
- sdbc_prefetch_hit++;
- this_entry_type = HASH_ENTRY_DM;
- pageio = 0;
- centry->cc_toflush = 0;
-
- centry->cc_hits++;
-
- /* this will reset the age flag */
- sdbc_centry_init_dm(centry);
-
- DTRACE_PROBE1(_sd_prefetch_buf,
- _sd_cctl_t *, centry);
- } else {
- /* block mismatch */
- sdbc_prefetch_lost++;
-
- CLEAR_CENTRY_INUSE(centry);
- continue;
- }
- } else {
- centry = sdbc_centry_alloc(cd, cblk, request_blocks,
- &stall, &alloc_tok, ALLOC_NOWAIT);
-
- if (centry == NULL) {
- /*
- * prefetch: cache is very busy. just do
- * the i/o for the blocks already acquired,
- * if any.
- */
- fba_orig_len -= fba_len;
- fba_len = 0;
- /*
- * if we have a chain of centry's
- * then back up (set centry to lentry).
- * if there is no chain (ioent == NULL)
- * then centry remains NULL. this can occur
- * if all previous centrys were hash hits
- * on valid blocks that were processed in
- * the skip logic above.
- */
- if (ioent)
- centry = lentry; /* backup */
- break;
- }
-
- /*
- * dmchaining adjustment.
- * if centry was obtained from the dmchain
- * then clear local pageio variable because the
- * centry already has cc_pageio set.
- */
- if (CENTRY_PAGEIO(centry))
- pageio = 0;
-
- DTRACE_PROBE1(_sd_alloc_buf, _sd_cctl_t *, centry);
-
- this_entry_type = ELIGIBLE_ENTRY_DM;
- if (centry->cc_aging_dm & FOUND_IN_HASH_DM)
- this_entry_type = HASH_ENTRY_DM;
- else {
- if (centry->cc_aging_dm & FOUND_HOLD_OVER_DM)
- this_entry_type = HOLD_ENTRY_DM;
- }
- }
-
- centry->cc_chain = NULL;
-
- centry->cc_aging_dm &= ~(FOUND_IN_HASH_DM|FOUND_HOLD_OVER_DM);
-
- /*
- * Do pagelist io mutual exclusion now if we did not do
- * it above.
- */
-
- if (pageio && SET_CENTRY_PAGEIO(centry)) {
- /* flusher not done with pageio */
- sdbc_prefetch_pageio2++;
-
- /*
- * prefetch: skip leading busy
- * or truncate at busy block
- */
- CLEAR_CENTRY_INUSE(centry);
- if (ioent == NULL)
- goto skip;
- sdbc_prefetch_busy_cnt++;
- fba_orig_len -= fba_len;
- fba_len = 0;
- centry = lentry; /* backup */
- break;
- }
-
- pageio = 0;
-
- fba_len -= st_cblk_len;
-
- if (ioent == NULL) {
- if (!SDBC_VALID_BITS(st_cblk_off, st_cblk_len,
- centry)) {
- io_pos = BLK_TO_FBA_NUM(cblk) + st_cblk_off;
- ioent = last_ioent = centry;
- } else {
- DATA_LOG(SDF_ALLOC, centry, st_cblk_off,
- st_cblk_len);
- DTRACE_PROBE4(_sd_prefetch_buf_data1,
- uint64_t, (uint64_t)(BLK_TO_FBA_NUM(cblk) +
- st_cblk_off), int, st_cblk_len,
- char *, *(int64_t *)(centry->cc_data +
- FBA_SIZE(st_cblk_off)), char *,
- *(int64_t *)(centry->cc_data +
- FBA_SIZE(st_cblk_off + st_cblk_len) - 8));
- }
-
- handle->bh_centry = centry;
- st_cblk_off = 0;
- st_cblk_len = (sdbc_cblk_fba_t)
- ((fba_len > (nsc_size_t)BLK_FBAS) ?
- BLK_FBAS : fba_len);
- } else {
- if (!SDBC_VALID_BITS(st_cblk_off, st_cblk_len, centry))
- last_ioent = centry;
- else {
- DTRACE_PROBE4(_sd_prefetch_buf_data2,
- uint64_t, (uint64_t)(BLK_TO_FBA_NUM(cblk) +
- st_cblk_off), int, st_cblk_len,
- char *, *(int64_t *)(centry->cc_data +
- FBA_SIZE(st_cblk_off)), char *,
- *(int64_t *)(centry->cc_data +
- FBA_SIZE(st_cblk_off + st_cblk_len) - 8));
- }
-
- lentry->cc_chain = centry;
- if (fba_len < (nsc_size_t)BLK_FBAS)
- st_cblk_len = (sdbc_cblk_fba_t)fba_len;
- }
- lentry = centry;
- cblk++;
-
- /* if this block has a new identity clear prefetch history */
- if (this_entry_type != HASH_ENTRY_DM)
- centry->cc_aging_dm &=
- ~(PREFETCH_BUF_I | PREFETCH_BUF_E);
-
- centry->cc_aging_dm &= ~(ENTRY_FIELD_DM);
- centry->cc_aging_dm |= this_entry_type | PREFETCH_BUF_E;
- if (flag & NSC_METADATA)
- centry->cc_aging_dm |= STICKY_METADATA_DM;
-
- --request_blocks;
- } while (fba_len > 0);
-
-
- if (locked) {
- rw_exit(&sdbc_queue_lock);
- locked = 0;
- }
-
- sdbc_centry_alloc_end(&alloc_tok);
-
- if (centry) {
- centry->cc_chain = NULL;
- if (sts = _sd_setup_category_on_type(handle->bh_centry)) {
- (void) _sd_free_buf(handle);
- goto done;
- }
-
- (void) _sd_setup_mem_chaining(handle->bh_centry, 0);
- }
-
-
- if (ioent) {
- /* prefetch: trailing valid can be released, adjust len */
- if ((centry != last_ioent)) {
- centry = last_ioent->cc_chain;
- last_ioent->cc_chain = NULL;
- while (centry) {
- lentry = centry->cc_chain;
- centry->cc_aging_dm &= ~PREFETCH_BUF_E;
- _sd_centry_release(centry);
- centry = lentry;
- sdbc_prefetch_trailing++;
- }
- fba_len = (CENTRY_BLK(last_ioent) -
- CENTRY_BLK(ioent) + 1) * BLK_FBAS -
- BLK_FBA_OFF(io_pos);
- fba_orig_len = fba_len + (io_pos - fba_pos);
- }
-
- _SD_DISCONNECT_CALLBACK(handle);
- sts = _sd_doread(handle, ioent, io_pos,
- (fba_pos + fba_orig_len - io_pos), flag);
- if (sts > 0)
- (void) _sd_free_buf(handle);
- } else {
- CACHE_FBA_READ(cd, fba_orig_len);
- CACHE_READ_HIT;
- FBA_READ_IO_KSTATS(cd, FBA_SIZE(fba_orig_len));
-
- sts = NSC_HIT;
- }
-done:
- if (locked)
- rw_exit(&sdbc_queue_lock);
-
- return (sts);
-}
-
-
-/*
- * _sd_cc_wait - wait for inuse cache block to become available
- * Usage:
- * if (SET_CENTRY_INUSE(centry)) {
- * _sd_cc_wait(cd, blk, centry, CC_INUSE);
- * goto try_again;
- * }
- * -or-
- * if (SET_CENTRY_PAGEIO(centry)) {
- * _sd_cc_wait(cd, blk, centry, CC_PAGEIO);
- * goto try_again;
- * }
- */
-void
-_sd_cc_wait(int cd, nsc_off_t cblk, _sd_cctl_t *centry, int flag)
-{
- volatile ushort_t *waiters;
- volatile uchar_t *uflag;
-
- if (flag == CC_INUSE) {
- waiters = &(centry->cc_await_use);
- uflag = &(CENTRY_INUSE(centry));
- } else if (flag == CC_PAGEIO) {
- waiters = &(centry->cc_await_page);
- uflag = &(CENTRY_PAGEIO(centry));
- } else {
- /* Oops! */
-#ifdef DEBUG
- cmn_err(CE_WARN, "!_sd_cc_wait: unknown flag value (%x)", flag);
-#endif
- return;
- }
-
- mutex_enter(&centry->cc_lock);
- if (CC_CD_BLK_MATCH(cd, cblk, centry) && (*uflag) != 0) {
- (*waiters)++;
- sd_serialize();
- if ((*uflag) != 0) {
- unsigned stime = nsc_usec();
- cv_wait(&centry->cc_blkcv, &centry->cc_lock);
- (*waiters)--;
- mutex_exit(&centry->cc_lock);
- SDTRACE(ST_INFO|SDF_ENT_GET,
- cd, 0, BLK_TO_FBA_NUM(cblk), (nsc_usec()-stime), 0);
- } else {
- (*waiters)--;
- mutex_exit(&centry->cc_lock);
- }
- } else
- mutex_exit(&centry->cc_lock);
-
-}
-
-/*
- * _sd_alloc_buf - Allocate a vector of buffers for io.
- *
- * ARGUMENTS:
- * cd - Cache descriptor (from a previous open)
- * fba_pos - disk position (512-byte FBAs)
- * fba_len - length in disk FBAs.
- * flag - allocation type. Flag is one or more of
- * NSC_RDBUF, NSC_WRBUF, NSC_NOBLOCK and hints.
- * NSC_RDAHEAD - prefetch for future read.
- * handle_p - pointer to a handle pointer.
- * If the handle pointer is non-null, its used as a
- * pre-allocated handle. Else a new handle will be allocated
- * and stored in *handle_p
- *
- * RETURNS:
- * errno if return > 0.
- * else NSC_HIT or NSC_DONE on success
- * or NSC_PENDING on io in progress and NSC_NOBLOCK
- * specified in the flag.
- * USAGE:
- * This routine allocates the cache blocks requested and creates a list
- * of entries for this request.
- * If NSC_NOBLOCK was not specified, this call could block on read io.
- * If flag specified NSC_RDBUF and the request is not an entire
- * hit, an io is initiated.
- */
-int
-_sd_alloc_buf(blind_t xcd, nsc_off_t fba_pos, nsc_size_t fba_len, int flag,
- _sd_buf_handle_t **handle_p)
-{
- int cd = (int)(unsigned long)xcd;
- _sd_cd_info_t *cdi;
- _sd_buf_handle_t *handle;
- int sts;
- nsc_off_t st_cblk, cblk; /* position of start and temp cache block */
- sdbc_cblk_fba_t st_cblk_len; /* FBA len of starting cache block */
- sdbc_cblk_fba_t end_cblk_len; /* FBA len of ending cache block */
- sdbc_cblk_fba_t st_cblk_off; /* FBA offset into starting cblock */
- nsc_off_t io_pos; /* offset in FBA's */
- _sd_bufvec_t *bufvec;
- _sd_cctl_t *centry, *lentry, *ioent = NULL;
- nsc_size_t fba_orig_len = fba_len; /* FBA length of orig request */
- int stall, pageio;
- unsigned char cc_flag;
- int this_entry_type;
- int locked = 0;
- nsc_size_t dmchain_request_blocks; /* size of dmchain in cache blocks */
- sdbc_allocbuf_t alloc_tok = {0};
- int min_frag = 0; /* frag statistics */
- int max_frag = 0; /* frag statistics */
- int nfrags = 0; /* frag statistics */
-#ifdef DEBUG
- int err = 0;
-#endif
-
-
- ASSERT(*handle_p != NULL);
- handle = *handle_p;
-
- if (_sdbc_shutdown_in_progress)
- return (EIO);
-
- if (xcd == NSC_ANON_CD)
- cd = _CD_NOHASH;
-
- KSTAT_RUNQ_ENTER(cd);
-
- /*
- * Force large writes on nvram systems to be write-through to
- * avoid the (slow) bcopy into nvram.
- */
-
- if (flag & NSC_WRBUF) {
- if (fba_len > (nsc_size_t)sdbc_wrthru_len) {
- flag |= NSC_WRTHRU;
- }
- }
-
-#ifdef DEBUG
- if (sdbc_pageio_debug != SDBC_PAGEIO_OFF) {
- switch (sdbc_pageio_debug) {
- case SDBC_PAGEIO_RDEV:
- if (cd != _CD_NOHASH &&
- sdbc_pageio_rdev != (dev_t)-1 &&
- _sd_cache_files[cd].cd_crdev == sdbc_pageio_rdev)
- flag |= NSC_PAGEIO;
- break;
-
- case SDBC_PAGEIO_RAND:
- if ((nsc_lbolt() % 3) == 0)
- flag |= NSC_PAGEIO;
- break;
-
- case SDBC_PAGEIO_ALL:
- flag |= NSC_PAGEIO;
- break;
- }
- }
-#endif /* DEBUG */
-
- if (fba_len > (nsc_size_t)BLK_FBAS) {
- rw_enter(&sdbc_queue_lock, RW_WRITER);
- locked = 1;
- }
-
- /*
- * _CD_NOHASH: client wants temporary (not hashed) cache memory
- * not associated with a local disk. Skip local disk checks.
- */
- if (cd == _CD_NOHASH) {
- flag &= ~(NSC_RDBUF | NSC_WRBUF | NSC_RDAHEAD);
- handle = *handle_p;
- handle->bh_flag |= NSC_HACTIVE;
- goto setup;
- }
-
- SDTRACE(ST_ENTER|SDF_ALLOCBUF, cd, fba_len, fba_pos, flag, 0);
-
-
- if ((flag & NSC_RDAHEAD) && _sd_prefetch_opt) {
- sts = _sd_prefetch_buf(cd, fba_pos, fba_len, flag, handle,
- locked);
- goto done;
- }
-
-#if !defined(_SD_NOCHECKS)
- if (flag & NSC_RDAHEAD) { /* _sd_prefetch_opt == 0 */
- nsc_size_t file_size; /* file_size in FBA's */
- /* prefetch: truncate if req'd */
- if (fba_len > sdbc_max_fbas)
- fba_len = sdbc_max_fbas;
- file_size = _sd_cache_files[(cd)].cd_info->sh_filesize;
- if ((fba_pos + fba_len) > file_size) {
- fba_len = file_size - fba_pos;
-#ifdef NSC_MULTI_TERABYTE
- if ((int64_t)fba_len <= 0) {
-#else
- if ((int32_t)fba_len <= 0) {
-#endif
- sts = EIO;
- SDTRACE(ST_EXIT|SDF_ALLOCBUF, cd, fba_len,
- fba_pos, flag, sts);
- goto done;
- }
- }
- } else
- if (sts = _sd_check_buffer_alloc(cd, fba_pos, fba_len, handle_p)) {
- SDTRACE(ST_EXIT|SDF_ALLOCBUF, cd, fba_len, fba_pos, flag, sts);
- goto done;
- }
-#endif
- if (fba_len == 0) {
- SDTRACE(ST_EXIT|SDF_ALLOCBUF, cd, fba_len, fba_pos,
- flag, EINVAL);
- sts = EINVAL;
- goto done;
- }
-
- handle->bh_flag |= NSC_HACTIVE;
- cdi = &_sd_cache_files[cd];
-
- if (cdi->cd_recovering) {
- /*
- * If recovering this device, then block all allocates
- * for reading or writing. If we allow reads then
- * this path could see old data before we recover.
- * If we allow writes then new data could be overwritten
- * by old data.
- * This is clearly still not a complete solution as
- * the thread doing this allocate could conceivably be
- * by this point (and in _sd_write/_sd_read for that matter
- * which don't even have this protection). But this type
- * of path seems to only exist in a failover situation
- * where a device has failed on the other node and works
- * on this node so the problem is not a huge one but exists
- * never the less.
- */
- if (sts = _sd_recovery_wblk_wait(cd)) {
- handle->bh_flag &= ~NSC_HACTIVE;
- SDTRACE(ST_EXIT|SDF_ALLOCBUF, cd, fba_len, fba_pos,
- flag, sts);
- goto done;
- }
- }
-
- /* write & disk failed, return error immediately */
- if ((flag & NSC_WRBUF) && cdi->cd_info->sh_failed) {
- handle->bh_flag &= ~NSC_HACTIVE;
- SDTRACE(ST_EXIT|SDF_ALLOCBUF, cd, fba_len, fba_pos, flag, EIO);
- sts = EIO;
- goto done;
- }
-
-setup:
-
- _SD_SETUP_HANDLE(handle, cd, fba_pos, fba_len, flag);
- handle->bh_centry = NULL;
- bufvec = handle->bh_bufvec;
- if (flag & NSC_RDAHEAD) { /* _sd_prefetch_opt == 0 */
- /* CKD prefetch: bufvec not req'd, use placeholder */
- bufvec->bufaddr = NULL;
- bufvec->bufvmeaddr = NULL;
- bufvec->buflen = 0;
- bufvec = _prefetch_sb_vec;
- }
- st_cblk = FBA_TO_BLK_NUM(fba_pos);
- st_cblk_off = BLK_FBA_OFF(fba_pos);
- st_cblk_len = BLK_FBAS - st_cblk_off;
- if ((nsc_size_t)st_cblk_len >= fba_len) {
- end_cblk_len = 0;
- st_cblk_len = (sdbc_cblk_fba_t)fba_len;
- } else
- end_cblk_len = BLK_FBA_OFF(fba_pos + fba_len);
- cblk = st_cblk;
-
-
- /*
- * count number of blocks on chain that is required
- */
-
- /* middle piece */
- dmchain_request_blocks =
- (fba_len - (st_cblk_len + end_cblk_len)) >> BLK_FBA_SHFT;
-
- /* start piece */
- ++dmchain_request_blocks;
-
- /* end piece */
- if (end_cblk_len)
- ++dmchain_request_blocks;
-
-
- cc_flag = 0;
- if ((handle->bh_flag & NSC_PINNABLE) && (handle->bh_flag & NSC_WRBUF))
- cc_flag |= CC_PINNABLE;
- if (handle->bh_flag & (NSC_NOCACHE|NSC_SEQ_IO))
- cc_flag |= CC_QHEAD;
- lentry = NULL;
- stall = 0;
-
- do {
- pageio = ((flag & NSC_PAGEIO) != 0 || sdbc_pageio_always != 0);
-cget:
- if ((centry = (_sd_cctl_t *)
- _sd_hash_search(cd, cblk, _sd_htable)) != 0) {
-
- if (SET_CENTRY_INUSE(centry)) {
- /* already inuse: wait for block, retry */
- sdbc_allocb_inuse++;
- if (locked)
- rw_exit(&sdbc_queue_lock);
- _sd_cc_wait(cd, cblk, centry, CC_INUSE);
- if (locked)
- rw_enter(&sdbc_queue_lock, RW_WRITER);
- goto cget;
- }
-
- /*
- * bug 4529671
- * now that we own the centry make sure that
- * it is still good. it could have been processed
- * by _sd_dealloc_dm() in the window between
- * _sd_hash_search() and SET_CENTRY_INUSE().
- */
- if ((_sd_cctl_t *)
- _sd_hash_search(cd, cblk, _sd_htable) != centry) {
- sdbc_allocb_deallocd++;
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!centry %p cd %d cblk %" NSC_SZFMT
- " fba_len %" NSC_SZFMT " lost to dealloc?! "
- "cc_data %p", (void *)centry, cd, cblk,
- fba_orig_len, (void *)centry->cc_data);
-#endif
-
- CLEAR_CENTRY_INUSE(centry);
- goto cget;
- }
-
- if (CC_CD_BLK_MATCH(cd, cblk, centry)) {
- /*
- * Do pagelist io mutual exclusion
- * before messing with the centry.
- */
- if (pageio && SET_CENTRY_PAGEIO(centry)) {
- /* wait for flusher to finish pageio */
- sdbc_allocb_pageio1++;
-
- CLEAR_CENTRY_INUSE(centry);
- if (locked)
- rw_exit(&sdbc_queue_lock);
- _sd_cc_wait(cd, cblk, centry,
- CC_PAGEIO);
- if (locked)
- rw_enter(&sdbc_queue_lock,
- RW_WRITER);
- goto cget;
- }
-
- sdbc_allocb_hit++;
- this_entry_type = HASH_ENTRY_DM;
- pageio = 0;
- centry->cc_toflush = 0;
-
- centry->cc_hits++;
-
- /* this will reset the age flag */
- sdbc_centry_init_dm(centry);
-
- DTRACE_PROBE1(_sd_alloc_buf1,
- _sd_cctl_t *, centry);
- } else {
- /* block mismatch: release, alloc new block */
- sdbc_allocb_lost++;
-
- CLEAR_CENTRY_INUSE(centry);
-
- goto cget;
-
- }
- } else {
- centry = sdbc_centry_alloc(cd, cblk,
- dmchain_request_blocks, &stall,
- &alloc_tok, locked ? ALLOC_LOCKED : 0);
-
- /*
- * dmchaining adjustment.
- * if centry was obtained from the dmchain
- * then clear local pageio variable because the
- * centry already has cc_pageio set.
- */
- if (CENTRY_PAGEIO(centry))
- pageio = 0;
-
- DTRACE_PROBE1(_sd_alloc_buf2, _sd_cctl_t *, centry);
-
- this_entry_type = ELIGIBLE_ENTRY_DM;
- if (centry->cc_aging_dm & FOUND_IN_HASH_DM)
- this_entry_type = HASH_ENTRY_DM;
- else {
- if (centry->cc_aging_dm & FOUND_HOLD_OVER_DM)
- this_entry_type = HOLD_ENTRY_DM;
- }
- }
-
- centry->cc_aging_dm &= ~(FOUND_IN_HASH_DM|FOUND_HOLD_OVER_DM);
-
- /*
- * Do pagelist io mutual exclusion now if we did not do
- * it above.
- */
-
- if (pageio && SET_CENTRY_PAGEIO(centry)) {
- /* wait for flusher to finish pageio */
- sdbc_allocb_pageio2++;
-
-
- CLEAR_CENTRY_INUSE(centry);
- if (locked)
- rw_exit(&sdbc_queue_lock);
- _sd_cc_wait(cd, cblk, centry, CC_PAGEIO);
- if (locked)
- rw_enter(&sdbc_queue_lock, RW_WRITER);
- goto cget;
- }
-
- pageio = 0;
-
- if (CENTRY_DIRTY(centry)) {
- /*
- * end action might set PEND_DIRTY flag
- * must lock if need to change flag bits
- */
- if (centry->cc_flag != (centry->cc_flag | cc_flag)) {
- /* was FAST */
- mutex_enter(&centry->cc_lock);
- centry->cc_flag |= cc_flag;
- /* was FAST */
- mutex_exit(&centry->cc_lock);
- }
- } else
- centry->cc_flag |= cc_flag;
-
- centry->cc_chain = NULL;
-
- /*
- * step 0:check valid bits in each cache ele as
- * the chain grows - set ioent/io_pos to first
- * instance of invalid data
- */
- if (cblk == st_cblk) {
- handle->bh_centry = centry;
- fba_len -= st_cblk_len;
- lentry = centry;
- if (flag & NSC_RDBUF) {
- if (!SDBC_VALID_BITS(st_cblk_off, st_cblk_len,
- centry)) {
- io_pos = fba_pos;
- ioent = centry;
- } else {
- DATA_LOG(SDF_ALLOC, centry, st_cblk_off,
- st_cblk_len);
-
- DTRACE_PROBE4(_sd_alloc_data1,
- uint64_t, (uint64_t)
- (BLK_TO_FBA_NUM(cblk) +
- st_cblk_off), int, st_cblk_len,
- char *, *(int64_t *)
- (centry->cc_data +
- FBA_SIZE(st_cblk_off)),
- char *, *(int64_t *)
- (centry->cc_data +
- FBA_SIZE(st_cblk_off + st_cblk_len)
- - 8));
- }
- }
- cblk++;
- } else if (fba_len == (nsc_size_t)end_cblk_len) {
- lentry->cc_chain = centry;
- fba_len -= end_cblk_len;
- if (flag & NSC_RDBUF) {
- if (ioent == NULL) {
- if (!SDBC_VALID_BITS(0, end_cblk_len,
- centry)) {
- io_pos = BLK_TO_FBA_NUM(cblk);
- ioent = centry;
- } else {
- DATA_LOG(SDF_ALLOC, centry, 0,
- end_cblk_len);
-
- DTRACE_PROBE4(_sd_alloc_data2,
- uint64_t,
- BLK_TO_FBA_NUM(cblk),
- int, end_cblk_len,
- char *, *(int64_t *)
- (centry->cc_data),
- char *, *(int64_t *)
- (centry->cc_data +
- FBA_SIZE(end_cblk_len)
- - 8));
- }
- }
- }
- } else {
- lentry->cc_chain = centry;
- lentry = centry;
- fba_len -= BLK_FBAS;
- if (flag & NSC_RDBUF) {
- if (ioent == NULL) {
- if (!FULLY_VALID(centry)) {
- io_pos = BLK_TO_FBA_NUM(cblk);
- ioent = centry;
- } else {
- DATA_LOG(SDF_ALLOC, centry, 0,
- BLK_FBAS);
-
- DTRACE_PROBE4(_sd_alloc_data3,
- uint64_t, (uint64_t)
- BLK_TO_FBA_NUM(cblk),
- int, BLK_FBAS,
- char *, *(int64_t *)
- (centry->cc_data),
- char *, *(int64_t *)
- (centry->cc_data +
- FBA_SIZE(BLK_FBAS) - 8));
- }
- }
- }
- cblk++;
- }
-
- /* if this block has a new identity clear prefetch history */
- if (this_entry_type != HASH_ENTRY_DM)
- centry->cc_aging_dm &=
- ~(PREFETCH_BUF_I | PREFETCH_BUF_E);
-
- centry->cc_aging_dm &= ~(ENTRY_FIELD_DM);
- centry->cc_aging_dm |= this_entry_type;
- if (flag & NSC_METADATA)
- centry->cc_aging_dm |= STICKY_METADATA_DM;
-
- --dmchain_request_blocks;
- } while (fba_len);
-
- if (locked) {
- rw_exit(&sdbc_queue_lock);
- locked = 0;
- }
-
- ASSERT(dmchain_request_blocks == 0);
-
- /*
- * do any necessary cleanup now that all the blocks are allocated.
- */
- sdbc_centry_alloc_end(&alloc_tok);
-
- /* be sure you nul term. the chain */
- centry->cc_chain = NULL;
-
- /*
- * step one: establish HOST/PARASITE/OTHER relationships
- * between the centry ele in the list and calc the alloc size
- * (fill in CATAGORY based on TYPE and immediate neighbors)
- */
- if (sts = _sd_setup_category_on_type(handle->bh_centry)) {
-#ifdef DEBUG
- err = _sd_free_buf(handle);
- if (err) {
- cmn_err(CE_WARN, "!sdbc(_sd_alloc_buf): _sd_free_buf "
- "failed: err:%d handle:%p", err, (void *)handle);
- }
-#else
- (void) _sd_free_buf(handle);
-#endif
- goto done;
- }
-
- /*
- * step two: alloc the needed mem and fill in the data and chaining
- * fields (leave bufvec for step three)
- */
- (void) _sd_setup_mem_chaining(handle->bh_centry, 0);
-
- /*
- * step three: do the bufvec
- */
- fba_len = fba_orig_len;
- centry = handle->bh_centry;
- bufvec = handle->bh_bufvec;
-
- while (centry) {
- DTRACE_PROBE3(_sd_alloc_buf_centrys, _sd_cctl_t *, centry,
- int, cd, uint64_t,
- (uint64_t)BLK_TO_FBA_NUM(CENTRY_BLK(centry)));
-
- if (fba_len == fba_orig_len) {
- bufvec->bufaddr = (centry->cc_data +
- FBA_SIZE(st_cblk_off));
- bufvec->bufvmeaddr = 0; /* not used */
- bufvec->buflen = FBA_SIZE(st_cblk_len);
- bufvec++;
- fba_len -= st_cblk_len;
- } else if (fba_len == (nsc_size_t)end_cblk_len) {
- _sd_bufvec_t *pbufvec = bufvec - 1;
-
- if ((pbufvec->bufaddr + pbufvec->buflen) ==
- centry->cc_data) {
- /* contiguous */
- pbufvec->buflen += FBA_SIZE(end_cblk_len);
- } else {
-
- bufvec->bufaddr = centry->cc_data;
- bufvec->bufvmeaddr = 0; /* not used */
- bufvec->buflen = FBA_SIZE(end_cblk_len);
- bufvec++;
- }
-
- fba_len -= end_cblk_len;
- } else {
- _sd_bufvec_t *pbufvec = bufvec - 1;
-
- if ((pbufvec->bufaddr + pbufvec->buflen) ==
- centry->cc_data) {
- /* contiguous */
- pbufvec->buflen += CACHE_BLOCK_SIZE;
- } else {
-
- bufvec->bufaddr = centry->cc_data;
- bufvec->bufvmeaddr = 0; /* not used */
- bufvec->buflen = CACHE_BLOCK_SIZE;
- bufvec++;
- }
-
- fba_len -= BLK_FBAS;
- }
-
- centry = centry->cc_chain;
- }
-
- /* be sure you nul term. the chain */
- bufvec->bufaddr = NULL;
- bufvec->bufvmeaddr = 0;
- bufvec->buflen = 0;
-
- /* frag statistics */
- {
- _sd_bufvec_t *tbufvec;
-
- for (tbufvec = handle->bh_bufvec; tbufvec != bufvec;
- ++tbufvec) {
- if ((min_frag > tbufvec->buflen) || (min_frag == 0))
- min_frag = tbufvec->buflen;
-
- if (max_frag < tbufvec->buflen)
- max_frag = tbufvec->buflen;
- }
-
- nfrags = bufvec - handle->bh_bufvec;
- min_frag = FBA_LEN(min_frag);
- max_frag = FBA_LEN(max_frag);
- }
-
- /* buffer memory frag stats */
- DTRACE_PROBE4(_sd_alloc_buf_frag, uint64_t, (uint64_t)fba_orig_len,
- int, nfrags, int, min_frag, int, max_frag);
-
-
- if (flag & NSC_WRBUF) {
- if (_SD_IS_WRTHRU(handle))
- goto alloc_done;
- if (_sd_alloc_write(handle->bh_centry, &stall)) {
- _sd_unblock(&_sd_flush_cv);
- handle->bh_flag |= NSC_FORCED_WRTHRU;
- } else {
- for (centry = handle->bh_centry;
- centry; centry = centry->cc_chain) {
-
- CENTRY_SET_FTPOS(centry);
- SSOP_SETCENTRY(sdbc_safestore,
- centry->cc_write);
- }
- }
- }
-
-alloc_done:
- if (locked) {
- rw_exit(&sdbc_queue_lock);
- locked = 0;
- }
- if (ioent) {
- _SD_DISCONNECT_CALLBACK(handle);
- sts = _sd_doread(handle, ioent, io_pos,
- (fba_pos + fba_orig_len - io_pos), flag);
- if (sts > 0)
- (void) _sd_free_buf(handle);
- } else
- if (flag & NSC_RDBUF) {
- CACHE_FBA_READ(cd, fba_orig_len);
- CACHE_READ_HIT;
- FBA_READ_IO_KSTATS(cd, FBA_SIZE(fba_orig_len));
-
- sts = NSC_HIT;
- } else
- sts = (stall) ? NSC_DONE : NSC_HIT;
-
- SDTRACE(ST_EXIT|SDF_ALLOCBUF, cd, fba_orig_len, fba_pos, flag, sts);
-
-done:
- if (locked)
- rw_exit(&sdbc_queue_lock);
-
- KSTAT_RUNQ_EXIT(cd);
-
- return (sts);
-}
-
-/*
- * consistency checking for ccents
- */
-
-#define ELIGIBLE(p) (p & ELIGIBLE_ENTRY_DM)
-#define HOLD(p) (p & HOLD_ENTRY_DM)
-#define HASHE(p) (p & HASH_ENTRY_DM)
-
-#define HOST(p) (p & HOST_ENTRY_DM)
-#define PARA(p) (p & PARASITIC_ENTRY_DM)
-#define OTHER(p) \
- (!(p & (HOST_ENTRY_DM | PARASITIC_ENTRY_DM | ELIGIBLE_ENTRY_DM)))
-
-#define AVAIL(p) (p & AVAIL_ENTRY_DM)
-
-/*
- * sdbc_check_cctl_cot -- consistency check for _sd_setup_category_on_type()
- * may only be called on entry to state machine (when ccent is either
- * ELIGIBLE_ENTRY_DM, HOLD_ENTRY_DM or HASH_ENTRY_DM).
- *
- * print message or panic (DEBUG) if inconsistency detected.
- */
-static int
-sdbc_check_cctl_cot(_sd_cctl_t *centry)
-{
- uint_t age;
- int size;
- uchar_t *data;
- int host_or_other;
- int para;
- int ccent_ok = 1;
-
- age = centry->cc_aging_dm;
- size = centry->cc_alloc_size_dm;
- data = centry->cc_data;
- host_or_other = size && data;
- para = !size && data;
-
- /*
- * on entry to _sd_setup_category_on_type(),
- * one of three mutually exclusive entry field bits must be set
- */
-
- switch ((age & (ELIGIBLE_ENTRY_DM | HOLD_ENTRY_DM | HASH_ENTRY_DM))) {
- case ELIGIBLE_ENTRY_DM:
- case HOLD_ENTRY_DM:
- case HASH_ENTRY_DM:
- /* ok */
- break;
- default:
- /* zero or multiple flag bits */
- ccent_ok = 0;
- break;
- }
-
- /* categories are mutually exclusive */
- if (HOST(age) && PARA(age))
- ccent_ok = 0;
-
- /* these bits should be cleared out (STICKY_METADATA_DM not used) */
- if (age & (AVAIL_ENTRY_DM | FOUND_HOLD_OVER_DM | FOUND_IN_HASH_DM |
- STICKY_METADATA_DM))
- ccent_ok = 0;
-
- /* eligible has no data and no size */
- if (ELIGIBLE(age) && (size || data))
- ccent_ok = 0;
-
- /* parasite has zero size and non-zero data */
- if (PARA(age) && !para)
- ccent_ok = 0;
-
- /* host has non-zero size and non-zero data */
- if (HOST(age) && !host_or_other)
- ccent_ok = 0;
-
- /* "other" is just like a host */
- if (OTHER(age) && !host_or_other)
- ccent_ok = 0;
-
- /* a HOLD or a HASH must have a size */
- if ((size) && !(age & (HASH_ENTRY_DM | HOLD_ENTRY_DM)))
- ccent_ok = 0;
-
- if (!ccent_ok)
- cmn_err(cmn_level,
- "!sdbc(sdbc_check_cctl_cot): inconsistent ccent %p "
- "age %x size %d data %p", (void *)centry, age, size,
- (void *)data);
-
- return (ccent_ok);
-}
-
-/*
- * sdbc_mark_cctl_cot -- mark cctls bad and invalidate when
- * inconsistency found in _sd_setup_category_on_type()
- * returns nothing
- *
- * Note: this is an error recovery path that is triggered when an
- * inconsistency in a cctl is detected. _sd_centry_release() will take
- * these cache entries out of circulation and place them on a separate list
- * for debugging purposes.
- */
-void
-sdbc_mark_cctl_cot(_sd_cctl_t *header, _sd_cctl_t *centry)
-{
- _sd_cctl_t *cur_ent = header;
-
- /* the entire chain is guilty by association */
- while (cur_ent) {
-
- (void) _sd_hash_delete((struct _sd_hash_hd *)cur_ent,
- _sd_htable);
-
- cur_ent->cc_aging_dm |= BAD_CHAIN_DM;
-
- cur_ent = cur_ent->cc_chain;
- }
-
- centry->cc_aging_dm |= BAD_ENTRY_DM; /* this is the problem child */
-}
-
-/*
- * _sd_setup_category_on_type(_sd_cctl_t *) - Setup the centry CATEGORY based on
- * centry TYPE and immediate neighbors. Identify each eligible (ie not HASH)
- * centry as a host/parasite. host actually have memory allocated to
- * them and parasites are chained to the host and point to page offsets within
- * the host's memory.
- *
- * RETURNS:
- * 0 on success, EINTR if inconsistency detected in centry
- *
- * Note:
- * none
- */
-static int
-_sd_setup_category_on_type(_sd_cctl_t *header)
-{
- _sd_cctl_t *prev_ent, *next_ent, *centry;
- _sd_cctl_t *anchor = NULL;
- int current_pest_count, local_max_dyn_list;
- int cl;
- int ret = 0;
-
- ASSERT(header);
-
- if (sdbc_use_dmchain)
- local_max_dyn_list = max_dm_queues - 1;
- else {
- /* pickup a fresh copy - has the world changed */
- local_max_dyn_list = dynmem_processing_dm.max_dyn_list;
- }
-
- prev_ent = 0;
- centry = header;
- next_ent = centry->cc_chain;
- current_pest_count = 0;
- cl = 2;
-
- /* try to recover from bad cctl */
- if (sdbc_check_cot && !sdbc_check_cctl_cot(centry))
- ret = EINTR;
-
- while (cl && (ret == 0)) {
- switch (cl) {
- case (1): /* chain to next/monitor for completion */
- prev_ent = centry;
- centry = next_ent;
- next_ent = 0;
- cl = 0;
- if (centry) {
-
- if (sdbc_check_cot &&
- !sdbc_check_cctl_cot(centry)) {
- ret = EINTR;
- break;
- }
-
- next_ent = centry->cc_chain;
- cl = 2;
- }
- break;
-
- case (2): /* vector to appropriate routine */
- if (!(centry->cc_aging_dm & ELIGIBLE_ENTRY_DM))
- cl = 5;
- else if (prev_ent && (prev_ent->cc_aging_dm &
- ELIGIBLE_ENTRY_DM))
- cl = 15;
- else
- cl = 10;
- break;
-
- case (5): /* process NON-ELIGIBLE entries */
- if (!(centry->cc_aging_dm &
- (HASH_ENTRY_DM|HOLD_ENTRY_DM))) {
- /* no catagory */
-
- /* consistency check */
- if (centry->cc_alloc_size_dm ||
- centry->cc_data) {
- cmn_err(cmn_level,
- "!sdbc(setup_cot): "
- "OTHER with data/size %p",
- (void *)centry);
-
- ret = EINTR;
- break;
- }
-
- centry->cc_aging_dm &=
- ~CATAGORY_ENTRY_DM;
- centry->cc_alloc_size_dm = BLK_SIZE(1);
- DTRACE_PROBE1(_sd_setup_category,
- _sd_cctl_t *, centry);
- }
- cl = 1;
- break;
-
- /*
- * no prev entry (ie top of list) or no prev
- * ELIGIBLE entry
- */
- case (10):
- /*
- * this is an eligible entry, does it start
- * a list or is it a loner
- */
- /* consistency check */
- if (centry->cc_alloc_size_dm ||
- centry->cc_data) {
- cmn_err(cmn_level, "!sdbc(setup_cot): "
- "HOST with data/size %p",
- (void *)centry);
- ret = EINTR;
- break;
- }
-
- if (next_ent && (next_ent->cc_aging_dm &
- ELIGIBLE_ENTRY_DM)) {
-
-
- /* it starts a list */
- /* host catagory */
- centry->cc_aging_dm |= HOST_ENTRY_DM;
- /* start out with one page */
- centry->cc_alloc_size_dm = BLK_SIZE(1);
- anchor = centry;
- DTRACE_PROBE1(_sd_setup_category,
- _sd_cctl_t *, anchor);
- cl = 1;
- } else {
- /*
- * it's a loner
- * drop status to no category and
- * restart
- */
- cl = 2;
- centry->cc_aging_dm &=
- ~ELIGIBLE_ENTRY_DM;
- }
- break;
-
- case (15): /* default to parasite catagory */
-
- /* consistency check */
- if (centry->cc_alloc_size_dm ||
- centry->cc_data) {
- cmn_err(cmn_level, "!sdbc(setup_cot): "
- "PARA with data/size %p",
- (void *)centry);
-
- ret = EINTR;
- break;
- }
-
- if (current_pest_count < local_max_dyn_list-1) {
- /* continue to grow the pest list */
- current_pest_count++;
- centry->cc_aging_dm |=
- PARASITIC_ENTRY_DM;
-
- /*
- * offset of host ent mem this will pt
- * to
- */
- centry->cc_alloc_size_dm =
- anchor->cc_alloc_size_dm;
- /*
- * up the host mem req by one for
- * this parasite
- */
- DTRACE_PROBE1(_sd_setup_category,
- _sd_cctl_t *, centry);
-
- anchor->cc_alloc_size_dm += BLK_SIZE(1);
-
- cl = 1;
- } else {
- /*
- * term this pest list - restart fresh
- * on this entry
- */
- current_pest_count = 0;
- prev_ent->cc_aging_dm &=
- ~(HOST_ENTRY_DM|ELIGIBLE_ENTRY_DM);
- cl = 2;
- }
- break;
- } /* switch(cl) */
- } /* while (cl) */
-
- if (ret != 0)
- sdbc_mark_cctl_cot(header, centry);
-
- return (ret);
-}
-
-/*
- * _sd_setup_mem_chaining(_sd_cctl_t *) - Allocate memory, setup
- * mem ptrs an host/pest chaining. Do the actual allocation as described in
- * sd_setup_category_on_type().
- *
- * RETURNS:
- * 0 on success
- * non-zero on error
- *
- * Note:
- * if called with ALLOC_NOWAIT, caller must check for non-zero return
- */
-static int
-_sd_setup_mem_chaining(_sd_cctl_t *header, int flag)
-{
- _sd_cctl_t *prev_ent, *next_ent, *centry;
- _sd_cctl_t *anchor = NULL;
- int cl, rc = 0;
-
- ASSERT(header);
-
- if (!header)
- return (0);
-
- prev_ent = 0;
- centry = header;
- next_ent = centry->cc_chain;
- cl = 2;
- while (cl) {
- switch (cl) {
- case (1): /* chain to next/monitor for completion */
- centry->cc_aging_dm &= ~ELIGIBLE_ENTRY_DM;
- prev_ent = centry;
- centry = next_ent;
- next_ent = 0;
- cl = 0;
- if (centry) {
- next_ent = centry->cc_chain;
- cl = 2;
- }
- break;
-
- case (2): /* vector to appropriate routine */
- if (centry->cc_aging_dm & HOST_ENTRY_DM)
- cl = 10;
- else if (centry->cc_aging_dm &
- PARASITIC_ENTRY_DM)
- cl = 15;
- else
- cl = 5;
- break;
-
- case (5): /* OTHER processing - alloc mem */
- if (rc = sdbc_centry_memalloc_dm(centry,
- centry->cc_alloc_size_dm, flag))
- /* The allocation failed */
- cl = 0;
- else
- cl = 1;
- break;
-
- /*
- * HOST entry processing - save the anchor pt,
- * alloc the memory,
- */
- case (10): /* setup head and nxt ptrs */
- anchor = centry;
- if (rc = sdbc_centry_memalloc_dm(centry,
- centry->cc_alloc_size_dm, flag))
- /* The allocation failed */
- cl = 0;
- else
- cl = 1;
- break;
-
- /*
- * PARASITIC entry processing - setup w/no
- * memory, setup head/next ptrs,
- */
- case (15):
- /*
- * fudge the data mem ptr to an offset from
- * the anchor alloc
- */
- if (!(centry->cc_aging_dm &
- (HASH_ENTRY_DM| HOLD_ENTRY_DM))) {
- centry->cc_head_dm = anchor;
-
- /* chain prev to this */
- prev_ent->cc_next_dm = centry;
-
- /*
- * generate the actual data ptr into
- * host entry memory
- */
- centry->cc_data = anchor->cc_data +
- centry->cc_alloc_size_dm;
- centry->cc_alloc_size_dm = 0;
- }
- cl = 1;
- break;
- } /* switch(cl) */
- } /* while (cl) */
-
- return (rc);
-}
-
-/*
- * _sd_check_buffer_alloc - Check if buffer allocation is invalid.
- *
- * RETURNS:
- * 0 if its ok to continue with allocation.
- * Else errno to be returned to the user.
- *
- * Note:
- * This routine could block if the device is not local and
- * recovery is in progress.
- */
-
-/* ARGSUSED */
-static int
-_sd_check_buffer_alloc(int cd, nsc_off_t fba_pos, nsc_size_t fba_len,
- _sd_buf_handle_t **hp)
-{
- /*
- * This check exists to ensure that someone will not pass in an
- * arbitrary pointer and try to pass it off as a handle.
- */
- if ((*hp)->bh_flag & (~_SD_VALID_FLAGS)) {
- cmn_err(CE_WARN, "!sdbc(_sd_check_buffer_alloc) "
- "cd %d invalid handle %p flags %x",
- cd, (void *)*hp, (*hp)->bh_flag);
- return (EINVAL);
- }
-
- if ((_sd_cache_initialized == 0) || (FILE_OPENED(cd) == 0)) {
- cmn_err(CE_WARN, "!sdbc(_sd_check_buffer_alloc) "
- "cd %d not open. Cache init %d",
- cd, _sd_cache_initialized);
- return (EINVAL);
- }
- ASSERT(cd >= 0);
- if (!(_sd_cache_files[cd].cd_rawfd) ||
- !nsc_held(_sd_cache_files[cd].cd_rawfd)) {
- cmn_err(CE_WARN,
- "!sdbc(_sd_check_buffer_alloc) cd %d is not attached", cd);
- return (EINVAL);
- }
-
- ASSERT_IO_SIZE(fba_pos, fba_len, cd);
- ASSERT_LEN(fba_len);
-
- return (0);
-}
-
-/*
- * sdbc_check_handle -- check that handle is valid
- * return 1 if ok, 0 otherwise (if debug then panic).
- */
-static int
-sdbc_check_handle(_sd_buf_handle_t *handle)
-{
- int ret = 1;
-
- if (!_SD_HANDLE_ACTIVE(handle)) {
-
- cmn_err(cmn_level, "!sdbc(_sd_free_buf): invalid handle %p"
- "cd %d fpos %" NSC_SZFMT " flen %" NSC_SZFMT " flag %x",
- (void *)handle, HANDLE_CD(handle), handle->bh_fba_pos,
- handle->bh_fba_len, handle->bh_flag);
-
- ret = 0;
- }
-
- return (ret);
-}
-
-/*
- * _sd_free_buf - Free the buffers allocated in _sd_alloc_buf.
- *
- * ARGUMENTS:
- * handle - The handle allocated in _sd_alloc_buf.
- *
- * RETURNS:
- * 0 on success.
- * Else errno.
- *
- * NOTE:
- * If handle was allocated through _sd_alloc_buf, the handle allocated
- * flag (NSC_HALLOCATED) will be reset by _sd_alloc_buf. This indicates
- * that _sd_free_buf should free up the handle as well.
- * All other handles directly allocated from _sd_alloc_handle will have
- * that flag set. Any handle with valid blocks will have the handle
- * active flag. It is an error if the active flag is not set.
- * (if free_buf were called without going through alloc_buf)
- */
-
-int
-_sd_free_buf(_sd_buf_handle_t *handle)
-{
- _sd_cctl_t *centry, *cc_chain;
- int cd = HANDLE_CD(handle);
- int flen = handle->bh_fba_len;
- int fpos = handle->bh_fba_pos;
-
- SDTRACE(ST_ENTER|SDF_FREEBUF, HANDLE_CD(handle),
- handle->bh_fba_len, handle->bh_fba_pos, 0, 0);
-
- if (sdbc_check_handle(handle) == 0)
- return (EINVAL);
-
- if (handle->bh_flag & NSC_MIXED) {
- /*
- * Data in this handle will be a mix of data from the
- * source device and data from another device, so
- * invalidate all the blocks.
- */
- handle->bh_flag &= ~NSC_QUEUE;
- centry = handle->bh_centry;
- while (centry) {
- centry->cc_valid = 0;
- centry = centry->cc_chain;
- }
- }
-
- if ((handle->bh_flag & NSC_QUEUE)) {
- handle->bh_flag &= ~NSC_QUEUE;
- _sd_queue_write(handle, handle->bh_fba_pos, handle->bh_fba_len);
- }
-
- handle->bh_flag &= ~NSC_HACTIVE;
-
- centry = handle->bh_centry;
- while (centry) {
- cc_chain = centry->cc_chain;
- _sd_centry_release(centry);
- centry = cc_chain;
- }
-
- /*
- * help prevent dup call to _sd_centry_release if this handle
- * is erroneously _sd_free_buf'd twice. (should not happen).
- */
- handle->bh_centry = NULL;
-
- if ((handle->bh_flag & NSC_HALLOCATED) == 0) {
- handle->bh_flag |= NSC_HALLOCATED;
- (void) _sd_free_handle(handle);
- } else {
- handle->bh_flag = NSC_HALLOCATED;
- }
-
- SDTRACE(ST_EXIT|SDF_FREEBUF, cd, flen, fpos, 0, 0);
-
- return (0);
-}
-
-
-static int _sd_lruq_srch = 0x2000;
-
-/*
- * sdbc_get_dmchain -- get a candidate centry chain pointing to
- * contiguous memory
- * ARGUMENTS:
- * cblocks - number of cache blocks requested
- * stall - pointer to stall count (no blocks avail)
- * flag - ALLOC_NOWAIT flag
- *
- * RETURNS:
- * a cache entry or possible NULL if ALLOC_NOWAIT set
- * USAGE:
- * attempt to satisfy entire request from queue
- * that has no memory allocated.
- * if this fails then attempt a partial allocation
- * with a preallocated block of requested size up to
- * max_dyn_list.
- * then look for largest chain less than max_dyn_list.
- */
-static _sd_cctl_t *
-sdbc_get_dmchain(int cblocks, int *stall, int flag)
-{
- _sd_cctl_t *cc_dmchain = NULL;
- _sd_queue_t *q;
- _sd_cctl_t *qhead;
- int num_tries;
- int cblocks_orig = cblocks;
- int nowait = flag & ALLOC_NOWAIT;
- int i;
-
- num_tries = _sd_lruq_srch;
-
- ASSERT(cblocks != 0);
-
- while (!cc_dmchain) {
- /* get it from the os if possible */
- q = &sdbc_dm_queues[0];
- qhead = &(q->sq_qhead);
-
- if (q->sq_inq >= cblocks) {
- mutex_enter(&q->sq_qlock);
- if (q->sq_inq >= cblocks) {
- _sd_cctl_t *cc_ent;
-
- cc_dmchain = qhead->cc_next;
-
- /*
- * set the inuse and pageio bits
- * Note: this code expects the cc_ent to
- * be available. no other thread may set the
- * inuse or pageio bit for an entry on the
- * 0 queue.
- */
- cc_ent = qhead;
- for (i = 0; i < cblocks; ++i) {
- cc_ent = cc_ent->cc_next;
-
- if (SET_CENTRY_INUSE(cc_ent)) {
- cmn_err(CE_PANIC,
- "centry inuse on 0 q! %p",
- (void *)cc_ent);
- }
-
- if (SET_CENTRY_PAGEIO(cc_ent)) {
- cmn_err(CE_PANIC,
- "centry pageio on 0 q! %p",
- (void *)cc_ent);
- }
- }
- /* got a dmchain */
-
- /* remove this chain from the 0 queue */
- cc_dmchain->cc_prev->cc_next = cc_ent->cc_next;
- cc_ent->cc_next->cc_prev = cc_dmchain->cc_prev;
- cc_dmchain->cc_prev = NULL;
- cc_ent->cc_next = NULL;
-
- q->sq_inq -= cblocks;
-
- ASSERT(GOOD_LRUSIZE(q));
-
- }
- mutex_exit(&q->sq_qlock);
- if (cc_dmchain)
- continue;
- }
-
- /* look for a pre-allocated block of the requested size */
-
-
- if (cblocks > (max_dm_queues - 1))
- cblocks = max_dm_queues - 1;
-
- q = &sdbc_dm_queues[cblocks];
- qhead = &(q->sq_qhead);
-
- if (q->sq_inq != 0) {
- _sd_cctl_t *tmp_dmchain;
-
- mutex_enter(&q->sq_qlock);
-
- for (tmp_dmchain = qhead->cc_next; tmp_dmchain != qhead;
- tmp_dmchain = tmp_dmchain->cc_next) {
-
- /*
- * get a dmchain
- * set the inuse and pageio bits
- */
- if (sdbc_dmchain_avail(tmp_dmchain)) {
- /* put on MRU end of queue */
- sdbc_requeue_dmchain(q, tmp_dmchain,
- 1, 0);
- cc_dmchain = tmp_dmchain;
- break;
- }
- sdbc_dmchain_not_avail++;
- }
-
- mutex_exit(&q->sq_qlock);
- if (cc_dmchain)
- continue;
- }
-
- /*
- * spin block
- * nudge the deallocator, accelerate ageing
- */
-
- mutex_enter(&dynmem_processing_dm.thread_dm_lock);
- cv_broadcast(&dynmem_processing_dm.thread_dm_cv);
- mutex_exit(&dynmem_processing_dm.thread_dm_lock);
-
- if (nowait)
- break;
-
- if (!(--num_tries)) {
- delay(drv_usectohz(20000));
- (void) (*stall)++;
- num_tries = _sd_lruq_srch;
- cblocks = cblocks_orig;
- } else { /* see if smaller request size is available */
- if (!(--cblocks))
- cblocks = cblocks_orig;
- }
-
- } /* while (!cc_dmchain) */
-
- return (cc_dmchain);
-}
-
-static int
-sdbc_dmchain_avail(_sd_cctl_t *cc_ent)
-{
- int chain_avail = 1;
- _sd_cctl_t *anchor = cc_ent;
-
- while (cc_ent) {
-
- ASSERT(_sd_cctl_valid(cc_ent));
-
- if (cc_ent->cc_aging_dm & BAD_CHAIN_DM) {
- chain_avail = 0;
- break;
- }
-
- if (CENTRY_DIRTY(cc_ent)) {
- chain_avail = 0;
- break;
- }
- if (SET_CENTRY_INUSE(cc_ent)) {
- chain_avail = 0;
- break;
- }
-
- if ((SET_CENTRY_PAGEIO(cc_ent))) {
-
- CLEAR_CENTRY_INUSE(cc_ent);
- chain_avail = 0;
- break;
- }
-
- if (CENTRY_DIRTY(cc_ent)) {
-
- CLEAR_CENTRY_PAGEIO(cc_ent);
- CLEAR_CENTRY_INUSE(cc_ent);
- chain_avail = 0;
- break;
- }
-
- cc_ent->cc_flag = 0;
- cc_ent->cc_toflush = 0;
-
- cc_ent = cc_ent->cc_next_dm;
- }
-
- if (!chain_avail)
- sdbc_clear_dmchain(anchor, cc_ent);
- else {
- cc_ent = anchor;
-
- /*
- * prevent possible deadlocks in _sd_cc_wait():
- * remove from hash and wakeup any waiters now that we
- * have acquired the chain.
- */
- while (cc_ent) {
- (void) _sd_hash_delete((struct _sd_hash_hd *)cc_ent,
- _sd_htable);
-
- mutex_enter(&cc_ent->cc_lock);
- if (cc_ent->cc_await_use) {
- cv_broadcast(&cc_ent->cc_blkcv);
- }
- mutex_exit(&cc_ent->cc_lock);
-
- cc_ent->cc_creat = nsc_lbolt();
- cc_ent->cc_hits = 0;
-
- cc_ent = cc_ent->cc_next_dm;
- }
- }
-
- return (chain_avail);
-}
-
-static void
-sdbc_clear_dmchain(_sd_cctl_t *cc_ent_start, _sd_cctl_t *cc_ent_end)
-{
- _sd_cctl_t *cc_ent = cc_ent_start;
- _sd_cctl_t *prev_ent;
-
- ASSERT(_sd_cctl_valid(cc_ent));
-
- while (cc_ent != cc_ent_end) {
-
- ASSERT(_sd_cctl_valid(cc_ent));
-
- prev_ent = cc_ent;
- cc_ent = cc_ent->cc_next_dm;
-
- CLEAR_CENTRY_PAGEIO(prev_ent);
- CLEAR_CENTRY_INUSE(prev_ent);
- }
-
-}
-
-/*
- * put a dmchain on the LRU end of a queue
- */
-void
-sdbc_ins_dmqueue_front(_sd_queue_t *q, _sd_cctl_t *cc_ent)
-{
- _sd_cctl_t *qhead = &(q->sq_qhead);
-
- ASSERT(_sd_cctl_valid(cc_ent));
-
- mutex_enter(&q->sq_qlock);
- cc_ent->cc_next = qhead->cc_next;
- cc_ent->cc_prev = qhead;
- qhead->cc_next->cc_prev = cc_ent;
- qhead->cc_next = cc_ent;
- q->sq_inq++;
- cc_ent->cc_cblocks = q->sq_dmchain_cblocks;
-
- ASSERT(GOOD_LRUSIZE(q));
-
- mutex_exit(&q->sq_qlock);
-
-}
-
-/*
- * put a dmchain on the MRU end of a queue
- */
-static void
-sdbc_ins_dmqueue_back(_sd_queue_t *q, _sd_cctl_t *cc_ent)
-{
- _sd_cctl_t *qhead = &(q->sq_qhead);
-
- ASSERT(_sd_cctl_valid(cc_ent));
-
- mutex_enter(&q->sq_qlock);
- cc_ent->cc_next = qhead;
- cc_ent->cc_prev = qhead->cc_prev;
- qhead->cc_prev->cc_next = cc_ent;
- qhead->cc_prev = cc_ent;
- cc_ent->cc_seq = q->sq_seq++;
- q->sq_inq++;
- cc_ent->cc_cblocks = q->sq_dmchain_cblocks;
-
- ASSERT(GOOD_LRUSIZE(q));
-
- mutex_exit(&q->sq_qlock);
-
-}
-
-/*
- * remove dmchain from a queue
- */
-void
-sdbc_remq_dmchain(_sd_queue_t *q, _sd_cctl_t *cc_ent)
-{
-
- ASSERT(_sd_cctl_valid(cc_ent));
-
- mutex_enter(&q->sq_qlock);
- cc_ent->cc_prev->cc_next = cc_ent->cc_next;
- cc_ent->cc_next->cc_prev = cc_ent->cc_prev;
- cc_ent->cc_next = cc_ent->cc_prev = NULL; /* defensive programming */
- cc_ent->cc_cblocks = -1; /* indicate not on any queue */
-
- q->sq_inq--;
-
- ASSERT(GOOD_LRUSIZE(q));
-
- mutex_exit(&q->sq_qlock);
-
-}
-
-/*
- * requeue a dmchain to the MRU end of its queue.
- * if getlock is 0 on entry the queue lock (sq_qlock) must be held
- */
-void
-sdbc_requeue_dmchain(_sd_queue_t *q, _sd_cctl_t *cc_ent, int mru,
- int getlock)
-{
- _sd_cctl_t *qhead = &(q->sq_qhead);
-
-
- ASSERT(_sd_cctl_valid(cc_ent));
-
- if (getlock)
- mutex_enter(&q->sq_qlock);
-
- /* inline of sdbc_remq_dmchain() */
- cc_ent->cc_prev->cc_next = cc_ent->cc_next;
- cc_ent->cc_next->cc_prev = cc_ent->cc_prev;
-
- if (mru) { /* put on MRU end of queue */
- /* inline of sdbc_ins_dmqueue_back */
- cc_ent->cc_next = qhead;
- cc_ent->cc_prev = qhead->cc_prev;
- qhead->cc_prev->cc_next = cc_ent;
- qhead->cc_prev = cc_ent;
- cc_ent->cc_seq = q->sq_seq++;
- (q->sq_req_stat)++;
- } else { /* put on LRU end of queue i.e. requeue to head */
- /* inline of sdbc_ins_dmqueue_front */
- cc_ent->cc_next = qhead->cc_next;
- cc_ent->cc_prev = qhead;
- qhead->cc_next->cc_prev = cc_ent;
- qhead->cc_next = cc_ent;
- cc_ent->cc_seq = q->sq_seq++;
-
- /*
- * clear the CC_QHEAD bit on all members of the chain
- */
- {
- _sd_cctl_t *tcent;
-
- for (tcent = cc_ent; tcent; tcent = tcent->cc_next_dm)
- tcent->cc_flag &= ~CC_QHEAD;
- }
- }
-
- if (getlock)
- mutex_exit(&q->sq_qlock);
-
-}
-
-/*
- * sdbc_dmchain_dirty(cc_ent)
- * return first dirty cc_ent in dmchain, NULL if chain is not dirty
- */
-static _sd_cctl_t *
-sdbc_dmchain_dirty(_sd_cctl_t *cc_ent)
-{
- for (/* CSTYLED */; cc_ent; cc_ent = cc_ent->cc_next_dm)
- if (CENTRY_DIRTY(cc_ent))
- break;
-
- return (cc_ent);
-}
-
-/*
- * sdbc_requeue_head_dm_try()
- * attempt to requeue a dmchain to the head of the queue
- */
-void
-sdbc_requeue_head_dm_try(_sd_cctl_t *cc_ent)
-{
- int qidx;
- _sd_queue_t *q;
-
- if (!sdbc_dmchain_dirty(cc_ent)) {
- qidx = cc_ent->cc_cblocks;
- q = &sdbc_dm_queues[qidx];
- sdbc_requeue_dmchain(q, cc_ent, 0, 1); /* requeue head */
- }
-}
-
-/*
- * sdbc_centry_alloc_blks -- allocate cache entries with memory
- *
- * ARGUMENTS:
- * cd - Cache descriptor (from a previous open)
- * cblk - cache block number.
- * reqblks - number of cache blocks to be allocated
- * flag - can be ALLOC_NOWAIT
- * RETURNS:
- * A cache block chain or NULL if ALLOC_NOWAIT and request fails
- *
- * Note: caller must check for null return if called with
- * ALLOC_NOWAIT set.
- */
-_sd_cctl_t *
-sdbc_centry_alloc_blks(int cd, nsc_off_t cblk, nsc_size_t reqblks, int flag)
-{
- sdbc_allocbuf_t alloc_tok = {0}; /* must be 0 */
- int stall = 0;
- _sd_cctl_t *centry = NULL;
- _sd_cctl_t *lentry = NULL;
- _sd_cctl_t *anchor = NULL;
- _sd_cctl_t *next_centry;
-
- ASSERT(reqblks);
-
- while (reqblks) {
- centry = sdbc_centry_alloc(cd, cblk, reqblks, &stall,
- &alloc_tok, flag);
-
- if (!centry)
- break;
-
- centry->cc_chain = NULL;
-
- if (lentry == NULL)
- anchor = centry;
- else
- lentry->cc_chain = centry;
-
- lentry = centry;
-
- centry->cc_aging_dm &= ~(ENTRY_FIELD_DM);
-
- if (centry->cc_aging_dm & FOUND_IN_HASH_DM)
- centry->cc_aging_dm |= HASH_ENTRY_DM;
- else
- if (centry->cc_aging_dm & FOUND_HOLD_OVER_DM)
- centry->cc_aging_dm |= HOLD_ENTRY_DM;
- else
- centry->cc_aging_dm |= ELIGIBLE_ENTRY_DM;
-
- centry->cc_aging_dm &= ~(FOUND_IN_HASH_DM|FOUND_HOLD_OVER_DM);
- --reqblks;
- }
-
- sdbc_centry_alloc_end(&alloc_tok);
-
- if (reqblks || (_sd_setup_category_on_type(anchor))) {
- centry = anchor;
- while (centry) {
- next_centry = centry->cc_chain;
- _sd_centry_release(centry);
- centry = next_centry;
- }
- anchor = NULL;
-
- } else
- /* This is where the memory is actually allocated */
- if (_sd_setup_mem_chaining(anchor, flag))
- anchor = NULL;
-
- return (anchor);
-}
-
-
-/*
- * sdbc_centry_alloc - sdbc internal function to allocate a new cache block.
- *
- * ARGUMENTS:
- * cd - Cache descriptor (from a previous open)
- * cblk - cache block number.
- * stall - pointer to stall count (no blocks avail)
- * req_blocks - number of cache blocks remaining in caller's i/o request
- * alloc_tok - pointer to token initialized to 0 on first call to function
- * flag - lock status of sdbc_queue_lock or ALLOC_NOWAIT flag
- * RETURNS:
- * A cache block, or possibly NULL if ALLOC_NOWAIT set .
- *
- * USAGE:
- * switch to the appropriate allocation function.
- * this function is used when callers need more than one cache block.
- * it is called repeatedly until the entire request is satisfied,
- * at which time the caller will then do the memory allocation.
- * if only one cache block is needed callers may use
- * sdbc_centry_alloc_blks() which also allocates memory.
- *
- * Note: caller must check for null return if called with
- * ALLOC_NOWAIT set.
- */
-
-_sd_cctl_t *
-sdbc_centry_alloc(int cd, nsc_off_t cblk, nsc_size_t req_blocks, int *stall,
- sdbc_allocbuf_t *alloc_tok, int flag)
-{
- _sd_cctl_t *centry;
-
- if (sdbc_use_dmchain)
- centry = sdbc_alloc_dmc(cd, cblk, req_blocks, stall, alloc_tok,
- flag);
- else
- centry = sdbc_alloc_lru(cd, cblk, stall, flag);
-
- return (centry);
-}
-
-/*
- * sdbc_alloc_dmc -- allocate a centry from a dmchain
- *
- * ARGUMENTS:
- * cd - Cache descriptor (from a previous open)
- * cblk - cache block number.
- * stall - pointer to stall count (no blocks avail)
- * req_blocks - number of cache blocks in clients i/o request
- * alloc_tok - pointer to token initialized to 0 on first call to function
- * flag - lock status of sdbc_queue_lock, or ALLOC_NOWAIT flag
- * RETURNS:
- * A cache block or possibly NULL if ALLOC_NOWAIT set
- *
- * USAGE:
- * if dmchain is empty, allocate one.
- */
-static _sd_cctl_t *
-sdbc_alloc_dmc(int cd, nsc_off_t cblk, nsc_size_t req_blocks, int *stall,
- sdbc_allocbuf_t *alloc_tok, int flag)
-{
- sdbc_allocbuf_impl_t *dmc = (sdbc_allocbuf_impl_t *)alloc_tok;
- _sd_cctl_t *centry = NULL;
-
- if (!dmc->sab_dmchain) {
- /*
- * Note - sdbc_get_dmchain() returns
- * with cc_inuse and cc_pageio set
- * for all members of dmchain.
- */
- if (dmc->sab_dmchain =
- sdbc_get_dmchain(req_blocks, stall, flag)) {
-
- /* remember q it came from */
- if (dmc->sab_dmchain->cc_alloc_size_dm)
- dmc->sab_q = dmc->sab_dmchain->cc_cblocks;
- }
- }
-
- /*
- * Note: dmchain pointer is advanced in sdbc_alloc_from_dmchain()
- */
- if (dmc->sab_dmchain) /* could be NULL if ALLOC_NOWAIT set */
- centry = sdbc_alloc_from_dmchain(cd, cblk, alloc_tok, flag);
-
- return (centry);
-}
-
-/*
- * sdbc_alloc_from_dmchain -- allocate centry from a dmchain of centrys
- *
- * ARGUMENTS:
- * cd - Cache descriptor (from a previous open)
- * cblk - cache block number.
- * alloc_tok - pointer to token
- * flag - lock status of sdbc_queue_lock or ALLOC_NOWAIT
- *
- * RETURNS:
- * A cache block or possibly NULL if ALLOC_NOWAIT set.
- *
- * USAGE:
- * This routine allocates a new cache block from the supplied dmchain.
- * Assumes that dmchain is non-NULL and that all cache entries in
- * the dmchain have been removed from hash and have their cc_inuse and
- * cc_pageio bits set.
- */
-static _sd_cctl_t *
-sdbc_alloc_from_dmchain(int cd, nsc_off_t cblk, sdbc_allocbuf_t *alloc_tok,
- int flag)
-{
- _sd_cctl_t *cc_ent, *old_ent;
- int categorize_centry;
- int locked = flag & ALLOC_LOCKED;
- int nowait = flag & ALLOC_NOWAIT;
- sdbc_allocbuf_impl_t *dmc = (sdbc_allocbuf_impl_t *)alloc_tok;
-
- SDTRACE(ST_ENTER|SDF_ENT_ALLOC, cd, 0, BLK_TO_FBA_NUM(cblk), 0, 0);
-
- ASSERT(dmc->sab_dmchain);
-
- cc_ent = dmc->sab_dmchain;
-
- ASSERT(_sd_cctl_valid(cc_ent));
-
- cc_ent->cc_valid = 0;
- categorize_centry = 0;
- if (cc_ent->cc_data)
- categorize_centry = FOUND_HOLD_OVER_DM;
-
-alloc_try:
- if (cd == _CD_NOHASH)
- CENTRY_BLK(cc_ent) = cblk;
- else if ((old_ent = (_sd_cctl_t *)
- _sd_hash_insert(cd, cblk, (struct _sd_hash_hd *)cc_ent,
- _sd_htable)) != cc_ent) {
-
- if (SET_CENTRY_INUSE(old_ent)) {
- sdbc_centry_inuse++;
-
- if (nowait) {
- cc_ent = NULL;
- goto out;
- }
-
- if (locked)
- rw_exit(&sdbc_queue_lock);
- _sd_cc_wait(cd, cblk, old_ent, CC_INUSE);
- if (locked)
- rw_enter(&sdbc_queue_lock, RW_WRITER);
- goto alloc_try;
- }
-
- /*
- * bug 4529671
- * now that we own the centry make sure that
- * it is still good. it could have been processed
- * by _sd_dealloc_dm() in the window between
- * _sd_hash_insert() and SET_CENTRY_INUSE().
- */
- if ((_sd_cctl_t *)_sd_hash_search(cd, cblk, _sd_htable)
- != old_ent) {
- sdbc_centry_deallocd++;
-#ifdef DEBUG
- cmn_err(CE_WARN, "!cc_ent %p cd %d cblk %" NSC_SZFMT
- " lost to dealloc?! cc_data %p", (void *)old_ent,
- cd, cblk, (void *)old_ent->cc_data);
-#endif
-
- CLEAR_CENTRY_INUSE(old_ent);
-
- if (nowait) {
- cc_ent = NULL;
- goto out;
- }
-
- goto alloc_try;
- }
-
- if (CC_CD_BLK_MATCH(cd, cblk, old_ent)) {
- sdbc_centry_hit++;
- old_ent->cc_toflush = 0;
- /* _sd_centry_release(cc_ent); */
- cc_ent = old_ent;
- categorize_centry = FOUND_IN_HASH_DM;
- } else {
- sdbc_centry_lost++;
-
- CLEAR_CENTRY_INUSE(old_ent);
-
- if (nowait) {
- cc_ent = NULL;
- goto out;
- }
-
- goto alloc_try;
- }
- }
-
- /*
- * advance the dmchain pointer, but only if we got the
- * cc_ent from the dmchain
- */
- if (categorize_centry != FOUND_IN_HASH_DM) {
- if (cc_ent->cc_data)
- dmc->sab_dmchain = dmc->sab_dmchain->cc_next_dm;
- else
- dmc->sab_dmchain = dmc->sab_dmchain->cc_next;
- }
-
-
- SDTRACE(ST_EXIT|SDF_ENT_ALLOC, cd, 0, BLK_TO_FBA_NUM(cblk), 0, 0);
-
- mutex_enter(&cc_ent->cc_lock);
- if (cc_ent->cc_await_use) {
- cv_broadcast(&cc_ent->cc_blkcv);
- }
- mutex_exit(&cc_ent->cc_lock);
-
- sdbc_centry_init_dm(cc_ent);
-
- cc_ent->cc_aging_dm |= categorize_centry;
-
- out:
-
- SDTRACE(ST_INFO|SDF_ENT_ALLOC, cd, 0, BLK_TO_FBA_NUM(cblk), 0, 0);
-
- return (cc_ent);
-}
-
-/*
- * sdbc_centry_alloc_end -- tidy up after all cache blocks have been
- * allocated for a request
- * ARGUMENTS:
- * alloc_tok - pointer to allocation token
- * RETURNS
- * nothing
- * USAGE:
- * at this time only useful when sdbc_use_dmchain is true.
- * if there are cache blocks remaining on the chain then the inuse and
- * pageio bits must be cleared (they were set in sdbc_get_dmchain().
- *
- */
-static void
-sdbc_centry_alloc_end(sdbc_allocbuf_t *alloc_tok)
-{
- _sd_cctl_t *next_centry;
- _sd_cctl_t *prev_centry;
- _sd_queue_t *q;
- sdbc_allocbuf_impl_t *dmc = (sdbc_allocbuf_impl_t *)alloc_tok;
-#ifdef DEBUG
- int chainpull = 0;
-#endif
-
- if (!sdbc_use_dmchain)
- return;
-
- next_centry = dmc->sab_dmchain;
-
- while (next_centry != NULL) {
- CLEAR_CENTRY_PAGEIO(next_centry);
-
- prev_centry = next_centry;
-
- if (next_centry->cc_data) {
-#ifdef DEBUG
- ++chainpull;
-#endif
- next_centry = next_centry->cc_next_dm;
-
- /* clear bit after final reference */
-
- CLEAR_CENTRY_INUSE(prev_centry);
- } else {
- next_centry = next_centry->cc_next;
-
- /*
- * a floater from the 0 queue, insert on q.
- *
- * since this centry is not on any queue
- * the inuse bit can be cleared before
- * inserting on the q. this is also required
- * since sdbc_get_dmchain() does not expect
- * inuse bits to be set on 0 queue entry's.
- */
-
- CLEAR_CENTRY_INUSE(prev_centry);
- q = &sdbc_dm_queues[0];
- sdbc_ins_dmqueue_front(q, prev_centry);
- }
- }
-
-#ifdef DEBUG
- /* compute wastage stats */
- ASSERT((chainpull >= 0) && (chainpull < max_dm_queues));
- if (chainpull)
- (*(dmchainpull_table + (dmc->sab_q *
- max_dm_queues + chainpull)))++;
-#endif
-
-}
-
-
-/*
- * sdbc_alloc_lru - allocate a new cache block from the lru queue
- *
- * ARGUMENTS:
- * cd - Cache descriptor (from a previous open)
- * cblk - cache block number.
- * stall - pointer to stall count (no blocks avail)
- * flag - lock status of sdbc_queue_lock or ALLOC_NOWAIT
- *
- * RETURNS:
- * A cache block or NULL if ALLOC_NOWAIT specified
- *
- * USAGE:
- * This routine allocates a new cache block from the lru.
- * If an allocation cannot be done, we block, unless ALLOC_NOWAIT is set.
- */
-
-static _sd_cctl_t *
-sdbc_alloc_lru(int cd, nsc_off_t cblk, int *stall, int flag)
-{
- _sd_cctl_t *cc_ent, *old_ent, *ccnext;
- _sd_queue_t *q = _SD_LRU_Q;
- _sd_cctl_t *qhead = &(q->sq_qhead);
- int tries = 0, num_tries;
- int categorize_centry;
- int locked = flag & ALLOC_LOCKED;
- int nowait = flag & ALLOC_NOWAIT;
-
- if (nowait) {
- num_tries = q->sq_inq / 100; /* only search 1% of q */
-
- if (num_tries <= 0) /* ensure num_tries is non-zero */
- num_tries = q->sq_inq;
- } else
- num_tries = _sd_lruq_srch;
-
- SDTRACE(ST_ENTER|SDF_ENT_ALLOC, cd, 0, BLK_TO_FBA_NUM(cblk), 0, 0);
-retry_alloc_centry:
-
- for (cc_ent = (qhead->cc_next); cc_ent != qhead; cc_ent = ccnext) {
- if (--num_tries <= 0)
- if (nowait) {
- cc_ent = NULL;
- goto out;
- } else
- break;
-
- ccnext = cc_ent->cc_next;
-
- if (cc_ent->cc_aging_dm & BAD_CHAIN_DM)
- continue;
-
- if (CENTRY_DIRTY(cc_ent))
- continue;
- if (SET_CENTRY_INUSE(cc_ent))
- continue;
-
- if (CENTRY_DIRTY(cc_ent)) {
- sdbc_centry_lost++;
-
- CLEAR_CENTRY_INUSE(cc_ent);
- continue;
- }
- cc_ent->cc_flag = 0; /* CC_INUSE */
- cc_ent->cc_toflush = 0;
-
- /*
- * Inlined requeue of the LRU. (should match _sd_requeue)
- */
- /* was FAST */
- mutex_enter(&q->sq_qlock);
-#if defined(_SD_DEBUG)
- if (1) {
- _sd_cctl_t *cp, *cn, *qp;
- cp = cc_ent->cc_prev;
- cn = cc_ent->cc_next;
- qp = (q->sq_qhead).cc_prev;
- if (!_sd_cctl_valid(cc_ent) ||
- (cp != &(q->sq_qhead) && !_sd_cctl_valid(cp)) ||
- (cn != &(q->sq_qhead) && !_sd_cctl_valid(cn)) ||
- !_sd_cctl_valid(qp))
- cmn_err(CE_PANIC,
- "_sd_centry_alloc %x prev %x next %x qp %x",
- cc_ent, cp, cn, qp);
- }
-#endif
- cc_ent->cc_prev->cc_next = cc_ent->cc_next;
- cc_ent->cc_next->cc_prev = cc_ent->cc_prev;
- cc_ent->cc_next = qhead;
- cc_ent->cc_prev = qhead->cc_prev;
- qhead->cc_prev->cc_next = cc_ent;
- qhead->cc_prev = cc_ent;
- cc_ent->cc_seq = q->sq_seq++;
- /* was FAST */
- mutex_exit(&q->sq_qlock);
- /*
- * End inlined requeue.
- */
-
-#if defined(_SD_STATS)
- if (_sd_hash_delete(cc_ent, _sd_htable) == 0)
- SDTRACE(SDF_REPLACE,
- CENTRY_CD(cc_ent), cc_ent->cc_hits,
- BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent)),
- nsc_lbolt(), cc_ent->cc_creat);
- cc_ent->cc_creat = nsc_lbolt();
- cc_ent->cc_hits = 0;
-#else
-#if defined(_SD_DEBUG)
- if (_sd_hash_delete(cc_ent, _sd_htable) == 0) {
- SDTRACE(SDF_REPLACE|ST_DL,
- CENTRY_CD(cc_ent),
- cc_ent->cc_valid,
- BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent)),
- cd, BLK_TO_FBA_NUM(cblk));
- if (cc_ent->cc_await_use ||
- ((cd == CENTRY_CD(cc_ent)) &&
- (cblk == CENTRY_BLK(cc_ent))))
- DATA_LOG(SDF_REPLACE|ST_DL, cc_ent, 0,
- BLK_FBAS);
- }
-#else
- (void) _sd_hash_delete((struct _sd_hash_hd *)cc_ent,
- _sd_htable);
-#endif
-#endif
- cc_ent->cc_creat = nsc_lbolt();
- cc_ent->cc_hits = 0;
-
- cc_ent->cc_valid = 0;
- categorize_centry = 0;
- if (cc_ent->cc_data)
- categorize_centry = FOUND_HOLD_OVER_DM;
-
- alloc_try:
- if (cd == _CD_NOHASH)
- CENTRY_BLK(cc_ent) = cblk;
- else if ((old_ent = (_sd_cctl_t *)
- _sd_hash_insert(cd, cblk, (struct _sd_hash_hd *)cc_ent,
- _sd_htable)) != cc_ent) {
-
- if (SET_CENTRY_INUSE(old_ent)) {
- sdbc_centry_inuse++;
-
- if (nowait) {
- _sd_centry_release(cc_ent);
- cc_ent = NULL;
- goto out;
- }
-
- if (locked)
- rw_exit(&sdbc_queue_lock);
- _sd_cc_wait(cd, cblk, old_ent, CC_INUSE);
- if (locked)
- rw_enter(&sdbc_queue_lock, RW_WRITER);
- goto alloc_try;
- }
-
- /*
- * bug 4529671
- * now that we own the centry make sure that
- * it is still good. it could have been processed
- * by _sd_dealloc_dm() in the window between
- * _sd_hash_insert() and SET_CENTRY_INUSE().
- */
- if ((_sd_cctl_t *)
- _sd_hash_search(cd, cblk, _sd_htable) != old_ent) {
- sdbc_centry_deallocd++;
-#ifdef DEBUG
- cmn_err(CE_WARN, "!cc_ent %p cd %d cblk %"
- NSC_SZFMT " lost to dealloc?! cc_data %p",
- (void *)old_ent, cd, cblk,
- (void *)old_ent->cc_data);
-#endif
-
- CLEAR_CENTRY_INUSE(old_ent);
-
- if (nowait) {
- _sd_centry_release(cc_ent);
- cc_ent = NULL;
- goto out;
- }
-
- goto alloc_try;
- }
-
- if (CC_CD_BLK_MATCH(cd, cblk, old_ent)) {
- sdbc_centry_hit++;
- old_ent->cc_toflush = 0;
- _sd_centry_release(cc_ent);
- cc_ent = old_ent;
- categorize_centry = FOUND_IN_HASH_DM;
- } else {
- sdbc_centry_lost++;
-
- CLEAR_CENTRY_INUSE(old_ent);
-
- if (nowait) {
- _sd_centry_release(cc_ent);
- cc_ent = NULL;
- goto out;
- }
-
- goto alloc_try;
- }
- }
-
- SDTRACE(ST_EXIT|SDF_ENT_ALLOC, cd, tries,
- BLK_TO_FBA_NUM(cblk), 0, 0);
-
- if (cc_ent->cc_await_use) {
- mutex_enter(&cc_ent->cc_lock);
- cv_broadcast(&cc_ent->cc_blkcv);
- mutex_exit(&cc_ent->cc_lock);
- }
-
- sdbc_centry_init_dm(cc_ent);
-
- cc_ent->cc_aging_dm |= categorize_centry;
-
- out:
- return (cc_ent);
- }
-
- SDTRACE(ST_INFO|SDF_ENT_ALLOC, cd, ++tries, BLK_TO_FBA_NUM(cblk), 0, 0);
-
- delay(drv_usectohz(20000));
- (void) (*stall)++;
- num_tries = _sd_lruq_srch;
- goto retry_alloc_centry;
-}
-
-/*
- * sdbc_centry_init_dm - setup the cache block for dynamic memory allocation
- *
- * ARGUMENTS:
- * centry - Cache block.
- *
- * RETURNS:
- * NONE
- *
- * USAGE:
- * This routine is the central point in which cache entry blocks are setup
- */
-static void
-sdbc_centry_init_dm(_sd_cctl_t *centry)
-{
-
- /* an entry already setup - don't touch simply refresh age */
- if (centry->cc_data) {
- centry->cc_aging_dm &= ~(FINAL_AGING_DM);
-
- DTRACE_PROBE1(sdbc_centry_init_dm_end,
- char *, centry->cc_data);
- return;
- }
-
- centry->cc_aging_dm &= ~(FINAL_AGING_DM | CATAGORY_ENTRY_DM);
-
- if (centry->cc_head_dm || centry->cc_next_dm)
- cmn_err(cmn_level, "!sdbc(sdbc_centry_init_dm): "
- "non-zero mem chain in ccent %p", (void *)centry);
-
- centry->cc_head_dm = 0;
-
- if (!sdbc_use_dmchain)
- centry->cc_next_dm = 0;
-
- centry->cc_data = 0;
-
-}
-
-/*
- * sdbc_centry_memalloc_dm
- *
- * Actually allocate the cache memory, storing it in the cc_data field for
- * the cctl
- *
- * ARGS:
- * centry: cache control block for which to allocate the memory
- * alloc_request: number of bytes to allocate
- * flag: if called with ALLOC_NOWAIT, caller must check for non-zero return
- *
- * RETURNS:
- * 0 on success
- * non-zero on error
- */
-static int
-sdbc_centry_memalloc_dm(_sd_cctl_t *centry, int alloc_request, int flag)
-{
- int cblocks;
- _sd_queue_t *newq;
- int sleep;
- sleep = (flag & ALLOC_NOWAIT) ? KM_NOSLEEP : KM_SLEEP;
-
- if (!centry->cc_data && (alloc_request > 0)) {
- /* host or other */
- dynmem_processing_dm.alloc_ct++;
- centry->cc_data = (unsigned char *)
- kmem_alloc((size_t)centry->cc_alloc_size_dm, sleep);
-
-
- if (sdbc_use_dmchain) {
- cblocks = centry->cc_alloc_size_dm >> _sd_cblock_shift;
- newq = &sdbc_dm_queues[cblocks];
-
- /* set the dmqueue index */
- centry->cc_cblocks = cblocks;
-
- /* put on appropriate queue */
- sdbc_ins_dmqueue_back(newq, centry);
- }
-
- /*
- * for KM_NOSLEEP (should never happen with KM_SLEEP)
- */
- if (!centry->cc_data)
- return (LOW_RESOURCES_DM);
- centry->cc_head_dm = centry;
- centry->cc_alloc_ct_dm++;
- }
-
- return (0);
-}
-
-/*
- * _sd_centry_release - release a cache block
- *
- * ARGUMENTS:
- * centry - Cache block.
- *
- * RETURNS:
- * NONE
- *
- * USAGE:
- * This routine frees up a cache block. It also frees up a write
- * block if allocated and its valid to release it.
- */
-
-void
-_sd_centry_release(_sd_cctl_t *centry)
-{
- ss_centry_info_t *wctl;
-
- SDTRACE(ST_ENTER|SDF_ENT_FREE, CENTRY_CD(centry), 0,
- BLK_TO_FBA_NUM(CENTRY_BLK(centry)), 0, 0);
-
- CLEAR_CENTRY_PAGEIO(centry);
-
- if ((wctl = centry->cc_write) != 0) {
- /* was FAST */
- mutex_enter(&centry->cc_lock);
- if (CENTRY_DIRTY(centry))
- wctl = NULL;
- else {
- centry->cc_write = NULL;
- centry->cc_flag &= ~(CC_PINNABLE);
- }
- /* was FAST */
- mutex_exit(&centry->cc_lock);
- if (wctl) {
- wctl->sc_dirty = 0;
- SSOP_SETCENTRY(sdbc_safestore, wctl);
- SSOP_DEALLOCRESOURCE(sdbc_safestore, wctl->sc_res);
- }
- }
-
- if (!(centry->cc_aging_dm & BAD_CHAIN_DM)) {
- if (sdbc_use_dmchain) {
- if (centry->cc_alloc_size_dm) {
-
- /* see if this can be queued to head */
- if (CENTRY_QHEAD(centry)) {
- sdbc_requeue_head_dm_try(centry);
- } else {
- int qidx;
- _sd_queue_t *q;
-
- qidx = centry->cc_cblocks;
- q = &sdbc_dm_queues[qidx];
-
- if (_sd_lru_reinsert(q, centry)) {
- sdbc_requeue_dmchain(q,
- centry, 1, 1);
- }
- }
- } else {
- /*
- * Fix for bug 4949134:
- * If an internal block is marked with CC_QHEAD
- * but the HOST block is not, the chain will
- * never age properly, and will never be made
- * available. Only the HOST of the dmchain is
- * checked for CC_QHEAD, so clearing an internal
- * block indiscriminately (as is being done
- * here) does no damage.
- *
- * The same result could instead be achieved by
- * not setting the CC_QHEAD flag in the first
- * place, if the block is an internal dmchain
- * block, and if it is found in the hash table.
- * The current solution was chosen since it is
- * the least intrusive.
- */
- centry->cc_flag &= ~CC_QHEAD;
- }
- } else {
- if (CENTRY_QHEAD(centry)) {
- if (!CENTRY_DIRTY(centry))
- _sd_requeue_head(centry);
- } else if (_sd_lru_reinsert(_SD_LRU_Q, centry))
- _sd_requeue(centry);
- }
- }
-
- SDTRACE(ST_EXIT|SDF_ENT_FREE, CENTRY_CD(centry), 0,
- BLK_TO_FBA_NUM(CENTRY_BLK(centry)), 0, 0);
-
- /* only clear inuse after final reference to centry */
-
- CLEAR_CENTRY_INUSE(centry);
-}
-
-
-/*
- * lookup to centry info associated with safestore resource
- * return pointer to the centry info structure
- */
-ss_centry_info_t *
-sdbc_get_cinfo_byres(ss_resource_t *res)
-{
- ss_centry_info_t *cinfo;
- ss_centry_info_t *cend;
- int found = 0;
-
- ASSERT(res != NULL);
-
- if (res == NULL)
- return (NULL);
-
- cinfo = _sdbc_gl_centry_info;
- cend = _sdbc_gl_centry_info +
- (_sdbc_gl_centry_info_size / sizeof (ss_centry_info_t)) - 1;
-
- for (; cinfo <= cend; ++cinfo)
- if (cinfo->sc_res == res) {
- ++found;
- break;
- }
-
- if (!found)
- cinfo = NULL; /* bad */
-
- return (cinfo);
-}
-
-/*
- * _sd_alloc_write - Allocate a write block (for remote mirroring)
- * and set centry->cc_write
- *
- * ARGUMENTS:
- * centry - Head of Cache chain
- * stall - pointer to stall count (no blocks avail)
- *
- * RETURNS:
- * 0 - and sets cc_write for all entries when write contl block obtained.
- * -1 - if a write control block could not be obtained.
- */
-
-int
-_sd_alloc_write(_sd_cctl_t *centry, int *stall)
-{
-
- ss_resourcelist_t *reslist;
- ss_resourcelist_t *savereslist;
- ss_resource_t *res;
- _sd_cctl_t *ce;
- int err;
- int need;
-
-
- need = 0;
-
- for (ce = centry; ce; ce = ce->cc_chain) {
- if (!(ce->cc_write))
- need++;
- }
-
- if (!need)
- return (0);
-
- if ((SSOP_ALLOCRESOURCE(sdbc_safestore, need, stall, &reslist))
- == SS_OK) {
- savereslist = reslist;
- for (ce = centry; ce; ce = ce->cc_chain) {
- if (ce->cc_write)
- continue;
- err = SSOP_GETRESOURCE(sdbc_safestore, &reslist, &res);
- if (err == SS_OK)
- ce->cc_write = sdbc_get_cinfo_byres(res);
-
- ASSERT(err == SS_OK); /* panic if DEBUG on */
- ASSERT(ce->cc_write != NULL);
-
- /*
- * this is bad and should not happen.
- * we use the saved reslist to cleanup
- * and return.
- */
- if ((err != SS_OK) || !ce->cc_write) {
-
- cmn_err(CE_WARN, "!_sd_alloc_write: "
- "bad resource list 0x%p"
- "changing to forced write thru mode",
- (void *)savereslist);
-
- (void) _sd_set_node_hint(NSC_FORCED_WRTHRU);
-
- while (SSOP_GETRESOURCE(sdbc_safestore,
- &savereslist, &res) == SS_OK) {
-
- SSOP_DEALLOCRESOURCE(sdbc_safestore,
- res);
- }
-
- return (-1);
-
- }
-
- }
- return (0);
- }
-
- /* no safestore resources available. do sync write */
- _sd_unblock(&_sd_flush_cv);
- return (-1);
-}
-
-/*
- * _sd_read - Interface call to do read.
- *
- * ARGUMENTS:
- * handle - handle allocated earlier on.
- * fba_pos - disk block number to read from.
- * fba_len - length in fbas.
- * flag - flag: (NSC_NOBLOCK for async io)
- *
- * RETURNS:
- * errno if return > 0
- * NSC_DONE or NSC_PENDING otherwise.
- *
- * USAGE:
- * This routine checks if the request is valid and calls the underlying
- * doread routine (also called by alloc_buf)
- */
-
-int
-_sd_read(_sd_buf_handle_t *handle, nsc_off_t fba_pos, nsc_size_t fba_len,
- int flag)
-{
- sdbc_cblk_fba_t st_cblk_len; /* FBA len of starting cache block */
- sdbc_cblk_fba_t end_cblk_len; /* FBA len of ending cache block */
- sdbc_cblk_fba_t st_cblk_off; /* FBA offset into starting cblock */
- _sd_cctl_t *cc_ent = NULL;
- nsc_size_t fba_orig_len = fba_len;
- int ret;
- int cd = HANDLE_CD(handle);
-
- if (_sdbc_shutdown_in_progress || (handle->bh_flag & NSC_ABUF)) {
- ret = EIO;
- goto out;
- }
-
-
-#if !defined(_SD_NOCHECKS)
- if (!_SD_HANDLE_ACTIVE(handle)) {
- cmn_err(CE_WARN, "!sdbc(_sd_read) handle %p not active",
- (void *)handle);
- ret = EINVAL;
- goto out;
- }
- ASSERT_HANDLE_LIMITS(handle, fba_pos, fba_len);
-#endif
- if (fba_len == 0) {
- ret = NSC_DONE;
- goto out;
- }
-
- KSTAT_RUNQ_ENTER(cd);
-
- st_cblk_off = BLK_FBA_OFF(fba_pos);
- st_cblk_len = BLK_FBAS - st_cblk_off;
- if ((nsc_size_t)st_cblk_len >= fba_len) {
- end_cblk_len = 0;
- st_cblk_len = (sdbc_cblk_fba_t)fba_len;
- } else {
- end_cblk_len = BLK_FBA_OFF(fba_pos + fba_len);
- }
-
- cc_ent = handle->bh_centry;
- while (CENTRY_BLK(cc_ent) != FBA_TO_BLK_NUM(fba_pos))
- cc_ent = cc_ent->cc_chain;
-
- if (!SDBC_VALID_BITS(st_cblk_off, st_cblk_len, cc_ent))
- goto need_io;
- DATA_LOG(SDF_RD, cc_ent, st_cblk_off, st_cblk_len);
-
- DTRACE_PROBE4(_sd_read_data1, uint64_t,
- (uint64_t)(BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent)) + st_cblk_off),
- uint64_t, (uint64_t)st_cblk_len, char *,
- *(int64_t *)(cc_ent->cc_data + FBA_SIZE(st_cblk_off)),
- char *, *(int64_t *)(cc_ent->cc_data +
- FBA_SIZE(st_cblk_off + st_cblk_len) - 8));
-
- fba_pos += st_cblk_len;
- fba_len -= st_cblk_len;
- cc_ent = cc_ent->cc_chain;
-
- while (fba_len > (nsc_size_t)end_cblk_len) {
- if (!FULLY_VALID(cc_ent))
- goto need_io;
- DATA_LOG(SDF_RD, cc_ent, 0, BLK_FBAS);
-
- DTRACE_PROBE4(_sd_read_data2, uint64_t,
- (uint64_t)BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent)),
- uint64_t, (uint64_t)BLK_FBAS,
- char *, *(int64_t *)(cc_ent->cc_data),
- char *, *(int64_t *)(cc_ent->cc_data +
- FBA_SIZE(BLK_FBAS) - 8));
-
- fba_pos += BLK_FBAS;
- fba_len -= BLK_FBAS;
- cc_ent = cc_ent->cc_chain;
- }
- if (fba_len) {
- if (!SDBC_VALID_BITS(0, end_cblk_len, cc_ent))
- goto need_io;
- DATA_LOG(SDF_RD, cc_ent, 0, end_cblk_len);
-
- DTRACE_PROBE4(_sd_read_data3, uint64_t,
- (uint64_t)BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent)),
- uint64_t, (uint64_t)end_cblk_len,
- char *, *(int64_t *)(cc_ent->cc_data),
- char *, *(int64_t *)(cc_ent->cc_data +
- FBA_SIZE(end_cblk_len) - 8));
- }
-
- CACHE_FBA_READ(handle->bh_cd, fba_orig_len);
- CACHE_READ_HIT;
-
- FBA_READ_IO_KSTATS(handle->bh_cd, FBA_SIZE(fba_orig_len));
-
- ret = NSC_HIT;
- goto stats_exit;
-need_io:
- _SD_DISCONNECT_CALLBACK(handle);
-
- ret = _sd_doread(handle, cc_ent, fba_pos, fba_len, flag);
-
-stats_exit:
- KSTAT_RUNQ_EXIT(cd);
-out:
- return (ret);
-}
-
-
-/*
- * sdbc_doread_prefetch - read ahead one cache block
- *
- * ARGUMENTS:
- * cc_ent - cache entry
- * fba_pos - disk block number to read from
- * fba_len - length in fbas.
- *
- * RETURNS:
- * number of fbas, if any, that are to be read beyond (fba_pos + fba_len)
- *
- * USAGE:
- * if readahead is to be done allocate a cache block and place
- * on the cc_chain of cc_ent
- */
-static int
-sdbc_doread_prefetch(_sd_cctl_t *cc_ent, nsc_off_t fba_pos, nsc_size_t fba_len)
-{
- nsc_off_t st_cblk = FBA_TO_BLK_NUM(fba_pos);
- nsc_off_t next_cblk = FBA_TO_BLK_NUM(fba_pos + BLK_FBAS);
- nsc_size_t filesize;
- int fba_count = 0; /* number of fbas to prefetch */
- _sd_cctl_t *cc_ra; /* the read ahead cache entry */
- int cd = CENTRY_CD(cc_ent);
- nsc_size_t vol_fill;
-
- filesize = _sd_cache_files[cd].cd_info->sh_filesize;
- vol_fill = filesize - (fba_pos + fba_len);
-
- /* readahead only for small reads */
- if ((fba_len <= FBA_LEN(CACHE_BLOCK_SIZE)) && (fba_pos != 0) &&
- (vol_fill > 0)) {
-
- /*
- * if prev block is in cache and next block is not,
- * then read ahead one block
- */
- if (_sd_hash_search(cd, st_cblk - 1, _sd_htable)) {
- if (!_sd_hash_search(cd, next_cblk, _sd_htable)) {
-
- cc_ra = sdbc_centry_alloc_blks
- (cd, next_cblk, 1, ALLOC_NOWAIT);
- if (cc_ra) {
- /* if in cache don't readahead */
- if (cc_ra->cc_aging_dm &
- HASH_ENTRY_DM) {
- ++sdbc_ra_hash;
- _sd_centry_release(cc_ra);
- } else {
- cc_ent->cc_chain = cc_ra;
- cc_ra->cc_chain = 0;
- fba_count =
- (vol_fill >
- (nsc_size_t)BLK_FBAS) ?
- BLK_FBAS : (int)vol_fill;
- /*
- * indicate implicit prefetch
- * and mark for release in
- * _sd_read_complete()
- */
- cc_ra->cc_aging_dm |=
- (PREFETCH_BUF_I |
- PREFETCH_BUF_IR);
- }
- } else {
- ++sdbc_ra_none;
- }
- }
- }
-
- }
-
- return (fba_count);
-}
-
-/*
- * _sd_doread - Check if blocks in cache. If not completely true, do io.
- *
- * ARGUMENTS:
- * handle - handle allocated earlier on.
- * fba_pos - disk block number to read from.
- * fba_len - length in fbas.
- * flag - flag: (NSC_NOBLOCK for async io)
- *
- * RETURNS:
- * errno if return > 0
- * NSC_DONE(from disk), or NSC_PENDING otherwise.
- *
- * Comments:
- * It initiates an io and either blocks waiting for the completion
- * or return NSC_PENDING, depending on whether the flag bit
- * NSC_NOBLOCK is reset or set.
- *
- */
-
-
-static int
-_sd_doread(_sd_buf_handle_t *handle, _sd_cctl_t *cc_ent, nsc_off_t fba_pos,
- nsc_size_t fba_len, int flag)
-{
- int cd, err;
- nsc_size_t fba_orig_len; /* length in FBA's of the original request */
- nsc_size_t file_len; /* length in bytes of io to be done */
- sdbc_cblk_fba_t st_cblk_len; /* FBA len of starting cache block */
- sdbc_cblk_fba_t end_cblk_len; /* FBA len of ending cache block */
- sdbc_cblk_fba_t st_cblk_off; /* FBA offset into starting cblock */
- int num_bdl;
- _sd_cctl_t *cc_temp;
- struct buf *bp;
- unsigned int want_bits;
- void (*fn)(blind_t, nsc_off_t, nsc_size_t, int);
- sdbc_cblk_fba_t end_cblk_fill; /* FBA's to fill to end of last block */
- nsc_size_t vol_end_fill; /* # of FBA's to fill to end of the volume */
-
- cd = HANDLE_CD(handle);
- SDTRACE(ST_ENTER|SDF_READ, cd, fba_len, fba_pos, flag, 0);
-
- ASSERT(cd >= 0);
- if (_sd_cache_files[cd].cd_info->sh_failed) {
- SDTRACE(ST_EXIT|SDF_READ, cd, fba_len, fba_pos, flag, EIO);
- return (EIO);
- }
-
- /*
- * adjust the position and length so that the entire cache
- * block is read in
- */
-
- /* first, adjust to beginning of cache block */
-
- fba_len += BLK_FBA_OFF(fba_pos); /* add start offset to length */
- fba_pos &= ~BLK_FBA_MASK; /* move position back to start of block */
-
- /* compute fill to end of cache block */
- end_cblk_fill = (BLK_FBAS - 1) - ((fba_len - 1) % BLK_FBAS);
- vol_end_fill = _sd_cache_files[(cd)].cd_info->sh_filesize -
- (fba_pos + fba_len);
-
- /* fill to lesser of cache block or end of volume */
- fba_len += ((nsc_size_t)end_cblk_fill < vol_end_fill) ? end_cblk_fill :
- vol_end_fill;
-
- DTRACE_PROBE2(_sd_doread_rfill, nsc_off_t, fba_pos,
- nsc_size_t, fba_len);
-
-
- /* for small reads do 1-block readahead if previous block is in cache */
- if (sdbc_prefetch1)
- fba_len += sdbc_doread_prefetch(cc_ent, fba_pos, fba_len);
-
- fba_orig_len = fba_len;
- st_cblk_off = BLK_FBA_OFF(fba_pos);
- st_cblk_len = BLK_FBAS - st_cblk_off;
- if ((nsc_size_t)st_cblk_len >= fba_len) {
- end_cblk_len = 0;
- st_cblk_len = (sdbc_cblk_fba_t)fba_len;
- } else {
- end_cblk_len = BLK_FBA_OFF(fba_pos + fba_len);
- }
-
- cc_temp = cc_ent;
- num_bdl = 0;
- while (cc_temp) {
- num_bdl += (SDBC_LOOKUP_IOCOUNT(CENTRY_DIRTY(cc_temp)));
- cc_temp = cc_temp->cc_chain;
- }
- bp = sd_alloc_iob(_sd_cache_files[cd].cd_crdev,
- fba_pos, num_bdl, B_READ);
- if (bp == NULL) {
- SDTRACE(ST_EXIT|SDF_READ, cd, fba_len, fba_pos, flag, E2BIG);
- return (E2BIG);
- }
-
- want_bits = SDBC_GET_BITS(st_cblk_off, st_cblk_len);
- if (want_bits & CENTRY_DIRTY(cc_ent))
- _sd_ccent_rd(cc_ent, want_bits, bp);
- else {
- sd_add_fba(bp, &cc_ent->cc_addr, st_cblk_off, st_cblk_len);
- }
- file_len = FBA_SIZE(st_cblk_len);
- cc_ent = cc_ent->cc_chain;
- fba_len -= st_cblk_len;
-
- while (fba_len > (nsc_size_t)end_cblk_len) {
- if (CENTRY_DIRTY(cc_ent))
- _sd_ccent_rd(cc_ent, (uint_t)BLK_FBA_BITS, bp);
- else {
- sd_add_fba(bp, &cc_ent->cc_addr, 0, BLK_FBAS);
- }
- file_len += CACHE_BLOCK_SIZE;
- cc_ent = cc_ent->cc_chain;
- fba_len -= BLK_FBAS;
- }
-
- if (fba_len) {
- want_bits = SDBC_GET_BITS(0, end_cblk_len);
- if (want_bits & CENTRY_DIRTY(cc_ent))
- _sd_ccent_rd(cc_ent, want_bits, bp);
- else {
- sd_add_fba(bp, &cc_ent->cc_addr, 0, end_cblk_len);
- }
- file_len += FBA_SIZE(end_cblk_len);
- }
-
- CACHE_READ_MISS;
- FBA_READ_IO_KSTATS(cd, file_len);
-
- DISK_FBA_READ(cd, FBA_NUM(file_len));
-
- fn = (handle->bh_flag & NSC_NOBLOCK) ? _sd_async_read_ea : NULL;
- err = sd_start_io(bp, _sd_cache_files[cd].cd_strategy, fn, handle);
-
- if (err != NSC_PENDING) {
- _sd_read_complete(handle, fba_pos, fba_orig_len, err);
- }
-
- SDTRACE(ST_EXIT|SDF_READ, cd, fba_orig_len, fba_pos, flag, err);
-
- return (err);
-}
-
-
-
-/*
- * _sd_read_complete - Do whatever is necessary after a read io is done.
- *
- * ARGUMENTS:
- * handle - handle allocated earlier on.
- * fba_pos - disk block number to read from.
- * fba_len - length in fbas.
- * error - error from io if any.
- *
- * RETURNS:
- * NONE.
- *
- * Comments:
- * This routine marks the cache blocks valid if the io completed
- * sucessfully. Called from the async end action as well as after
- * a synchrnous read completes.
- */
-
-void
-_sd_read_complete(_sd_buf_handle_t *handle, nsc_off_t fba_pos,
- nsc_size_t fba_len, int error)
-{
- sdbc_cblk_fba_t st_cblk_len; /* FBA len of starting cache block */
- sdbc_cblk_fba_t end_cblk_len; /* FBA len of ending cache block */
- sdbc_cblk_fba_t st_cblk_off; /* FBA offset into starting cblock */
- nsc_size_t cur_fba_len; /* length in FBA's */
- _sd_cctl_t *cc_iocent;
- _sd_cctl_t *first_iocent; /* first buffer when processing prefetch */
-
- cc_iocent = handle->bh_centry;
-
- if ((handle->bh_error = error) == 0) {
- while (CENTRY_BLK(cc_iocent) != FBA_TO_BLK_NUM(fba_pos))
- cc_iocent = cc_iocent->cc_chain;
-
- cur_fba_len = fba_len;
- st_cblk_off = BLK_FBA_OFF(fba_pos);
- st_cblk_len = BLK_FBAS - st_cblk_off;
- if ((nsc_size_t)st_cblk_len >= fba_len) {
- end_cblk_len = 0;
- st_cblk_len = (sdbc_cblk_fba_t)fba_len;
- } else {
- end_cblk_len = BLK_FBA_OFF(fba_pos + fba_len);
- }
-
- SDBC_SET_VALID_BITS(st_cblk_off, st_cblk_len, cc_iocent);
- DATA_LOG(SDF_RDIO, cc_iocent, st_cblk_off, st_cblk_len);
-
- DTRACE_PROBE4(_sd_read_complete_data1, uint64_t, (uint64_t)
- BLK_TO_FBA_NUM(CENTRY_BLK(cc_iocent)) + st_cblk_off,
- int, st_cblk_len, char *,
- *(int64_t *)(cc_iocent->cc_data + FBA_SIZE(st_cblk_off)),
- char *, *(int64_t *)(cc_iocent->cc_data +
- FBA_SIZE(st_cblk_off + st_cblk_len) - 8));
-
-
- first_iocent = cc_iocent;
- cc_iocent = cc_iocent->cc_chain;
- cur_fba_len -= st_cblk_len;
-
- while (cur_fba_len > (nsc_size_t)end_cblk_len) {
- SET_FULLY_VALID(cc_iocent);
- DATA_LOG(SDF_RDIO, cc_iocent, 0, BLK_FBAS);
-
- DTRACE_PROBE4(_sd_read_complete_data2, uint64_t,
- (uint64_t)BLK_TO_FBA_NUM(CENTRY_BLK(cc_iocent)),
- int, BLK_FBAS, char *,
- *(int64_t *)(cc_iocent->cc_data), char *,
- *(int64_t *)(cc_iocent->cc_data +
- FBA_SIZE(BLK_FBAS) - 8));
-
- /*
- * 4755485 release implicit prefetch buffers
- *
- * the cc_chain of the first buffer must NULL'd
- * else _sd_free_buf() will do a double free when
- * it traverses the chain.
- *
- * if a buffer has been marked PREFETCH_BUF_IR then
- * it is guaranteed that
- * 1. it is the second in a chain of two.
- * 2. cur_fba_len is BLK_FBAS.
- * 3. end_cblk_len is zero.
- *
- * because of 1 (and 2) above, we can safely exit the
- * while loop via the break statement without
- * executing the last two statements. the break
- * statement is necessary because it would be unsafe
- * to access cc_iocent which could be reallocated
- * immediately after the _sd_centry_release().
- */
- if (cc_iocent->cc_aging_dm & PREFETCH_BUF_IR) {
- cc_iocent->cc_aging_dm &= ~(PREFETCH_BUF_IR);
- _sd_centry_release(cc_iocent);
- first_iocent->cc_chain = NULL;
- break;
- }
-
- cc_iocent = cc_iocent->cc_chain;
- cur_fba_len -= BLK_FBAS;
- }
- if (end_cblk_len) {
- SDBC_SET_VALID_BITS(0, end_cblk_len, cc_iocent);
- DATA_LOG(SDF_RDIO, cc_iocent, 0, end_cblk_len);
-
- DTRACE_PROBE4(_sd_read_complete_data3, uint64_t,
- (uint64_t)BLK_TO_FBA_NUM(CENTRY_BLK(cc_iocent)),
- int, end_cblk_len, char *,
- *(int64_t *)(cc_iocent->cc_data), char *,
- *(int64_t *)(cc_iocent->cc_data +
- FBA_SIZE(end_cblk_len) - 8));
- }
- }
-
-}
-
-
-/*
- * _sd_async_read_ea - End action for async reads.
- *
- * ARGUMENTS:
- * xhandle - handle allocated earlier on (cast to blind_t).
- * fba_pos - disk block number read from.
- * fba_len - length in fbas.
- * error - error from io if any.
- *
- * RETURNS:
- * NONE.
- *
- * Comments:
- * This routine is called at interrupt level when the io is done.
- * This is called only when read is asynchronous (NSC_NOBLOCK)
- */
-
-static void
-_sd_async_read_ea(blind_t xhandle, nsc_off_t fba_pos, nsc_size_t fba_len,
- int error)
-{
- _sd_buf_handle_t *handle = xhandle;
- int cd;
-
- if (error) {
- cd = HANDLE_CD(handle);
- ASSERT(cd >= 0);
- _sd_cache_files[cd].cd_info->sh_failed = 1;
- }
- SDTRACE(ST_ENTER|SDF_READ_EA, HANDLE_CD(handle),
- handle->bh_fba_len, handle->bh_fba_pos, 0, error);
-
- _sd_read_complete(handle, fba_pos, fba_len, error);
-
-#if defined(_SD_DEBUG_PATTERN)
- check_buf_consistency(handle, "rd");
-#endif
-
- SDTRACE(ST_EXIT|SDF_READ_EA, HANDLE_CD(handle),
- handle->bh_fba_len, handle->bh_fba_pos, 0, 0);
- _SD_READ_CALLBACK(handle);
-}
-
-
-/*
- * _sd_async_write_ea - End action for async writes.
- *
- * ARGUMENTS:
- * xhandle - handle allocated earlier on. (cast to blind_t)
- * fba_pos - disk block number written to.
- * fba_len - length in fbas.
- * error - error from io if any.
- *
- * RETURNS:
- * NONE.
- *
- * Comments:
- * This routine is called at interrupt level when the write io is done.
- * This is called only when we are in write-through mode and the write
- * call indicated asynchronous callback. (NSC_NOBLOCK)
- */
-
-/* ARGSUSED */
-
-static void
-_sd_async_write_ea(blind_t xhandle, nsc_off_t fba_pos, nsc_size_t fba_len,
- int error)
-{
- _sd_buf_handle_t *handle = xhandle;
- handle->bh_error = error;
-
- if (error)
- _sd_cache_files[HANDLE_CD(handle)].cd_info->sh_failed = 1;
-
- _SD_WRITE_CALLBACK(handle);
-}
-
-/*
- * update_dirty - set dirty bits in cache block which is already dirty
- * cc_inuse is held, need cc_lock to avoid race with _sd_process_pending
- * must check for I/O in-progress and set PEND_DIRTY.
- * return previous dirty bits
- * [if set _sd_process_pending will re-issue]
- */
-static _sd_bitmap_t
-update_dirty(_sd_cctl_t *cc_ent, sdbc_cblk_fba_t st_off, sdbc_cblk_fba_t st_len)
-{
- _sd_bitmap_t old;
-
- /* was FAST */
- mutex_enter(&cc_ent->cc_lock);
- old = CENTRY_DIRTY(cc_ent);
- if (old) {
- /*
- * If we are writing to an FBA that is still marked dirty,
- * record a write cancellation.
- */
- if (old & SDBC_GET_BITS(st_off, st_len)) {
- CACHE_WRITE_CANCELLATION(CENTRY_CD(cc_ent));
- }
-
- /* This is a write to a block that was already dirty */
- SDBC_SET_DIRTY(st_off, st_len, cc_ent);
- sd_serialize();
- if (CENTRY_IO_INPROGRESS(cc_ent))
- cc_ent->cc_flag |= CC_PEND_DIRTY;
- }
- /* was FAST */
- mutex_exit(&cc_ent->cc_lock);
- return (old);
-}
-
-/*
- * _sd_write - Interface call to commit part of handle.
- *
- * ARGUMENTS:
- * handle - handle allocated earlier o.
- * fba_pos - disk block number to write to.
- * fba_len - length in fbas.
- * flag - (NSC_NOBLOCK | NSC_WRTHRU)
- *
- * RETURNS:
- * errno if return > 0
- * NSC_HIT (in cache), NSC_DONE (to disk) or NSC_PENDING otherwise.
- *
- * Comments:
- * This routine checks validity of the handle and then calls the
- * sync-write function if this write is determined to be write-through.
- * Else, it reflects the data to the write blocks on the mirror node,
- * (allocated in alloc_buf). If the cache block is not dirty, it is
- * marked dirty and queued up for io processing later on.
- * If parts are already dirty but io is not in progress yet, it is
- * marked dirty and left alone (it is already in the queue)
- * If parts are already dirty but io is in progress, it is marked
- * dirty and also a flag is set indicating that this buffer should
- * be reprocessed after the io-end-action.
- * Attempt is made to coalesce multiple writes into a single list
- * for io processing later on.
- *
- * Issuing of writes may be delayed until the handle is released;
- * _sd_queue_write() sets NSC_QUEUE, indicating that dirty bits
- * and reflection to mirror have already been done, just queue I/O.
- */
-
-
-
-int
-_sd_write(_sd_buf_handle_t *handle, nsc_off_t fba_pos, nsc_size_t fba_len,
- int flag)
-{
- int cd = HANDLE_CD(handle);
- int num_queued, ret, queue_only, store_only;
- sdbc_cblk_fba_t st_cblk_len; /* FBA len of starting cache block */
- sdbc_cblk_fba_t end_cblk_len; /* FBA len of ending cache block */
- sdbc_cblk_fba_t st_cblk_off; /* FBA offset into starting cblock */
- nsc_size_t cur_fba_len; /* position in disk blocks */
- _sd_cctl_t *cc_ent = NULL;
- _sd_cctl_t *cur_chain = NULL, *dirty_next = NULL;
-
-
- if (_sdbc_shutdown_in_progress) {
- ret = EIO;
- goto out;
- }
-
-
- if (!_SD_HANDLE_ACTIVE(handle)) {
- SDALERT(SDF_WRITE,
- SDT_INV_CD, 0, SDT_INV_BL, handle->bh_flag, 0);
- ret = EINVAL;
- goto out;
- }
-#if !defined(_SD_NOCHECKS)
- ASSERT_HANDLE_LIMITS(handle, fba_pos, fba_len);
- if ((handle->bh_flag & NSC_WRBUF) == 0) {
- ret = EINVAL;
- goto out;
- }
-#endif
- if (fba_len == 0) {
- ret = NSC_DONE;
- goto out;
- }
-
- /*
- * store_only: don't queue this I/O yet
- * queue_only: queue I/O to disk, don't store in mirror node
- */
- if (flag & NSC_QUEUE)
- queue_only = 1, store_only = 0;
- else
- if (_SD_DELAY_QUEUE && (fba_len != handle->bh_fba_len))
- queue_only = 0, store_only = 1;
- else
- queue_only = store_only = 0;
-
- if (!queue_only && _SD_FORCE_DISCONNECT(fba_len))
- _SD_DISCONNECT_CALLBACK(handle);
-
- if (_sd_cache_files[cd].cd_info->sh_failed) {
- ret = EIO;
- goto out;
- }
-
- KSTAT_RUNQ_ENTER(cd);
-
- SDTRACE(ST_ENTER|SDF_WRITE, cd, fba_len, fba_pos, flag, 0);
-
-#if defined(_SD_DEBUG_PATTERN)
- check_buf_consistency(handle, "wr");
-#endif
-
- cc_ent = handle->bh_centry;
-
- while (CENTRY_BLK(cc_ent) != FBA_TO_BLK_NUM(fba_pos))
- cc_ent = cc_ent->cc_chain;
-
- if (((handle->bh_flag | flag) & _SD_WRTHRU_MASK) ||
- (!queue_only && _sd_remote_store(cc_ent, fba_pos, fba_len))) {
- flag |= NSC_WRTHRU;
-
- ret = _sd_sync_write(handle, fba_pos, fba_len, flag);
- goto stats_exit;
- }
-
- if (store_only) /* enqueue in _sd_free_buf() */
- handle->bh_flag |= NSC_QUEUE;
- cur_fba_len = fba_len;
- st_cblk_off = BLK_FBA_OFF(fba_pos);
- st_cblk_len = BLK_FBAS - st_cblk_off;
- if ((nsc_size_t)st_cblk_len >= fba_len) {
- end_cblk_len = 0;
- st_cblk_len = (sdbc_cblk_fba_t)fba_len;
- } else {
- end_cblk_len = BLK_FBA_OFF(fba_pos + fba_len);
- }
-
- if (CENTRY_DIRTY(cc_ent) && update_dirty(cc_ent, st_cblk_off,
- st_cblk_len))
- goto loop1;
- if (store_only) {
- SDBC_SET_TOFLUSH(st_cblk_off, st_cblk_len, cc_ent);
- goto loop1;
- }
- SDBC_SET_DIRTY(st_cblk_off, st_cblk_len, cc_ent);
- cur_chain = dirty_next = cc_ent;
- num_queued = 1;
-
-loop1:
- DATA_LOG(SDF_WR, cc_ent, st_cblk_off, st_cblk_len);
-
- DTRACE_PROBE4(_sd_write_data1, uint64_t, (uint64_t)
- (BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent)) + st_cblk_off),
- int, st_cblk_len, char *,
- *(int64_t *)(cc_ent->cc_data + FBA_SIZE(st_cblk_off)),
- char *, *(int64_t *)(cc_ent->cc_data +
- FBA_SIZE(st_cblk_off+ st_cblk_len) - 8));
-
- cur_fba_len -= st_cblk_len;
- cc_ent = cc_ent->cc_chain;
-
- while (cur_fba_len > (nsc_size_t)end_cblk_len) {
- if (CENTRY_DIRTY(cc_ent) && update_dirty(cc_ent, 0, BLK_FBAS)) {
- if (cur_chain) {
- _sd_enqueue_dirty(cd, cur_chain, dirty_next,
- num_queued);
- cur_chain = dirty_next = NULL;
- }
- goto loop2;
- }
- if (store_only) {
- SDBC_SET_TOFLUSH(0, BLK_FBAS, cc_ent);
- goto loop2;
- }
- SDBC_SET_DIRTY(0, BLK_FBAS, cc_ent);
- if (dirty_next) {
- dirty_next->cc_dirty_next = cc_ent;
- dirty_next = cc_ent;
- num_queued++;
- } else {
- cur_chain = dirty_next = cc_ent;
- num_queued = 1;
- }
- loop2:
- DATA_LOG(SDF_WR, cc_ent, 0, BLK_FBAS);
-
- DTRACE_PROBE4(_sd_write_data2, uint64_t,
- (uint64_t)(BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent))),
- int, BLK_FBAS, char *, *(int64_t *)(cc_ent->cc_data),
- char *, *(int64_t *)(cc_ent->cc_data +
- FBA_SIZE(BLK_FBAS) - 8));
-
- cc_ent = cc_ent->cc_chain;
- cur_fba_len -= BLK_FBAS;
- }
-
-#if defined(_SD_DEBUG)
- if (cur_fba_len != end_cblk_len)
- cmn_err(CE_WARN, "!fba_len %" NSC_SZFMT " end_cblk_len %d in "
- "_sd_write", cur_fba_len, end_cblk_len);
-#endif
-
- if (cur_fba_len) {
- if (CENTRY_DIRTY(cc_ent) && update_dirty(cc_ent, 0,
- end_cblk_len)) {
- if (cur_chain) {
- _sd_enqueue_dirty(cd, cur_chain, dirty_next,
- num_queued);
- cur_chain = dirty_next = NULL;
- }
- goto loop3;
- }
- if (store_only) {
- SDBC_SET_TOFLUSH(0, end_cblk_len, cc_ent);
- goto loop3;
- }
- SDBC_SET_DIRTY(0, end_cblk_len, cc_ent);
- if (dirty_next) {
- dirty_next->cc_dirty_next = cc_ent;
- dirty_next = cc_ent;
- num_queued++;
- } else {
- cur_chain = dirty_next = cc_ent;
- num_queued = 1;
- }
- }
-loop3:
- if (cur_fba_len) {
- DATA_LOG(SDF_WR, cc_ent, 0, end_cblk_len);
-
- DTRACE_PROBE4(_sd_write_data3, uint64_t,
- (uint64_t)(BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent))),
- int, end_cblk_len, char *, *(int64_t *)(cc_ent->cc_data),
- char *, *(int64_t *)(cc_ent->cc_data +
- FBA_SIZE(end_cblk_len) - 8));
-
- }
-
- if (!store_only && cur_chain) {
- _sd_enqueue_dirty(cd, cur_chain, dirty_next, num_queued);
- }
-
- if (!queue_only) {
- CACHE_FBA_WRITE(cd, fba_len);
- CACHE_WRITE_HIT;
-
- FBA_WRITE_IO_KSTATS(cd, FBA_SIZE(fba_len));
- }
-
- ret = NSC_HIT;
-
-stats_exit:
- SDTRACE(ST_EXIT|SDF_WRITE, cd, fba_len, fba_pos, flag, ret);
- KSTAT_RUNQ_EXIT(cd);
-out:
- return (ret);
-}
-
-
-/*
- * _sd_queue_write(handle, fba_pos, fba_len): Queues delayed writes for
- * flushing
- *
- * ARGUMENTS: handle - handle allocated with NSC_WRBUF
- * fba_pos - starting fba pos from _sd_alloc_buf()
- * fba_len - fba len from _sd_alloc_buf()
- *
- * USAGE : Called if _SD_DELAY_QUEUE is set. Finds all blocks in the
- * handle marked for flushing and queues them to be written in
- * optimized (i.e. sequential) order
- */
-static void
-_sd_queue_write(_sd_buf_handle_t *handle, nsc_off_t fba_pos, nsc_size_t fba_len)
-{
- nsc_off_t fba_end;
- sdbc_cblk_fba_t sblk, len, dirty;
- _sd_cctl_t *cc_ent;
- nsc_off_t flush_pos;
- int flush_pos_valid = 0;
- nsc_size_t flush_len = 0;
-
- cc_ent = handle->bh_centry;
- fba_end = fba_pos + fba_len;
- fba_pos = BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent)); /* 1st block */
- while (fba_pos < fba_end) {
- dirty = cc_ent->cc_toflush;
- cc_ent->cc_toflush = 0;
- /*
- * Full block
- */
- if (_SD_BMAP_ISFULL(dirty)) {
- if (flush_pos_valid == 0) {
- flush_pos_valid = 1;
- flush_pos = fba_pos;
- }
- flush_len += BLK_FBAS;
- }
- /*
- * Partial block
- */
- else while (dirty) {
- sblk = SDBC_LOOKUP_STPOS(dirty);
- len = SDBC_LOOKUP_LEN(dirty);
- SDBC_LOOKUP_MODIFY(dirty);
-
- if (sblk && flush_pos_valid) {
- (void) _sd_write(handle, flush_pos, flush_len,
- NSC_QUEUE);
- flush_pos_valid = 0;
- flush_len = 0;
- }
- if (flush_pos_valid == 0) {
- flush_pos_valid = 1;
- flush_pos = fba_pos + sblk;
- }
- flush_len += len;
- }
- fba_pos += BLK_FBAS;
- cc_ent = cc_ent->cc_chain;
- /*
- * If we find a gap, write out what we've got
- */
- if (flush_pos_valid && (flush_pos + flush_len) != fba_pos) {
- (void) _sd_write(handle, flush_pos, flush_len,
- NSC_QUEUE);
- flush_pos_valid = 0;
- flush_len = 0;
- }
- }
- if (flush_pos_valid)
- (void) _sd_write(handle, flush_pos, flush_len, NSC_QUEUE);
-}
-
-
-static int
-_sd_remote_store(_sd_cctl_t *cc_ent, nsc_off_t fba_pos, nsc_size_t fba_len)
-{
- sdbc_cblk_fba_t st_cblk_len; /* FBA len of starting cache block */
- sdbc_cblk_fba_t end_cblk_len; /* FBA len of ending cache block */
- sdbc_cblk_fba_t st_cblk_off; /* FBA offset into starting cblock */
- ss_resource_t *ss_res;
-
- if (_sd_nodes_configured <= 2 && _sd_is_mirror_down())
- return (0);
- st_cblk_off = BLK_FBA_OFF(fba_pos);
- st_cblk_len = BLK_FBAS - st_cblk_off;
- if ((nsc_size_t)st_cblk_len >= fba_len) {
- end_cblk_len = 0;
- st_cblk_len = (sdbc_cblk_fba_t)fba_len;
- } else {
- end_cblk_len = BLK_FBA_OFF(fba_pos + fba_len);
- }
-
- fba_len -= st_cblk_len;
-
- ss_res = cc_ent->cc_write->sc_res;
- if (SSOP_WRITE_CBLOCK(sdbc_safestore, ss_res,
- cc_ent->cc_data + FBA_SIZE(st_cblk_off), FBA_SIZE(st_cblk_len),
- FBA_SIZE(st_cblk_off))) {
-
- cmn_err(CE_WARN,
- "!sdbc(_sd_write) safe store failed. Going synchronous");
- SDTRACE(SDF_REFLECT, CENTRY_CD(cc_ent), fba_len,
- fba_pos, 0, -1);
- return (-1);
- }
-
- cc_ent = cc_ent->cc_chain;
- while (fba_len > (nsc_size_t)end_cblk_len) {
- fba_len -= BLK_FBAS;
-
- if (SSOP_WRITE_CBLOCK(sdbc_safestore, ss_res, cc_ent->cc_data,
- CACHE_BLOCK_SIZE, 0)) {
-
- cmn_err(CE_WARN, "!sdbc(_sd_write) safe store failed. "
- "Going synchronous");
- SDTRACE(SDF_REFLECT, CENTRY_CD(cc_ent), fba_len,
- fba_pos, 0, -1);
- return (-1);
- }
-
- cc_ent = cc_ent->cc_chain;
- } /* end while */
-
- if (fba_len) {
- if (SSOP_WRITE_CBLOCK(sdbc_safestore, ss_res,
- cc_ent->cc_data, FBA_SIZE(end_cblk_len), 0)) {
-
- cmn_err(CE_WARN, "!sdbc(_sd_write) nvmem dma failed. "
- "Going synchronous");
- SDTRACE(SDF_REFLECT, CENTRY_CD(cc_ent), fba_len,
- fba_pos, 0, -1);
- return (-1);
- }
- }
- return (0);
-}
-
-
-/*
- * _sd_sync_write2 - Write-through function.
- *
- * ARGUMENTS:
- * wr_handle - handle into which to write the data.
- * wr_st_pos - starting FBA position in wr_handle.
- * fba_len - length in fbas.
- * flag - NSC_NOBLOCK for async io.
- * rd_handle - handle from which to read the data, or NULL.
- * rd_st_pos - starting FBA position in rd_handle.
- *
- * RETURNS:
- * errno if return > 0
- * NSC_DONE or NSC_PENDING otherwise.
- *
- * Comments:
- * This routine initiates io of the indicated portion. It returns
- * synchronously after io is completed if NSC_NOBLOCK is not set.
- * Else NSC_PENDING is returned with a subsequent write callback on
- * io completion.
- *
- * See _sd_copy_direct() for usage when
- * (wr_handle != rd_handle && rd_handle != NULL)
- */
-
-static int
-_sd_sync_write2(_sd_buf_handle_t *wr_handle, nsc_off_t wr_st_pos,
- nsc_size_t fba_len, int flag, _sd_buf_handle_t *rd_handle,
- nsc_off_t rd_st_pos)
-{
- void (*fn)(blind_t, nsc_off_t, nsc_size_t, int);
- _sd_cctl_t *wr_ent, *rd_ent;
- nsc_size_t this_len;
- nsc_off_t rd_pos, wr_pos;
- nsc_size_t log_bytes;
- int cd = HANDLE_CD(wr_handle);
- int err;
- uint_t dirty;
- struct buf *bp;
-
- LINTUSED(flag);
-
- _SD_DISCONNECT_CALLBACK(wr_handle);
-
- if (rd_handle == NULL) {
- rd_handle = wr_handle;
- rd_st_pos = wr_st_pos;
- }
-
- wr_ent = wr_handle->bh_centry;
- while (CENTRY_BLK(wr_ent) != FBA_TO_BLK_NUM(wr_st_pos))
- wr_ent = wr_ent->cc_chain;
-
- rd_ent = rd_handle->bh_centry;
- while (CENTRY_BLK(rd_ent) != FBA_TO_BLK_NUM(rd_st_pos))
- rd_ent = rd_ent->cc_chain;
-
- bp = sd_alloc_iob(_sd_cache_files[cd].cd_crdev,
- wr_st_pos, FBA_TO_BLK_LEN(fba_len) + 2, B_WRITE);
-
- if (bp == NULL)
- return (E2BIG);
-
- wr_pos = BLK_FBA_OFF(wr_st_pos);
- rd_pos = BLK_FBA_OFF(rd_st_pos);
- log_bytes = 0;
-
- do {
- this_len = min((BLK_FBAS - rd_pos), (BLK_FBAS - wr_pos));
-
- if (this_len > fba_len)
- this_len = fba_len;
-
- /*
- * clear dirty bits in the write handle.
- */
-
- if (CENTRY_DIRTY(wr_ent)) {
- mutex_enter(&wr_ent->cc_lock);
-
- if (CENTRY_DIRTY(wr_ent)) {
- if (this_len == (nsc_size_t)BLK_FBAS ||
- rd_handle != wr_handle) {
- /*
- * optimization for when we have a
- * full cache block, or are doing
- * copy_direct (see below).
- */
-
- wr_ent->cc_write->sc_dirty = 0;
- } else {
- dirty = wr_ent->cc_write->sc_dirty;
- dirty &= ~(SDBC_GET_BITS(
- wr_pos, this_len));
- wr_ent->cc_write->sc_dirty = dirty;
- }
-
- SSOP_SETCENTRY(sdbc_safestore,
- wr_ent->cc_write);
- }
-
- mutex_exit(&wr_ent->cc_lock);
- }
-
- /*
- * update valid bits in the write handle.
- */
-
- if (rd_handle == wr_handle) {
- if (this_len == (nsc_size_t)BLK_FBAS) {
- SET_FULLY_VALID(wr_ent);
- } else {
- SDBC_SET_VALID_BITS(wr_pos, this_len, wr_ent);
- }
- } else {
- /*
- * doing copy_direct, so mark the write handle
- * as invalid since the data is on disk, but not
- * in cache.
- */
- wr_ent->cc_valid = 0;
- }
-
- DATA_LOG(SDF_WRSYNC, rd_ent, rd_pos, this_len);
-
- DTRACE_PROBE4(_sd_sync_write2_data, uint64_t,
- (uint64_t)BLK_TO_FBA_NUM(CENTRY_BLK(rd_ent)) + rd_pos,
- uint64_t, (uint64_t)this_len, char *,
- *(int64_t *)(rd_ent->cc_data + FBA_SIZE(rd_pos)),
- char *, *(int64_t *)(rd_ent->cc_data +
- FBA_SIZE(rd_pos + this_len) - 8));
-
- sd_add_fba(bp, &rd_ent->cc_addr, rd_pos, this_len);
-
- log_bytes += FBA_SIZE(this_len);
- fba_len -= this_len;
-
- wr_pos += this_len;
- if (wr_pos >= (nsc_size_t)BLK_FBAS) {
- wr_ent = wr_ent->cc_chain;
- wr_pos = 0;
- }
-
- rd_pos += this_len;
- if (rd_pos >= (nsc_size_t)BLK_FBAS) {
- rd_ent = rd_ent->cc_chain;
- rd_pos = 0;
- }
-
- } while (fba_len > 0);
-
- DISK_FBA_WRITE(cd, FBA_NUM(log_bytes));
- CACHE_WRITE_MISS;
-
- FBA_WRITE_IO_KSTATS(cd, log_bytes);
-
- fn = (wr_handle->bh_flag & NSC_NOBLOCK) ? _sd_async_write_ea : NULL;
-
- err = sd_start_io(bp, _sd_cache_files[cd].cd_strategy, fn, wr_handle);
-
- if (err != NSC_PENDING) {
- DATA_LOG_CHAIN(SDF_WRSYEA, wr_handle->bh_centry,
- wr_st_pos, FBA_NUM(log_bytes));
- }
-
- return (err);
-}
-
-
-static int
-_sd_sync_write(_sd_buf_handle_t *handle, nsc_off_t fba_pos, nsc_size_t fba_len,
- int flag)
-{
- return (_sd_sync_write2(handle, fba_pos, fba_len, flag, NULL, 0));
-}
-
-
-/*
- * _sd_zero - Interface call to zero out a portion of cache blocks.
- *
- * ARGUMENTS:
- * handle - handle allocated earlier on.
- * fba_pos - disk block number to zero from.
- * fba_len - length in fbas.
- * flag - NSC_NOBLOCK for async io.
- *
- * RETURNS:
- * errno if return > 0
- * NSC_DONE or NSC_PENDING otherwise.
- *
- * Comments:
- * This routine zeroes out the indicated portion of the cache blocks
- * and commits the data to disk.
- * (See write for more details on the commit)
- */
-
-
-int
-_sd_zero(_sd_buf_handle_t *handle, nsc_off_t fba_pos, nsc_size_t fba_len,
- int flag)
-{
- int cd;
- sdbc_cblk_fba_t st_cblk_len; /* FBA len of starting cache block */
- sdbc_cblk_fba_t end_cblk_len; /* FBA len of ending cache block */
- sdbc_cblk_fba_t st_cblk_off; /* FBA offset into starting cblock */
- nsc_size_t cur_fba_len; /* position in disk blocks */
- int ret;
- _sd_cctl_t *cc_ent;
-
- if (_sdbc_shutdown_in_progress) {
- DTRACE_PROBE(shutdown);
- return (EIO);
- }
-
- if (!_SD_HANDLE_ACTIVE(handle)) {
- cmn_err(CE_WARN, "!sdbc(_sd_zero) handle %p not active",
- (void *)handle);
-
- DTRACE_PROBE1(handle_active, int, handle->bh_flag);
-
- return (EINVAL);
- }
- ASSERT_HANDLE_LIMITS(handle, fba_pos, fba_len);
- if ((handle->bh_flag & NSC_WRBUF) == 0) {
- DTRACE_PROBE1(handle_write, int, handle->bh_flag);
- return (EINVAL);
- }
-
- if (fba_len == 0) {
- DTRACE_PROBE(zero_len);
- return (NSC_DONE);
- }
-
- if (_SD_FORCE_DISCONNECT(fba_len))
- _SD_DISCONNECT_CALLBACK(handle);
-
- cd = HANDLE_CD(handle);
- SDTRACE(ST_ENTER|SDF_ZERO, cd, fba_len, fba_pos, flag, 0);
-
- cc_ent = handle->bh_centry;
- while (CENTRY_BLK(cc_ent) != FBA_TO_BLK_NUM(fba_pos))
- cc_ent = cc_ent->cc_chain;
- cur_fba_len = fba_len;
- st_cblk_off = BLK_FBA_OFF(fba_pos);
- st_cblk_len = BLK_FBAS - st_cblk_off;
- if ((nsc_size_t)st_cblk_len >= fba_len) {
- end_cblk_len = 0;
- st_cblk_len = (sdbc_cblk_fba_t)fba_len;
- } else {
- end_cblk_len = BLK_FBA_OFF(fba_pos + fba_len);
- }
-
- cur_fba_len -= st_cblk_len;
- bzero(cc_ent->cc_data + FBA_SIZE(st_cblk_off), FBA_SIZE(st_cblk_len));
-
- cc_ent = cc_ent->cc_chain;
- while (cur_fba_len > (nsc_size_t)end_cblk_len) {
- cur_fba_len -= BLK_FBAS;
- bzero(cc_ent->cc_data, CACHE_BLOCK_SIZE);
- cc_ent = cc_ent->cc_chain;
- }
- if (cur_fba_len) {
- bzero(cc_ent->cc_data, FBA_SIZE(cur_fba_len));
- }
-
- ret = _sd_write(handle, fba_pos, fba_len, flag);
- SDTRACE(ST_EXIT|SDF_ZERO, cd, fba_len, fba_pos, flag, ret);
-
- return (ret);
-}
-
-
-/*
- * _sd_copy - Copies portions of 2 handles.
- *
- * ARGUMENTS:
- * handle1 - handle allocated earlier on.
- * handle2 - handle allocated earlier on.
- * fba_pos1 - disk block number to read from.
- * fba_pos2 - disk block number to write to.
- * fba_len - length in fbas.
- *
- * RETURNS:
- * errno if return > 0
- * NSC_DONE otherwise.
- *
- * Comments:
- * This routine copies the 2 handles.
- * WARNING: this could put the cache blocks in the destination handle
- * in an inconsistent state. (the blocks could be valid in cache,
- * but the copy makes the cache different from disk)
- *
- */
-
-
-int
-_sd_copy(_sd_buf_handle_t *handle1, _sd_buf_handle_t *handle2,
- nsc_off_t fba_pos1, nsc_off_t fba_pos2, nsc_size_t fba_len)
-{
- sdbc_cblk_fba_t st_cblk_len; /* FBA len of starting cache block */
- sdbc_cblk_fba_t end_cblk_len; /* FBA len of ending cache block */
- sdbc_cblk_fba_t st_cblk_off; /* FBA offset into starting cblock */
- nsc_off_t off1, off2; /* offsets in FBA's into the disk */
- nsc_size_t cur_fba_len; /* position in disk blocks */
- _sd_cctl_t *cc_ent1, *cc_ent2;
-
- if (_sdbc_shutdown_in_progress) {
- DTRACE_PROBE(shutdown);
- return (EIO);
- }
- if (!_SD_HANDLE_ACTIVE(handle1) || !_SD_HANDLE_ACTIVE(handle2)) {
- cmn_err(CE_WARN, "!sdbc(_sd_copy) handle %p or %p not active",
- (void *)handle1, (void *)handle2);
-
- DTRACE_PROBE2(handle_active1, int, handle1->bh_flag,
- int, handle2->bh_flag);
-
- return (EINVAL);
- }
- ASSERT_HANDLE_LIMITS(handle1, fba_pos1, fba_len);
- ASSERT_HANDLE_LIMITS(handle2, fba_pos2, fba_len);
-
- cc_ent1 = handle1->bh_centry;
- while (CENTRY_BLK(cc_ent1) != FBA_TO_BLK_NUM(fba_pos1))
- cc_ent1 = cc_ent1->cc_chain;
-
- cc_ent2 = handle2->bh_centry;
- while (CENTRY_BLK(cc_ent2) != FBA_TO_BLK_NUM(fba_pos2))
- cc_ent2 = cc_ent2->cc_chain;
-
- if (BLK_FBA_OFF(fba_pos1) != BLK_FBA_OFF(fba_pos2)) {
- /* Different offsets, do it slowly (per fba) */
-
- while (fba_len) {
- off1 = FBA_SIZE(BLK_FBA_OFF(fba_pos1));
- off2 = FBA_SIZE(BLK_FBA_OFF(fba_pos2));
-
- bcopy(cc_ent1->cc_data+off1, cc_ent2->cc_data+off2,
- FBA_SIZE(1));
-
- fba_pos1++;
- fba_pos2++;
- fba_len--;
-
- if (FBA_TO_BLK_NUM(fba_pos1) != CENTRY_BLK(cc_ent1))
- cc_ent1 = cc_ent1->cc_chain;
- if (FBA_TO_BLK_NUM(fba_pos2) != CENTRY_BLK(cc_ent2))
- cc_ent2 = cc_ent2->cc_chain;
- }
-
- DTRACE_PROBE(_sd_copy_end);
- return (NSC_DONE);
- }
- cur_fba_len = fba_len;
- st_cblk_off = BLK_FBA_OFF(fba_pos1);
- st_cblk_len = BLK_FBAS - st_cblk_off;
- if ((nsc_size_t)st_cblk_len >= fba_len) {
- end_cblk_len = 0;
- st_cblk_len = (sdbc_cblk_fba_t)fba_len;
- } else {
- end_cblk_len = BLK_FBA_OFF(fba_pos1 + fba_len);
- }
-
- bcopy(cc_ent1->cc_data + FBA_SIZE(st_cblk_off),
- cc_ent2->cc_data + FBA_SIZE(st_cblk_off), FBA_SIZE(st_cblk_len));
- cur_fba_len -= st_cblk_len;
- cc_ent1 = cc_ent1->cc_chain;
- cc_ent2 = cc_ent2->cc_chain;
-
- while (cur_fba_len > (nsc_size_t)end_cblk_len) {
- bcopy(cc_ent1->cc_data, cc_ent2->cc_data, CACHE_BLOCK_SIZE);
- cc_ent1 = cc_ent1->cc_chain;
- cc_ent2 = cc_ent2->cc_chain;
- cur_fba_len -= BLK_FBAS;
- }
- if (cur_fba_len) {
- bcopy(cc_ent1->cc_data, cc_ent2->cc_data,
- FBA_SIZE(end_cblk_len));
- }
-
- return (NSC_DONE);
-}
-
-
-/*
- * _sd_copy_direct - Copies data from one handle direct to another disk.
- *
- * ARGUMENTS:
- * handle1 - handle to read from
- * handle2 - handle to write to
- * fba_pos1 - disk block number to read from.
- * fba_pos2 - disk block number to write to.
- * fba_len - length in fbas.
- *
- * RETURNS:
- * errno if return > 0
- * NSC_DONE otherwise.
- *
- * Comments:
- * This routine copies data from handle1 directly (sync write)
- * onto the disk pointed to by handle2. The handle2 is then
- * invalidated since the data it contains is now stale compared to
- * the disk.
- */
-
-static int
-_sd_copy_direct(_sd_buf_handle_t *handle1, _sd_buf_handle_t *handle2,
- nsc_off_t fba_pos1, nsc_off_t fba_pos2, nsc_size_t fba_len)
-{
- int rc;
-
- if (_sdbc_shutdown_in_progress) {
- DTRACE_PROBE(shutdown);
- return (EIO);
- }
-
- if (!_SD_HANDLE_ACTIVE(handle1) || !_SD_HANDLE_ACTIVE(handle2)) {
- cmn_err(CE_WARN,
- "!sdbc(_sd_copy_direct) handle %p or %p not active",
- (void *)handle1, (void *)handle2);
-
- DTRACE_PROBE2(handle_active2, int, handle1->bh_flag,
- int, handle2->bh_flag);
-
- return (EINVAL);
- }
-
- ASSERT_HANDLE_LIMITS(handle1, fba_pos1, fba_len);
- ASSERT_HANDLE_LIMITS(handle2, fba_pos2, fba_len);
-
- if ((handle2->bh_flag & NSC_WRITE) == 0) {
- cmn_err(CE_WARN,
- "!sdbc(_sd_copy_direct) handle2 %p is not writeable",
- (void *)handle2);
- DTRACE_PROBE1(handle2_write, int, handle2->bh_flag);
- return (EINVAL);
- }
-
- rc = _sd_sync_write2(handle2, fba_pos2, fba_len, 0, handle1, fba_pos1);
-
- return (rc);
-}
-
-
-/*
- * _sd_enqueue_dirty - Enqueue a list of dirty buffers.
- *
- * ARGUMENTS:
- * cd - cache descriptor.
- * chain - pointer to list.
- * cc_last - last entry in the chain.
- * numq - number of entries in the list.
- *
- * RETURNS:
- * NONE.
- *
- * Comments:
- * This routine queues up the dirty blocks for io processing.
- * It uses the cc_last to try to coalesce multiple lists into a
- * single list, if consecutive writes are sequential in nature.
- */
-
-void
-_sd_enqueue_dirty(int cd, _sd_cctl_t *chain, _sd_cctl_t *cc_last, int numq)
-{
- _sd_cd_info_t *cdi;
- _sd_cctl_t *last_ent;
- int start_write = 0, maxq = SGIO_MAX;
-
- ASSERT(cd >= 0);
- cdi = &(_sd_cache_files[cd]);
-#if defined(_SD_DEBUG)
- if (chain->cc_dirty_link)
- cmn_err(CE_WARN, "!dirty_link set in enq %x fl %x",
- chain->cc_dirty_link, chain->cc_flag);
-#endif
-
- /* was FAST */
- mutex_enter(&(cdi->cd_lock));
- cdi->cd_info->sh_numdirty += numq;
- if (cc_last == NULL)
- numq = 0;
-
- if (cdi->cd_dirty_head == NULL) {
- cdi->cd_dirty_head = cdi->cd_dirty_tail = chain;
- cdi->cd_last_ent = cc_last;
- cdi->cd_lastchain_ptr = chain;
- cdi->cd_lastchain = numq;
- } else {
- if ((cc_last) && (last_ent = cdi->cd_last_ent) &&
- (CENTRY_BLK(chain) == (CENTRY_BLK(last_ent)+1)) &&
- (SDBC_DIRTY_NEIGHBORS(last_ent, chain)) &&
- (cdi->cd_lastchain + numq < maxq)) {
- cdi->cd_last_ent->cc_dirty_next = chain;
- cdi->cd_last_ent = cc_last;
- cdi->cd_lastchain += numq;
- } else {
- cdi->cd_dirty_tail->cc_dirty_link = chain;
- cdi->cd_dirty_tail = chain;
- cdi->cd_last_ent = cc_last;
- cdi->cd_lastchain_ptr = chain;
- cdi->cd_lastchain = numq;
- start_write = 1;
- }
- }
- /* was FAST */
- mutex_exit(&(cdi->cd_lock));
- if (start_write)
- (void) _SD_CD_WRITER(cd);
-}
-
-/*
- * _sd_enqueue_dirty_chain - Enqueue a chain of a list of dirty buffers.
- *
- * ARGUMENTS:
- * cd - cache descriptor.
- * chain_first - first list in this chain.
- * chain_last - last list in this chain.
- * numq - number of entries being queue (total of all lists)
- *
- * RETURNS:
- * NONE.
- *
- * Comments:
- * This routine is called from the processing after io completions.
- * If the buffers are still dirty, they are queued up in one shot.
- */
-
-void
-_sd_enqueue_dirty_chain(int cd, _sd_cctl_t *chain_first,
- _sd_cctl_t *chain_last, int numq)
-{
- _sd_cd_info_t *cdi;
-
- ASSERT(cd >= 0);
- cdi = &(_sd_cache_files[cd]);
- if (chain_last->cc_dirty_link)
- cmn_err(CE_PANIC,
- "!_sd_enqueue_dirty_chain: chain_last %p dirty_link %p",
- (void *)chain_last, (void *)chain_last->cc_dirty_link);
- /* was FAST */
- mutex_enter(&(cdi->cd_lock));
- cdi->cd_last_ent = NULL;
- cdi->cd_lastchain_ptr = NULL;
- cdi->cd_lastchain = 0;
-
- cdi->cd_info->sh_numdirty += numq;
- if (cdi->cd_dirty_head == NULL) {
- cdi->cd_dirty_head = chain_first;
- cdi->cd_dirty_tail = chain_last;
- } else {
- cdi->cd_dirty_tail->cc_dirty_link = chain_first;
- cdi->cd_dirty_tail = chain_last;
- }
- /* was FAST */
- mutex_exit(&(cdi->cd_lock));
-}
-
-/*
- * Convert the 64 bit statistic structure to 32bit version.
- * Possibly losing information when cache is > 4gb. Ha!
- *
- * NOTE: this code isn't really MT ready since the copied to struct
- * is static. However the race is pretty benign and isn't a whole
- * lot worse than the vanilla version which copies data to user
- * space from kernel structures that can be changing under it too.
- * We can't use a local stack structure since the data size is
- * 70k or so and kernel stacks are tiny (8k).
- */
-#ifndef _MULTI_DATAMODEL
-/* ARGSUSED */
-#endif
-static int
-convert_stats(_sd_stats32_t *uptr)
-{
-#ifndef _MULTI_DATAMODEL
- return (SDBC_EMODELCONVERT);
-#else
- int rc = 0;
-
- /*
- * This could be done in less code with bcopy type operations
- * but this is simpler to follow and easier to change if
- * the structures change.
- */
-
- _sd_cache_stats32->net_dirty = _sd_cache_stats->net_dirty;
- _sd_cache_stats32->net_pending = _sd_cache_stats->net_pending;
- _sd_cache_stats32->net_free = _sd_cache_stats->net_free;
- _sd_cache_stats32->st_count = _sd_cache_stats->st_count;
- _sd_cache_stats32->st_loc_count = _sd_cache_stats->st_loc_count;
- _sd_cache_stats32->st_rdhits = _sd_cache_stats->st_rdhits;
- _sd_cache_stats32->st_rdmiss = _sd_cache_stats->st_rdmiss;
- _sd_cache_stats32->st_wrhits = _sd_cache_stats->st_wrhits;
- _sd_cache_stats32->st_wrmiss = _sd_cache_stats->st_wrmiss;
- _sd_cache_stats32->st_blksize = _sd_cache_stats->st_blksize;
-
- _sd_cache_stats32->st_lru_blocks = _sd_cache_stats->st_lru_blocks;
- _sd_cache_stats32->st_lru_noreq = _sd_cache_stats->st_lru_noreq;
- _sd_cache_stats32->st_lru_req = _sd_cache_stats->st_lru_req;
-
- _sd_cache_stats32->st_wlru_inq = _sd_cache_stats->st_wlru_inq;
-
- _sd_cache_stats32->st_cachesize = _sd_cache_stats->st_cachesize;
- _sd_cache_stats32->st_numblocks = _sd_cache_stats->st_numblocks;
- _sd_cache_stats32->st_wrcancelns = _sd_cache_stats->st_wrcancelns;
- _sd_cache_stats32->st_destaged = _sd_cache_stats->st_destaged;
-
- /*
- * bcopy the shared stats which has nothing that needs conversion
- * in them
- */
-
- bcopy(_sd_cache_stats->st_shared, _sd_cache_stats32->st_shared,
- sizeof (_sd_shared_t) * sdbc_max_devs);
-
- if (copyout(_sd_cache_stats32, uptr, sizeof (_sd_stats32_t) +
- (sdbc_max_devs - 1) * sizeof (_sd_shared_t)))
- rc = EFAULT;
-
- return (rc);
-#endif /* _MULTI_DATAMODEL */
-}
-
-
-int
-_sd_get_stats(_sd_stats_t *uptr, int convert_32)
-{
- int rc = 0;
-
- if (_sd_cache_stats == NULL) {
- static _sd_stats_t dummy;
-#ifdef _MULTI_DATAMODEL
- static _sd_stats32_t dummy32;
-#endif
-
- if (convert_32) {
-#ifdef _MULTI_DATAMODEL
- if (copyout(&dummy32, uptr, sizeof (_sd_stats32_t)))
- rc = EFAULT;
-#else
- rc = SDBC_EMODELCONVERT;
-#endif
- } else if (copyout(&dummy, uptr, sizeof (_sd_stats_t)))
- rc = EFAULT;
- return (rc);
- }
-
- _sd_cache_stats->st_lru_blocks = _sd_lru_q.sq_inq;
- _sd_cache_stats->st_lru_noreq = _sd_lru_q.sq_noreq_stat;
- _sd_cache_stats->st_lru_req = _sd_lru_q.sq_req_stat;
-
- if (sdbc_safestore) {
- ssioc_stats_t ss_stats;
-
- if (SSOP_CTL(sdbc_safestore, SSIOC_STATS,
- (uintptr_t)&ss_stats) == 0)
- _sd_cache_stats->st_wlru_inq = ss_stats.wq_inq;
- else
- _sd_cache_stats->st_wlru_inq = 0;
- }
-
- if (convert_32)
- rc = convert_stats((_sd_stats32_t *)uptr);
- else if (copyout(_sd_cache_stats, uptr,
- sizeof (_sd_stats_t) + (sdbc_max_devs - 1) * sizeof (_sd_shared_t)))
- rc = EFAULT;
-
- return (rc);
-}
-
-
-int
-_sd_set_hint(int cd, uint_t hint)
-{
- int ret = 0;
- if (FILE_OPENED(cd)) {
- SDTRACE(ST_ENTER|SDF_HINT, cd, 1, SDT_INV_BL, hint, 0);
- _sd_cache_files[cd].cd_hint |= (hint & _SD_HINT_MASK);
- SDTRACE(ST_EXIT|SDF_HINT, cd, 1, SDT_INV_BL, hint, ret);
- } else
- ret = EINVAL;
-
- return (ret);
-}
-
-
-
-int
-_sd_clear_hint(int cd, uint_t hint)
-{
- int ret = 0;
- if (FILE_OPENED(cd)) {
- SDTRACE(ST_ENTER|SDF_HINT, cd, 2, SDT_INV_BL, hint, 0);
- _sd_cache_files[cd].cd_hint &= ~(hint & _SD_HINT_MASK);
- SDTRACE(ST_EXIT|SDF_HINT, cd, 2, SDT_INV_BL, hint, ret);
- } else
- ret = EINVAL;
-
- return (ret);
-}
-
-
-int
-_sd_get_cd_hint(int cd, uint_t *hint)
-{
- *hint = 0;
- if (FILE_OPENED(cd)) {
- *hint = _sd_cache_files[cd].cd_hint;
- return (0);
- } else
- return (EINVAL);
-}
-
-static int
-_sd_node_hint_caller(blind_t hint, int hint_action)
-{
- int rc;
-
- switch (hint_action) {
- case NSC_GET_NODE_HINT:
- rc = _sd_get_node_hint((uint_t *)hint);
- break;
- case NSC_SET_NODE_HINT:
- rc = _sd_set_node_hint((uint_t)(unsigned long)hint);
- break;
- case NSC_CLEAR_NODE_HINT:
- rc = _sd_clear_node_hint((uint_t)(unsigned long)hint);
- break;
- default:
- rc = EINVAL;
- break;
- }
-
- return (rc);
-}
-
-int
-_sd_set_node_hint(uint_t hint)
-{
- SDTRACE(ST_ENTER|SDF_HINT, SDT_INV_CD, 3, SDT_INV_BL, hint, 0);
- if ((_sd_node_hint & NSC_NO_FORCED_WRTHRU) &&
- (hint & NSC_FORCED_WRTHRU))
- return (EINVAL);
- _sd_node_hint |= (hint & _SD_HINT_MASK);
- SDTRACE(ST_EXIT|SDF_HINT, SDT_INV_CD, 3, SDT_INV_BL, hint, 0);
- return (0);
-}
-
-
-int
-_sd_clear_node_hint(uint_t hint)
-{
- SDTRACE(ST_ENTER|SDF_HINT, SDT_INV_CD, 4, SDT_INV_BL, hint, 0);
- _sd_node_hint &= ~(hint & _SD_HINT_MASK);
- SDTRACE(ST_EXIT|SDF_HINT, SDT_INV_CD, 4, SDT_INV_BL, hint, 0);
- return (0);
-}
-
-
-int
-_sd_get_node_hint(uint_t *hint)
-{
- *hint = _sd_node_hint;
- return (0);
-}
-
-
-int
-_sd_get_partsize(blind_t xcd, nsc_size_t *ptr)
-{
- int cd = (int)(unsigned long)xcd;
-
- if (FILE_OPENED(cd)) {
- *ptr = _sd_cache_files[cd].cd_info->sh_filesize;
- return (0);
- } else
- return (EINVAL);
-}
-
-
-int
-_sd_get_maxfbas(blind_t xcd, int flag, nsc_size_t *ptr)
-{
- int cd = (int)(unsigned long)xcd;
-
- if (!FILE_OPENED(cd))
- return (EINVAL);
-
- if (flag & NSC_CACHEBLK)
- *ptr = BLK_FBAS;
- else
- *ptr = sdbc_max_fbas;
-
- return (0);
-}
-
-
-int
-_sd_control(blind_t xcd, int cmd, void *ptr, int len)
-{
- _sd_cd_info_t *cdi;
- int cd = (int)(unsigned long)xcd;
-
- cdi = &(_sd_cache_files[cd]);
- return (nsc_control(cdi->cd_rawfd, cmd, ptr, len));
-}
-
-
-int
-_sd_discard_pinned(blind_t xcd, nsc_off_t fba_pos, nsc_size_t fba_len)
-{
- int cd = (int)(unsigned long)xcd;
- _sd_cctl_t *cc_ent, **cc_lst, **cc_tmp, *nxt;
- ss_centry_info_t *wctl;
- int found = 0;
- nsc_off_t cblk;
- _sd_cd_info_t *cdi = &_sd_cache_files[cd];
- int rc;
-
- if ((!FILE_OPENED(cd)) || (!cdi->cd_info->sh_failed)) {
-
- return (EINVAL);
- }
-
- for (cblk = FBA_TO_BLK_NUM(fba_pos);
- cblk < FBA_TO_BLK_LEN(fba_pos + fba_len); cblk++) {
- if (cc_ent =
- (_sd_cctl_t *)_sd_hash_search(cd, cblk, _sd_htable)) {
- if (!CENTRY_PINNED(cc_ent))
- continue;
-
- /*
- * remove cc_ent from failed links
- * cc_lst - pointer to "cc_dirty_link" pointer
- * starts at &cd_failed_head.
- * cc_tmp - pointer to "cc_dirty_next"
- * except when equal to cc_lst.
- */
- mutex_enter(&cdi->cd_lock);
- cc_tmp = cc_lst = &(cdi->cd_fail_head);
- while (*cc_tmp != cc_ent) {
- cc_tmp = &((*cc_tmp)->cc_dirty_next);
- if (!*cc_tmp)
- cc_lst = &((*cc_lst)->cc_dirty_link),
- cc_tmp = cc_lst;
- }
- if (*cc_tmp) {
- found++;
- if (cc_lst != cc_tmp) /* break chain */
- *cc_tmp = NULL;
- nxt = cc_ent->cc_dirty_next;
- if (nxt) {
- nxt->cc_dirty_link =
- (*cc_lst)->cc_dirty_link;
- *cc_lst = nxt;
- } else {
- *cc_lst = (*cc_lst)->cc_dirty_link;
- }
- cdi->cd_info->sh_numfail--;
- nsc_unpinned_data(cdi->cd_iodev,
- BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent)),
- BLK_FBAS);
- }
- mutex_exit(&cdi->cd_lock);
-
- /* clear dirty bits */
- /* was FAST */
- mutex_enter(&cc_ent->cc_lock);
- cc_ent->cc_valid = cc_ent->cc_dirty = 0;
- cc_ent->cc_flag &= ~(CC_QHEAD|CC_PEND_DIRTY|CC_PINNED);
- cc_ent->cc_dirty_link = NULL;
- wctl = cc_ent->cc_write;
- cc_ent->cc_write = NULL;
- /* was FAST */
- mutex_exit(&cc_ent->cc_lock);
-
- /* release cache block to head of LRU */
- if (wctl) {
- wctl->sc_flag = 0;
- wctl->sc_dirty = 0;
- SSOP_SETCENTRY(sdbc_safestore, wctl);
- SSOP_DEALLOCRESOURCE(sdbc_safestore,
- wctl->sc_res);
- }
-
- if (!sdbc_use_dmchain)
- _sd_requeue_head(cc_ent);
- }
- }
-
- rc = found ? NSC_DONE : EINVAL;
-
- return (rc);
-}
-
-
-/*
- * Handle allocation
- */
-
-_sd_buf_hlist_t _sd_handle_list;
-
-/*
- * _sdbc_handles_unload - cache is being unloaded.
- */
-void
-_sdbc_handles_unload(void)
-{
- mutex_destroy(&_sd_handle_list.hl_lock);
-
-}
-
-/*
- * _sdbc_handles_load - cache is being unloaded.
- */
-int
-_sdbc_handles_load(void)
-{
- mutex_init(&_sd_handle_list.hl_lock, NULL, MUTEX_DRIVER, NULL);
-
- return (0);
-}
-
-int
-_sdbc_handles_configure()
-{
- _sd_handle_list.hl_count = 0;
-
- _sd_handle_list.hl_top.bh_next = &_sd_handle_list.hl_top;
- _sd_handle_list.hl_top.bh_prev = &_sd_handle_list.hl_top;
-
- return (0);
-}
-
-
-
-/*
- * _sdbc_handles_deconfigure - cache is being deconfigured
- */
-void
-_sdbc_handles_deconfigure(void)
-{
- _sd_handle_list.hl_count = 0;
-}
-
-
-_sd_buf_handle_t *
-_sd_alloc_handle(sdbc_callback_fn_t d_cb, sdbc_callback_fn_t r_cb,
- sdbc_callback_fn_t w_cb)
-{
- _sd_buf_handle_t *handle;
-
- handle = (_sd_buf_handle_t *)kmem_zalloc(sizeof (_sd_buf_handle_t),
- KM_SLEEP);
- /* maintain list and count for debugging */
- mutex_enter(&_sd_handle_list.hl_lock);
-
- handle->bh_prev = &_sd_handle_list.hl_top;
- handle->bh_next = _sd_handle_list.hl_top.bh_next;
- _sd_handle_list.hl_top.bh_next->bh_prev = handle;
- _sd_handle_list.hl_top.bh_next = handle;
-
- ++_sd_handle_list.hl_count;
- mutex_exit(&_sd_handle_list.hl_lock);
-#if !defined(_SD_NOCHECKS)
- ASSERT(!(handle->bh_flag & (NSC_HALLOCATED | NSC_HACTIVE)));
-#endif
- handle->bh_disconnect_cb = d_cb;
- handle->bh_read_cb = r_cb;
- handle->bh_write_cb = w_cb;
- handle->bh_flag |= NSC_HALLOCATED;
- handle->bh_alloc_thread = nsc_threadp();
-
- return (handle);
-}
-
-int
-_sd_free_handle(_sd_buf_handle_t *handle)
-{
-
- if ((handle->bh_flag & NSC_HALLOCATED) == 0) {
- cmn_err(CE_WARN, "!sdbc(_sd_free_handle) handle %p not valid",
- (void *)handle);
-
- DTRACE_PROBE(_sd_free_handle_end);
-
- return (EINVAL);
- }
- if (_SD_HANDLE_ACTIVE(handle)) {
- cmn_err(CE_WARN,
- "!sdbc(_sd_free_handle) attempt to free active handle %p",
- (void *)handle);
-
- DTRACE_PROBE1(free_handle_active, int, handle->bh_flag);
-
- return (EINVAL);
- }
-
-
- /* remove from queue before free */
- mutex_enter(&_sd_handle_list.hl_lock);
- handle->bh_prev->bh_next = handle->bh_next;
- handle->bh_next->bh_prev = handle->bh_prev;
- --_sd_handle_list.hl_count;
- mutex_exit(&_sd_handle_list.hl_lock);
-
- kmem_free(handle, sizeof (_sd_buf_handle_t));
-
- return (0);
-}
-
-
-
-
-#if !defined (_SD_8K_BLKSIZE)
-#define _SD_MAX_MAP 0x100
-#else /* !(_SD_8K_BLKSIZE) */
-#define _SD_MAX_MAP 0x10000
-#endif /* !(_SD_8K_BLKSIZE) */
-
-char _sd_contig_bmap[_SD_MAX_MAP];
-_sd_map_info_t _sd_lookup_map[_SD_MAX_MAP];
-
-void
-_sd_init_contig_bmap(void)
-{
- int i, j;
-
- for (i = 1; i < _SD_MAX_MAP; i = ((i << 1) | 1))
- for (j = i; j < _SD_MAX_MAP; j <<= 1)
- _sd_contig_bmap[j] = 1;
-}
-
-
-
-
-void
-_sd_init_lookup_map(void)
-{
- unsigned int i, j, k;
- int stpos, len;
- _sd_bitmap_t mask;
-
- for (i = 0; i < _SD_MAX_MAP; i++) {
- for (j = i, k = 0; j && ((j & 1) == 0); j >>= 1, k++)
- ;
- stpos = k;
- _sd_lookup_map[i].mi_stpos = (unsigned char)k;
-
- for (k = 0; j & 1; j >>= 1, k++)
- ;
- len = k;
- _sd_lookup_map[i].mi_len = (unsigned char)k;
-
- _sd_lookup_map[i].mi_mask = SDBC_GET_BITS(stpos, len);
- }
- for (i = 0; i < _SD_MAX_MAP; i++) {
- mask = (_sd_bitmap_t)i;
- for (j = 0; mask; j++)
- SDBC_LOOKUP_MODIFY(mask);
-
- _sd_lookup_map[i].mi_dirty_count = (unsigned char)j;
- }
- for (i = 0; i < _SD_MAX_MAP; i++) {
- _sd_lookup_map[i].mi_io_count = SDBC_LOOKUP_DTCOUNT(i);
- mask = ~i;
- _sd_lookup_map[i].mi_io_count += SDBC_LOOKUP_DTCOUNT(mask);
- }
-}
-
-
-nsc_def_t _sd_sdbc_def[] = {
- "Open", (uintptr_t)_sd_open_io, 0,
- "Close", (uintptr_t)_sd_close_io, 0,
- "Attach", (uintptr_t)_sdbc_io_attach_cd, 0,
- "Detach", (uintptr_t)_sdbc_io_detach_cd, 0,
- "AllocBuf", (uintptr_t)_sd_alloc_buf, 0,
- "FreeBuf", (uintptr_t)_sd_free_buf, 0,
- "Read", (uintptr_t)_sd_read, 0,
- "Write", (uintptr_t)_sd_write, 0,
- "Zero", (uintptr_t)_sd_zero, 0,
- "Copy", (uintptr_t)_sd_copy, 0,
- "CopyDirect", (uintptr_t)_sd_copy_direct, 0,
- "Uncommit", (uintptr_t)_sd_uncommit, 0,
- "AllocHandle", (uintptr_t)_sd_alloc_handle, 0,
- "FreeHandle", (uintptr_t)_sd_free_handle, 0,
- "Discard", (uintptr_t)_sd_discard_pinned, 0,
- "Sizes", (uintptr_t)_sd_cache_sizes, 0,
- "GetPinned", (uintptr_t)_sd_get_pinned, 0,
- "NodeHints", (uintptr_t)_sd_node_hint_caller, 0,
- "PartSize", (uintptr_t)_sd_get_partsize, 0,
- "MaxFbas", (uintptr_t)_sd_get_maxfbas, 0,
- "Control", (uintptr_t)_sd_control, 0,
- "Provide", NSC_CACHE, 0,
- 0, 0, 0
-};
-
-/*
- * do the SD_GET_CD_CLUSTER_DATA ioctl (get the global filename data)
- */
-/* ARGSUSED */
-int
-sd_get_file_info_data(char *uaddrp)
-{
- return (ENOTTY);
-}
-
-/*
- * do the SD_GET_CD_CLUSTER_SIZE ioctl (get size of global filename area)
- */
-int
-sd_get_file_info_size(void *uaddrp)
-{
- if (copyout(&_sdbc_gl_file_info_size, uaddrp,
- sizeof (_sdbc_gl_file_info_size))) {
- return (EFAULT);
- }
-
- return (0);
-}
-
-
-/*
- * SD_GET_GLMUL_SIZES ioctl
- * get sizes of the global info regions (for this node only)
- */
-/* ARGSUSED */
-int
-sd_get_glmul_sizes(int *uaddrp)
-{
- return (ENOTTY);
-}
-
-/*
- * SD_GET_GLMUL_INFO ioctl
- * get the global metadata for write blocks (for this node only)
- */
-/* ARGSUSED */
-int
-sd_get_glmul_info(char *uaddrp)
-{
-
- return (ENOTTY);
-}
-
-int
-sdbc_global_stats_update(kstat_t *ksp, int rw)
-{
- sdbc_global_stats_t *sdbc_gstats;
- _sd_stats_t *gstats_vars;
- uint_t hint;
-
- sdbc_gstats = (sdbc_global_stats_t *)(ksp->ks_data);
-
- gstats_vars = _sd_cache_stats;
-
- if (rw == KSTAT_WRITE) {
- return (EACCES);
- }
-
- /* default to READ */
- sdbc_gstats->ci_sdbc_count.value.ul = gstats_vars->st_count;
- sdbc_gstats->ci_sdbc_loc_count.value.ul = gstats_vars->st_loc_count;
- sdbc_gstats->ci_sdbc_rdhits.value.ul = (ulong_t)gstats_vars->st_rdhits;
- sdbc_gstats->ci_sdbc_rdmiss.value.ul = (ulong_t)gstats_vars->st_rdmiss;
- sdbc_gstats->ci_sdbc_wrhits.value.ul = (ulong_t)gstats_vars->st_wrhits;
- sdbc_gstats->ci_sdbc_wrmiss.value.ul = (ulong_t)gstats_vars->st_wrmiss;
-
- sdbc_gstats->ci_sdbc_blksize.value.ul =
- (ulong_t)gstats_vars->st_blksize;
- sdbc_gstats->ci_sdbc_lru_blocks.value.ul = (ulong_t)_sd_lru_q.sq_inq;
-#ifdef DEBUG
- sdbc_gstats->ci_sdbc_lru_noreq.value.ul =
- (ulong_t)_sd_lru_q.sq_noreq_stat;
- sdbc_gstats->ci_sdbc_lru_req.value.ul = (ulong_t)_sd_lru_q.sq_req_stat;
-#endif
- sdbc_gstats->ci_sdbc_wlru_inq.value.ul =
- (ulong_t)gstats_vars->st_wlru_inq;
- sdbc_gstats->ci_sdbc_cachesize.value.ul =
- (ulong_t)gstats_vars->st_cachesize;
- sdbc_gstats->ci_sdbc_numblocks.value.ul =
- (ulong_t)gstats_vars->st_numblocks;
- sdbc_gstats->ci_sdbc_wrcancelns.value.ul =
- (ulong_t)gstats_vars->st_wrcancelns;
- sdbc_gstats->ci_sdbc_destaged.value.ul =
- (ulong_t)gstats_vars->st_destaged;
- sdbc_gstats->ci_sdbc_num_shared.value.ul = (ulong_t)sdbc_max_devs;
- (void) _sd_get_node_hint(&hint);
- sdbc_gstats->ci_sdbc_nodehints.value.ul = (ulong_t)hint;
-
-
- return (0);
-}
-
-int
-sdbc_cd_stats_update(kstat_t *ksp, int rw)
-{
- sdbc_cd_stats_t *sdbc_shstats;
- _sd_shared_t *shstats_vars;
- int name_len;
- uint_t hint;
-
- sdbc_shstats = (sdbc_cd_stats_t *)(ksp->ks_data);
-
- shstats_vars = (_sd_shared_t *)(ksp->ks_private);
-
- if (rw == KSTAT_WRITE) {
- return (EACCES);
- }
-
- /* copy tail of filename to kstat. leave 1 byte for null char */
- if (shstats_vars->sh_filename != NULL) {
- name_len = (int)strlen(shstats_vars->sh_filename);
- name_len -= (KSTAT_DATA_CHAR_LEN - 1);
-
- if (name_len < 0) {
- name_len = 0;
- }
-
- (void) strlcpy(sdbc_shstats->ci_sdbc_vol_name.value.c,
- shstats_vars->sh_filename + name_len, KSTAT_DATA_CHAR_LEN);
- } else {
- cmn_err(CE_WARN, "!Kstat error: no volume name associated "
- "with cache descriptor");
- }
-
- sdbc_shstats->ci_sdbc_failed.value.ul =
- (ulong_t)shstats_vars->sh_failed;
- sdbc_shstats->ci_sdbc_cd.value.ul = (ulong_t)shstats_vars->sh_cd;
- sdbc_shstats->ci_sdbc_cache_read.value.ul =
- (ulong_t)shstats_vars->sh_cache_read;
- sdbc_shstats->ci_sdbc_cache_write.value.ul =
- (ulong_t)shstats_vars->sh_cache_write;
- sdbc_shstats->ci_sdbc_disk_read.value.ul =
- (ulong_t)shstats_vars->sh_disk_read;
- sdbc_shstats->ci_sdbc_disk_write.value.ul =
- (ulong_t)shstats_vars->sh_disk_write;
-#ifdef NSC_MULTI_TERABYTE
- sdbc_shstats->ci_sdbc_filesize.value.ui64 =
- (uint64_t)shstats_vars->sh_filesize;
-#else
- sdbc_shstats->ci_sdbc_filesize.value.ul =
- (ulong_t)shstats_vars->sh_filesize;
-#endif
- sdbc_shstats->ci_sdbc_numdirty.value.ul =
- (ulong_t)shstats_vars->sh_numdirty;
- sdbc_shstats->ci_sdbc_numio.value.ul = (ulong_t)shstats_vars->sh_numio;
- sdbc_shstats->ci_sdbc_numfail.value.ul =
- (ulong_t)shstats_vars->sh_numfail;
- sdbc_shstats->ci_sdbc_destaged.value.ul =
- (ulong_t)shstats_vars->sh_destaged;
- sdbc_shstats->ci_sdbc_wrcancelns.value.ul =
- (ulong_t)shstats_vars->sh_wrcancelns;
- (void) _sd_get_cd_hint(shstats_vars->sh_cd, &hint);
- sdbc_shstats->ci_sdbc_cdhints.value.ul = (ulong_t)hint;
-
-
- return (0);
-}
-
-
-/*
- * cd_kstat_add
- *
- * Installs all kstats and associated infrastructure (mutex, buffer),
- * associated with a particular cache descriptor. This function is called
- * when the cache descriptor is opened in _sd_open().
- * "cd" -- cache descriptor number whose kstats we wish to add
- * returns: 0 on success, -1 on failure
- */
-static int
-cd_kstat_add(int cd)
-{
- char name[KSTAT_STRLEN];
-
- if (cd < 0 || cd >= sdbc_max_devs) {
- cmn_err(CE_WARN, "!invalid cache descriptor: %d", cd);
- return (-1);
- }
-
- /* create a regular kstat for this cache descriptor */
- if (!sdbc_cd_kstats) {
- cmn_err(CE_WARN, "!sdbc_cd_kstats not allocated");
- return (-1);
- }
-
- (void) snprintf(name, KSTAT_STRLEN, "%s%d", SDBC_KSTAT_CDSTATS, cd);
-
- sdbc_cd_kstats[cd] = kstat_create(SDBC_KSTAT_MODULE,
- cd, name, SDBC_KSTAT_CLASS, KSTAT_TYPE_NAMED,
- sizeof (sdbc_cd_stats)/sizeof (kstat_named_t),
- KSTAT_FLAG_VIRTUAL|KSTAT_FLAG_WRITABLE);
-
- if (sdbc_cd_kstats[cd] != NULL) {
- sdbc_cd_kstats[cd]->ks_data = &sdbc_cd_stats;
- sdbc_cd_kstats[cd]->ks_update = sdbc_cd_stats_update;
- sdbc_cd_kstats[cd]->ks_private =
- &_sd_cache_stats->st_shared[cd];
- kstat_install(sdbc_cd_kstats[cd]);
- } else {
- cmn_err(CE_WARN, "!cdstats %d kstat allocation failed", cd);
- }
-
- /* create an I/O kstat for this cache descriptor */
- if (!sdbc_cd_io_kstats) {
- cmn_err(CE_WARN, "!sdbc_cd_io_kstats not allocated");
- return (-1);
- }
-
- (void) snprintf(name, KSTAT_STRLEN, "%s%d", SDBC_IOKSTAT_CDSTATS, cd);
-
- sdbc_cd_io_kstats[cd] = kstat_create(
- SDBC_KSTAT_MODULE, cd, name, "disk", KSTAT_TYPE_IO, 1, 0);
-
- if (sdbc_cd_io_kstats[cd]) {
- if (!sdbc_cd_io_kstats_mutexes) {
- cmn_err(CE_WARN, "!sdbc_cd_io_kstats_mutexes not "
- "allocated");
- return (-1);
- }
-
- mutex_init(&sdbc_cd_io_kstats_mutexes[cd], NULL,
- MUTEX_DRIVER, NULL);
-
- sdbc_cd_io_kstats[cd]->ks_lock = &sdbc_cd_io_kstats_mutexes[cd];
-
- kstat_install(sdbc_cd_io_kstats[cd]);
-
- } else {
- cmn_err(CE_WARN, "!sdbc cd %d io kstat allocation failed", cd);
- }
-
- return (0);
-}
-
-/*
- * cd_kstat_remove
- *
- * Uninstalls all kstats and associated infrastructure (mutex, buffer),
- * associated with a particular cache descriptor. This function is called
- * when the cache descriptor is closed in _sd_close().
- * "cd" -- cache descriptor number whose kstats we wish to remove
- * returns: 0 on success, -1 on failure
- */
-static int
-cd_kstat_remove(int cd)
-{
- if (cd < 0 || cd >= sdbc_max_devs) {
- cmn_err(CE_WARN, "!invalid cache descriptor: %d", cd);
- return (-1);
- }
-
- /* delete the regular kstat corresponding to this cache descriptor */
- if (sdbc_cd_kstats && sdbc_cd_kstats[cd]) {
- kstat_delete(sdbc_cd_kstats[cd]);
- sdbc_cd_kstats[cd] = NULL;
- }
-
- /* delete the I/O kstat corresponding to this cache descriptor */
- if (sdbc_cd_io_kstats && sdbc_cd_io_kstats[cd]) {
- kstat_delete(sdbc_cd_io_kstats[cd]);
- sdbc_cd_io_kstats[cd] = NULL;
-
- if (sdbc_cd_io_kstats_mutexes) {
- /* destroy the mutex associated with this I/O kstat */
- mutex_destroy(&sdbc_cd_io_kstats_mutexes[cd]);
- }
- }
-
- return (0);
-}
-
-#ifdef DEBUG
-/*
- * kstat update
- */
-int
-sdbc_dynmem_kstat_update_dm(kstat_t *ksp, int rw)
-{
- sdbc_dynmem_dm_t *sdbc_dynmem;
- _dm_process_vars_t *process_vars;
- _dm_process_vars_t local_dm_process_vars;
-
- simplect_dm++;
-
- sdbc_dynmem = (sdbc_dynmem_dm_t *)(ksp->ks_data);
-
- /* global dynmem_processing_dm */
- process_vars = (_dm_process_vars_t *)(ksp->ks_private);
-
- if (rw == KSTAT_WRITE) {
- simplect_dm = sdbc_dynmem->ci_sdbc_simplect.value.ul;
- local_dm_process_vars.monitor_dynmem_process =
- sdbc_dynmem->ci_sdbc_monitor_dynmem.value.ul;
- local_dm_process_vars.max_dyn_list =
- sdbc_dynmem->ci_sdbc_max_dyn_list.value.ul;
- local_dm_process_vars.cache_aging_ct1 =
- sdbc_dynmem->ci_sdbc_cache_aging_ct1.value.ul;
- local_dm_process_vars.cache_aging_ct2 =
- sdbc_dynmem->ci_sdbc_cache_aging_ct2.value.ul;
- local_dm_process_vars.cache_aging_ct3 =
- sdbc_dynmem->ci_sdbc_cache_aging_ct3.value.ul;
- local_dm_process_vars.cache_aging_sec1 =
- sdbc_dynmem->ci_sdbc_cache_aging_sec1.value.ul;
- local_dm_process_vars.cache_aging_sec2 =
- sdbc_dynmem->ci_sdbc_cache_aging_sec2.value.ul;
- local_dm_process_vars.cache_aging_sec3 =
- sdbc_dynmem->ci_sdbc_cache_aging_sec3.value.ul;
- local_dm_process_vars.cache_aging_pcnt1 =
- sdbc_dynmem->ci_sdbc_cache_aging_pcnt1.value.ul;
- local_dm_process_vars.cache_aging_pcnt2 =
- sdbc_dynmem->ci_sdbc_cache_aging_pcnt2.value.ul;
- local_dm_process_vars.max_holds_pcnt =
- sdbc_dynmem->ci_sdbc_max_holds_pcnt.value.ul;
- local_dm_process_vars.process_directive =
- sdbc_dynmem->ci_sdbc_process_directive.value.ul;
- (void) sdbc_edit_xfer_process_vars_dm(&local_dm_process_vars);
-
- if (process_vars->process_directive & WAKE_DEALLOC_THREAD_DM) {
- process_vars->process_directive &=
- ~WAKE_DEALLOC_THREAD_DM;
- mutex_enter(&dynmem_processing_dm.thread_dm_lock);
- cv_broadcast(&dynmem_processing_dm.thread_dm_cv);
- mutex_exit(&dynmem_processing_dm.thread_dm_lock);
- }
-
- return (0);
- }
-
- /* default to READ */
- sdbc_dynmem->ci_sdbc_simplect.value.ul = simplect_dm;
- sdbc_dynmem->ci_sdbc_monitor_dynmem.value.ul =
- process_vars->monitor_dynmem_process;
- sdbc_dynmem->ci_sdbc_max_dyn_list.value.ul =
- process_vars->max_dyn_list;
- sdbc_dynmem->ci_sdbc_cache_aging_ct1.value.ul =
- process_vars->cache_aging_ct1;
- sdbc_dynmem->ci_sdbc_cache_aging_ct2.value.ul =
- process_vars->cache_aging_ct2;
- sdbc_dynmem->ci_sdbc_cache_aging_ct3.value.ul =
- process_vars->cache_aging_ct3;
- sdbc_dynmem->ci_sdbc_cache_aging_sec1.value.ul =
- process_vars->cache_aging_sec1;
- sdbc_dynmem->ci_sdbc_cache_aging_sec2.value.ul =
- process_vars->cache_aging_sec2;
- sdbc_dynmem->ci_sdbc_cache_aging_sec3.value.ul =
- process_vars->cache_aging_sec3;
- sdbc_dynmem->ci_sdbc_cache_aging_pcnt1.value.ul =
- process_vars->cache_aging_pcnt1;
- sdbc_dynmem->ci_sdbc_cache_aging_pcnt2.value.ul =
- process_vars->cache_aging_pcnt2;
- sdbc_dynmem->ci_sdbc_max_holds_pcnt.value.ul =
- process_vars->max_holds_pcnt;
- sdbc_dynmem->ci_sdbc_process_directive.value.ul =
- process_vars->process_directive;
-
- sdbc_dynmem->ci_sdbc_alloc_ct.value.ul = process_vars->alloc_ct;
- sdbc_dynmem->ci_sdbc_dealloc_ct.value.ul = process_vars->dealloc_ct;
- sdbc_dynmem->ci_sdbc_history.value.ul = process_vars->history;
- sdbc_dynmem->ci_sdbc_nodatas.value.ul = process_vars->nodatas;
- sdbc_dynmem->ci_sdbc_candidates.value.ul = process_vars->candidates;
- sdbc_dynmem->ci_sdbc_deallocs.value.ul = process_vars->deallocs;
- sdbc_dynmem->ci_sdbc_hosts.value.ul = process_vars->hosts;
- sdbc_dynmem->ci_sdbc_pests.value.ul = process_vars->pests;
- sdbc_dynmem->ci_sdbc_metas.value.ul = process_vars->metas;
- sdbc_dynmem->ci_sdbc_holds.value.ul = process_vars->holds;
- sdbc_dynmem->ci_sdbc_others.value.ul = process_vars->others;
- sdbc_dynmem->ci_sdbc_notavail.value.ul = process_vars->notavail;
-
- return (0);
-}
-#endif
diff --git a/usr/src/uts/common/avs/ns/sdbc/sd_bcache.h b/usr/src/uts/common/avs/ns/sdbc/sd_bcache.h
deleted file mode 100644
index 0cf9bf3836..0000000000
--- a/usr/src/uts/common/avs/ns/sdbc/sd_bcache.h
+++ /dev/null
@@ -1,1161 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SD_BCACHE_H
-#define _SD_BCACHE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef DS_DDICT
-#include <sys/nsctl/contract.h>
-#endif
-#include <sys/nsctl/nsctl.h>
-#include <sys/nsctl/sdbc_ioctl.h>
-#include <sys/nsctl/sd_hash.h>
-#include <sys/nsctl/sd_cache.h>
-#include <sys/nsctl/sd_conf.h>
-#include <sys/nsctl/safestore.h>
-
-/*
- * Definitions for kstats
- */
-#define SDBC_KSTAT_CLASS "storedge"
-#define SDBC_KSTAT_MODULE "sdbc"
-
-#ifdef DEBUG
-#define SDBC_KSTAT_DYNMEM "dynmem"
-#endif
-
-#define SDBC_KSTAT_CDNAME "cdname"
-#define SDBC_KSTAT_CDSTATS "cd"
-#define SDBC_KSTAT_GSTATS "global"
-#define SDBC_KSTAT_STATS "sdbcstats"
-#define SDBC_IOKSTAT_GSTATS "gsdbc"
-#define SDBC_IOKSTAT_CDSTATS "sdbc"
-
-/* Global kstat field names */
-#define SDBC_GKSTAT_COUNT "sdbc_count"
-#define SDBC_GKSTAT_LOC_COUNT "sdbc_loc_count"
-#define SDBC_GKSTAT_RDHITS "sdbc_rdhits"
-#define SDBC_GKSTAT_RDMISS "sdbc_rdmiss"
-#define SDBC_GKSTAT_WRHITS "sdbc_wrhits"
-#define SDBC_GKSTAT_WRMISS "sdbc_wrmiss"
-#define SDBC_GKSTAT_BLKSIZE "sdbc_blksize"
-#define SDBC_GKSTAT_LRU_BLOCKS "sdbc_lru_blocks"
-
-#ifdef DEBUG
-#define SDBC_GKSTAT_LRU_NOREQ "sdbc_lru_noreq"
-#define SDBC_GKSTAT_LRU_REQ "sdbc_lru_req"
-#endif
-
-#define SDBC_GKSTAT_WLRU_INQ "sdbc_wlru_inq"
-#define SDBC_GKSTAT_CACHESIZE "sdbc_cachesize"
-#define SDBC_GKSTAT_NUMBLOCKS "sdbc_numblocks"
-#define SDBC_GKSTAT_NUM_SHARED "sdbc_num_shared"
-#define SDBC_GKSTAT_WRCANCELNS "sdbc_wrcancelns"
-#define SDBC_GKSTAT_DESTAGED "sdbc_destaged"
-#define SDBC_GKSTAT_NODEHINTS "sdbc_nodehints"
-
-/* per-cache descriptor kstats field names */
-#define SDBC_CDKSTAT_VOL_NAME "sdbc_vol_name"
-#define SDBC_CDKSTAT_FAILED "sdbc_failed"
-#define SDBC_CDKSTAT_CD "sdbc_cd"
-#define SDBC_CDKSTAT_CACHE_READ "sdbc_cache_read"
-#define SDBC_CDKSTAT_CACHE_WRITE "sdbc_cache_write"
-#define SDBC_CDKSTAT_DISK_READ "sdbc_disk_read"
-#define SDBC_CDKSTAT_DISK_WRITE "sdbc_disk_write"
-#define SDBC_CDKSTAT_FILESIZE "sdbc_filesize"
-#define SDBC_CDKSTAT_NUMDIRTY "sdbc_numdirty"
-#define SDBC_CDKSTAT_NUMIO "sdbc_numio"
-#define SDBC_CDKSTAT_NUMFAIL "sdbc_numfail"
-#define SDBC_CDKSTAT_DESTAGED "sdbc_destaged"
-#define SDBC_CDKSTAT_WRCANCELNS "sdbc_wrcancelns"
-#define SDBC_CDKSTAT_CDHINTS "sdbc_cdhints"
-
-#ifdef DEBUG
-/* dynmem kstats field names */
-#define SDBC_DMKSTAT_MONITOR_DYNMEM "sdbc_monitor_dynmem"
-#define SDBC_DMKSTAT_MAX_DYN_LIST "sdbc_max_dyn_list"
-#define SDBC_DMKSTAT_CACHE_AGING_CT1 "sdbc_cache_aging_ct1"
-#define SDBC_DMKSTAT_CACHE_AGING_CT2 "sdbc_cache_aging_ct2"
-#define SDBC_DMKSTAT_CACHE_AGING_CT3 "sdbc_cache_aging_ct3"
-#define SDBC_DMKSTAT_CACHE_AGING_SEC1 "sdbc_cache_aging_sec1"
-#define SDBC_DMKSTAT_CACHE_AGING_SEC2 "sdbc_cache_aging_sec2"
-#define SDBC_DMKSTAT_CACHE_AGING_SEC3 "sdbc_cache_aging_sec3"
-#define SDBC_DMKSTAT_CACHE_AGING_PCNT1 "sdbc_cache_aging_pcnt1"
-#define SDBC_DMKSTAT_CACHE_AGING_PCNT2 "sdbc_cache_aging_pcnt2"
-#define SDBC_DMKSTAT_MAX_HOLDS_PCNT "sdbc_max_holds_pcnt"
-#define SDBC_DMKSTAT_ALLOC_CNT "sdbc_alloc_cnt"
-#define SDBC_DMKSTAT_DEALLOC_CNT "sdbc_dealloc_cnt"
-#define SDBC_DMKSTAT_HISTORY "sdbc_history"
-#define SDBC_DMKSTAT_NODATAS "sdbc_nodatas"
-#define SDBC_DMKSTAT_CANDIDATES "sdbc_candidates"
-#define SDBC_DMKSTAT_DEALLOCS "sdbc_deallocs"
-#define SDBC_DMKSTAT_HOSTS "sdbc_hosts"
-#define SDBC_DMKSTAT_PESTS "sdbc_pests"
-#define SDBC_DMKSTAT_METAS "sdbc_metas"
-#define SDBC_DMKSTAT_HOLDS "sdbc_holds"
-#define SDBC_DMKSTAT_OTHERS "sdbc_others"
-#define SDBC_DMKSTAT_NOTAVAIL "sdbc_notavail"
-#define SDBC_DMKSTAT_PROCESS_DIRECTIVE "sdbc_process_directive"
-#define SDBC_DMKSTAT_SIMPLECT "sdbc_simplect"
-
-#endif
-
-/* ... values are in range [0-BLK_FBAS] */
-typedef uint32_t sdbc_cblk_fba_t; /* FBA len or offset in cache block */
-
-typedef unsigned char *ucaddr_t; /* unsigned char pointer */
-
-/*
- * Atomic exchange function
- */
-
-#ifdef _KERNEL
-
-/*
- * Note: ldstub sets all bits in the memory byte.
- * so far this is compatible with the usage of xmem_bu() whereby
- * the values of ptr are either 0 or 1, and the xmem_bu() is used
- * to set the byte to 1.
- */
-#define xmem_bu(val, ptr) nsc_ldstub((uint8_t *)ptr)
-#define atomic_swap xmem_bu
-#define sd_serialize nsc_membar_stld
-
-#endif /* _KERNEL */
-
-#if defined(_KERNEL) || defined(_KMEMUSER)
-
-#if defined(_SD_8K_BLKSIZE)
-typedef unsigned short _sd_bitmap_t;
-#else
-typedef unsigned char _sd_bitmap_t;
-#endif
-
-/*
- * CCTL flag types
- */
-
-/*
- * Note: CC_INUSE and CC_PAGEIO are dummy flags that are used in
- * individual flags bytes (cc_inuse and cc_pageio) NOT cc_flag.
- * Thus they can take any convenient value, however, they must be
- * distinct and non-zero.
- */
-#define CC_INUSE 0x01 /* Cache entry is in use */
-#define CC_PAGEIO 0x02 /* Pagelist IO is active for cache entry */
-
-/*
- * Real cc_flag values.
- */
-#define CC_PEND_DIRTY 0x02 /* The entry needs to be reprocessed for io */
-#define CC_PINNED 0x04 /* The entry has data that is "pinned" */
-#define CC_PINNABLE 0x08 /* Issue pin if write fails */
-#define CC_QHEAD 0x10 /* NSC_NOCACHE: requeue at head */
-
-/* specify the size of _sd_cctl[] array */
-#define _SD_CCTL_GROUPS 32
-
-/*
- * Individual SDBC cache block entry
- * "cc_lock" must be held when changing dirty/valid bits.
- * "cc_inuse" (optimistic) atomic exchange replaces check/set of
- * CC_INUSE bit in cc_flag; special handling of rare collisions.
- * "cc_pageio" flusher / client locking of pagelist io operations,
- * atomic exchange - needs machine ld/st protection.
- * "cc_iostatus" is set by flusher without holding cc_lock,
- * writer will set CC_PEND_DIRTY if cc_iostatus is set.
- * Thus "cc_inuse", "cc_iostatus" and "cc_pageio" are volatile.
- *
- * The cc_await_* values are in the main _sd_cctl to avoid over
- * signalling _cc_blkcv.
- *
- * The _sd_cctl structure is aligned to group related members and
- * to ensure good packing.
- */
-
-typedef struct _sd_cctl_sync {
- kcondvar_t _cc_blkcv; /* Synchronisation var to block on */
- kmutex_t _cc_lock; /* Cache entry spinlock */
-} _sd_cctl_sync_t;
-
-typedef struct sd_addr_s { /* Generic address structure */
- unsigned char *sa_virt; /* Virtual address of data */
-} sd_addr_t;
-
-/*
- * See notes above.
- */
-
-typedef struct _sd_cctl {
- _sd_hash_hd_t cc_head; /* hash information - must be first */
- struct _sd_cctl *cc_next, *cc_prev; /* next and prev in a chain */
- struct _sd_cctl *cc_chain; /* chaining request centries */
- struct _sd_cctl *cc_dirty_next; /* for chaining sequential writes */
- struct _sd_cctl *cc_dirty_link; /* for chaining the dirty lists */
- struct _sd_cctl *cc_dirty_net_next; /* for chaining net writes */
- struct _sd_cctl *cc_dirty_net_link; /* for chaining net lists */
- uint_t cc_seq; /* sequence number: for lru optim */
- volatile int net_iostatus; /* net status of io */
- volatile _sd_bitmap_t net_dirty; /* net cache block dirty mask */
- _sd_bitmap_t cc_valid; /* Cache block valid mask */
- _sd_bitmap_t cc_toflush; /* Cache block deferred dirty mask */
- volatile _sd_bitmap_t cc_dirty; /* Cache block dirty mask */
- volatile ushort_t cc_await_use; /* # waiting for this entry (inuse) */
- volatile ushort_t cc_await_page; /* # waiting for this entry (pageio) */
- volatile uchar_t cc_inuse; /* atomic_swap(CC_INUSE, cc_inuse) */
- volatile uchar_t cc_pageio; /* atomic_swap(CC_PAGEIO, cc_pageio) */
- uchar_t cc_flag; /* flag */
- char cc_iocount; /* number of ios in progress */
- volatile uchar_t cc_iostatus; /* status of io */
- uchar_t cc_prot; /* Segmented LRU protection flag */
- sd_addr_t cc_addr; /* Data address information */
- ss_centry_info_t *cc_write; /* mirrored writes control block */
- struct _sd_cctl_sync *cc_sync; /* Cache block synchronisation blk */
-
- /* support for backend i/o memory coalescing */
- sd_addr_t cc_anon_addr; /* address for backend mem coalescing */
- int cc_anon_len; /* length of anon mem */
-
- clock_t cc_creat;
- int cc_hits;
-
- /* dynamic memory support fields */
- uint_t cc_aging_dm; /* For bit settings */
- /* see defines */
- int cc_alloc_size_dm; /* mem allocation */
- /* size bytes */
- struct _sd_cctl *cc_head_dm; /* ptr to host centry */
- /* for a host/pest */
- /* chain */
- struct _sd_cctl *cc_next_dm; /* ptr to next centry */
- /* in host/pest chain */
- struct _sd_cctl *cc_link_list_dm; /* simple link list */
- /* ptr of all centrys */
- /* dynmem chains */
- /* _sd_queue_t *cc_dmchain_q; dmqueue */
- int cc_cblocks; /* number of centrys for size_dm */
-
- /* debugging stats */
- int cc_alloc_ct_dm;
- int cc_dealloc_ct_dm;
-
-} _sd_cctl_t;
-
-/* cache entry allocation tokens */
-typedef struct sdbc_allocbuf_s {
- intptr_t opaque[2]; /* must be initialized to 0 */
-} sdbc_allocbuf_t;
-
-typedef struct sdbc_allocbuf_impl_s {
- _sd_cctl_t *sab_dmchain;
- int sab_q; /* dmqueue of last chain allocated */
- int reserved; /* stats ? */
-} sdbc_allocbuf_impl_t;
-
-/*
- * bits for flag argument to sdbc_centry_alloc() and callees.
- */
-#define ALLOC_LOCKED 0x1 /* locked status of sdbc_queue_lock */
-#define ALLOC_NOWAIT 0x2 /* do not block, return NULL */
-
-/*
- * definitions supporting the dynmem dealloc thread
- */
-#define LOW_RESOURCES_DM -1
-
-#define NO_THREAD_DM -1
-#define PROCESS_CACHE_DM 0
-#define CACHE_SHUTDOWN_DM 1
-#define CACHE_THREAD_TERMINATED_DM 2
-#define TIME_DELAY_LVL0 3
-#define TIME_DELAY_LVL1 4
-#define TIME_DELAY_LVL2 5
-#define HISTORY_LVL0 (ushort_t)0
-#define HISTORY_LVL1 (ushort_t)0x00ff
-#define HISTORY_LVL2 (ushort_t)0xff00
-/*
- * definitions supporing the ddditional fields in the cache
- * entry structure for dyn mem
- */
-#define FIRST_AGING_DM 0x00000001
-#define FINAL_AGING_DM 0x000000ff
-#define FOUND_IN_HASH_DM 0x00000100 /* used to bring cent info */
- /* out of sd_centry_alloc() */
-#define FOUND_HOLD_OVER_DM 0x00000200 /* used to bring cent info */
- /* out of sd_centry_alloc() */
-#define HOST_ENTRY_DM 0x00000400
-#define PARASITIC_ENTRY_DM 0x00000800
-#define STICKY_METADATA_DM 0x00001000
-#define CATAGORY_ENTRY_DM (HOST_ENTRY_DM|PARASITIC_ENTRY_DM| \
- STICKY_METADATA_DM)
-#define ELIGIBLE_ENTRY_DM 0x00002000
-#define HASH_ENTRY_DM 0x00008000
-#define HOLD_ENTRY_DM 0x00010000
-#define ENTRY_FIELD_DM (ELIGIBLE_ENTRY_DM|HASH_ENTRY_DM|HOLD_ENTRY_DM)
-#define AVAIL_ENTRY_DM 0x00020000
-
-/* info only */
-#define PREFETCH_BUF_I 0x00040000 /* implicit read-ahead */
-#define PREFETCH_BUF_E 0x00080000 /* explicit read-ahead */
-#define PREFETCH_BUF_IR 0x00100000 /* release when read complete */
-
-/* error processing */
-#define BAD_ENTRY_DM 0x20000000 /* inconsistent ccent */
-#define BAD_CHAIN_DM 0x40000000 /* chain containing bad ccent */
-
-/*
- * definitions supporting the dynmem monitoring
- */
-#define RPT_SHUTDOWN_PROCESS_DM 0x00000001
-#define RPT_DEALLOC_STATS1_DM 0x00000002 /* nodat,cand,host,pest,meta, */
- /* other,dealloc */
-#define RPT_DEALLOC_STATS2_DM 0x00000004 /* hysterisis,grossct */
-/*
- * definitions supporting the processing directive bit flags
- */
-#define WAKE_DEALLOC_THREAD_DM 0x00000001 /* one shot - acted */
- /* on then cleared */
-#define MAX_OUT_ACCEL_HIST_FLAG_DM 0x00000002 /* one shot - acted */
- /* on then cleared */
-/*
- * Default - Max - Min definitions
- */
-#define MAX_DYN_LIST_DEFAULT 8
-#define MONITOR_DYNMEM_PROCESS_DEFAULT 0
-#define CACHE_AGING_CT_DEFAULT 3
-#define CACHE_AGING_SEC1_DEFAULT 10
-#define CACHE_AGING_SEC2_DEFAULT 5
-#define CACHE_AGING_SEC3_DEFAULT 1
-#define CACHE_AGING_PCNT1_DEFAULT 50
-#define CACHE_AGING_PCNT2_DEFAULT 25
-#define MAX_HOLDS_PCNT_DEFAULT 0
-#define PROCESS_DIRECTIVE_DEFAULT 0
-
-#define CACHE_AGING_CT_MAX FINAL_AGING_DM /* 255 */
-#define CACHE_AGING_SEC1_MAX 255 /* arbitrary but easy to remember */
-#define CACHE_AGING_SEC2_MAX 255 /* arbitrary but easy to remember */
-#define CACHE_AGING_SEC3_MAX 255 /* arbitrary but easy to remember */
-#define CACHE_AGING_PCNT1_MAX 100
-#define CACHE_AGING_PCNT2_MAX 100
-#define MAX_HOLDS_PCNT_MAX 100
-/*
- * dynmem global structure defn
- */
-typedef struct _dm_process_vars {
- kcondvar_t thread_dm_cv;
- kmutex_t thread_dm_lock;
- int sd_dealloc_flagx; /* gen'l purpose bit flag */
- int monitor_dynmem_process; /* bit flag indicating what to report */
- int max_dyn_list; /* max num of pages to allow list to */
- /* grow */
- /* cache aging parameter set */
- int cache_aging_ct1; /* hosts/pests - aging hits which */
- /* trigger dealloc */
- int cache_aging_ct2; /* metas - aging hits which */
- /* trigger dealloc not yet imple */
- int cache_aging_ct3; /* holds - aging hits which */
- /* trigger dealloc */
- int cache_aging_sec1; /* sleep time between cache list */
- /* exam - 100% to pcnt1 free */
- int cache_aging_sec2; /* sleep time between cache list */
- /* exam - pcnt1 to pcnt2 free */
- int cache_aging_sec3; /* sleep time between cache list */
- /* exam - pcnt2 to 0% free */
- int cache_aging_pcnt1; /* % free when to kick in accel */
- /* aging - sec2 */
- int cache_aging_pcnt2; /* % free when to kick in accel */
- /* aging - sec3 */
- int max_holds_pcnt; /* max % of cents to act as holdovers */
- /* stats - debug */
- int alloc_ct; /* gross count */
- int dealloc_ct; /* gross count */
- /* thread stats - debug and on the fly tuning of dealloc vars */
- int history; /* history flag */
- int nodatas; /* # cctls w/o data assigned */
- int notavail; /* # cctls w/data but in use */
- int candidates; /* # cand. for dealloc checking */
- int deallocs; /* # deallocs */
- int hosts; /* # hosts */
- int pests; /* # pests */
- int metas; /* # metas - sticky meata data */
- int holds; /* # holdovers - single page, fully */
- /* aged but not dealloc'd or hash */
- /* del'd */
- int others; /* # everybody else */
- int process_directive; /* processing directive bitmap flag */
- /* standard stats (no prefetch tallies here) */
- int read_hits; /* found in cache memory */
- int read_misses; /* not found in cache memory */
- int write_hits; /* found in cache memory */
- int write_misses; /* not found in cache memory */
- int write_thru; /* not bothering to put in cache mem */
- /*
- * prefetch tracked by _sd_prefetch_valid_cnt and _sd_prefetch_busy_cnt
- * might want different usage ?
- */
- int prefetch_hits;
- int prefetch_misses;
-} _dm_process_vars_t;
-
-/*
- * dynmem interface
- */
-int sdbc_edit_xfer_process_vars_dm(_dm_process_vars_t *process_vars);
-
-/*
- * Defines to hide the sd_addr_t structure
- */
-
-#define cc_data cc_addr.sa_virt
-
-
-/*
- * Defines to hide the synchronisation block
- */
-
-#define cc_blkcv cc_sync->_cc_blkcv
-#define cc_lock cc_sync->_cc_lock
-
-/*
- * This struct exists solely so that sd_info is able to
- * extract this kind of data from sdbc without passing out
- * the entire _sd_cctl_t which has lots of pointers which
- * makes it impossible to deal with in 32bit program and an
- * LP64 kernel.
- */
-
-typedef struct {
- int ci_write; /* 0 == no wrt data */
- _sd_bitmap_t ci_dirty; /* dirty bits */
- _sd_bitmap_t ci_valid; /* valid bits */
- int ci_cd; /* the cd */
- nsc_off_t ci_dblk; /* the disk block number */
-} sdbc_info_t;
-
-typedef struct _sd_wr_cctl {
- ss_resource_t wc_res;
- ss_centry_info_t wc_centry_info;
-} _sd_wr_cctl_t;
-
-typedef struct _sd_queue {
- struct _sd_cctl sq_qhead; /* LRU queue head */
- kmutex_t sq_qlock; /* LRU spinlock */
- char sq_await; /* number blocked on lru sema */
- int sq_inq; /* Number of LRU entries in q */
- unsigned int sq_seq; /* sequence number for lru optim */
- unsigned int sq_req_stat;
- unsigned int sq_noreq_stat;
-
- /* dmchain support */
- int sq_dmchain_cblocks; /* dmchain len in ccents */
-} _sd_queue_t;
-
-
-
-/*
- * The net structure contains which memory net has been configured for
- * cache, the amount of space allocated, the write control and fault
- * tolerant blocks etc
- */
-
-typedef struct _sd_net {
- unsigned short sn_psize; /* Page size of memory in this net */
- unsigned char sn_configured; /* is this network configured */
- size_t sn_csize; /* Cache size in bytes */
- uint_t sn_wsize; /* Write size in bytes */
- int sn_cpages; /* number of pages for Cache */
-}_sd_net_t;
-
-#endif /* _KERNEL || _KMEMUSER */
-
-
-/*
- * Shared structure shared between cds and statistics
- *
- * NOTE - this structure is visible as an ioctl result.
- * If anything changes here _sd_get_stats() and convert_stats()
- * will need to be changed.
- */
-typedef struct _sd_shared {
- nsc_size_t sh_filesize; /* Filesize (in FBAs) */
- volatile uchar_t sh_alloc; /* Is this allocated? */
- volatile uchar_t sh_failed; /* Disk failure status (0 == ok, */
- /* 1 == i/o error, 2 == open failed ) */
- unsigned short sh_cd; /* the cache descriptor. (for stats) */
- int sh_cache_read; /* Number of FBAs read from cache */
- int sh_cache_write; /* Number of FBAs written to cache */
- int sh_disk_read; /* Number of FBAs read from disk */
- int sh_disk_write; /* Number of FBAs written to disk */
- volatile int sh_numdirty; /* Number of dirty blocks */
- volatile int sh_numio; /* Number of blocks on way to disk */
- volatile int sh_numfail; /* Number of blocks failed */
- int sh_flushloop; /* Loops delayed so far */
- int sh_flag; /* Flags visible to user programs */
- int sh_destaged; /* number of bytes destaged to disk */
- int sh_wrcancelns; /* number of writes to dirty blocks */
- char sh_filename[NSC_MAXPATH];
-} _sd_shared_t;
-
-
-#if defined(_KERNEL) || defined(_KMEMUSER)
-
-/*
- * Cache descriptor information.
- */
-typedef struct _sd_cd_info {
- int cd_desc; /* The cache descriptor */
- int cd_flag; /* Flag */
- nsc_fd_t *cd_rawfd; /* File descriptor for raw device */
- strategy_fn_t cd_strategy; /* Cached copy of strategy func */
- dev_t cd_crdev; /* The device this represents */
- nsc_iodev_t *cd_iodev; /* I/O device for callbacks */
- kmutex_t cd_lock; /* spinlock guarding this cd */
- volatile uchar_t cd_writer; /* Disk writer status */
- unsigned int cd_hint; /* Hints for this descriptor */
- ss_voldata_t *cd_global; /* RM information for this cd */
- struct _sd_cctl *cd_dirty_head, *cd_dirty_tail; /* dirty chain */
- struct _sd_cctl *cd_last_ent; /* last entry in dirty chain, for */
- int cd_lastchain; /* sequential optimization */
- struct _sd_cctl *cd_lastchain_ptr; /* last sequential chain */
- struct _sd_cctl *cd_io_head, *cd_io_tail; /* io in progress q */
- struct _sd_cctl *cd_fail_head;
- struct _sd_shared *cd_info; /* shared info (filename, size) */
- char cd_failover; /* done nsc_reserve during failover */
- volatile char cd_recovering; /* cd is being recovered failover or */
- /* disk_online */
- char cd_write_inprogress;
- struct sd_net_hnd *net_hnd;
-} _sd_cd_info_t;
-
-typedef struct _sd_buf_hlist {
- _sd_buf_handle_t hl_top;
- kmutex_t hl_lock;
- short hl_count;
-} _sd_buf_hlist_t;
-
-#endif /* _KERNEL || _KMEMUSER */
-
-/*
- * Index into the following st_mem_sizes[] array
- */
-#define _SD_LOCAL_MEM 0x00 /* type of memory to allocate */
-#define _SD_CACHE_MEM 0x01
-#define _SD_IOBUF_MEM 0x02
-#define _SD_HASH_MEM 0x03
-#define _SD_GLOBAL_MEM 0x04
-#define _SD_STATS_MEM 0x05
-#define _SD_MAX_MEM _SD_STATS_MEM + 1
-
-/* maintain stat struct layout */
-#define NUM_WQ_PAD 4
-/*
- * cache statistics structure
- *
- * NOTE - if anything changes here _sd_get_stats() and convert_stats()
- * must be changed and _sd_stats32_t must also be synchronized.
- *
- */
-typedef struct _sd_stats {
- int net_dirty;
- int net_pending;
- int net_free;
- int st_count; /* number of opens for device */
- int st_loc_count; /* number of open devices */
- int st_rdhits; /* number of read hits */
- int st_rdmiss; /* number of read misses */
- int st_wrhits; /* number of write hits */
- int st_wrmiss; /* number of write misses */
- int st_blksize; /* cache block size (in bytes) */
- uint_t st_lru_blocks;
- uint_t st_lru_noreq;
- uint_t st_lru_req;
- int st_wlru_inq; /* number of write blocks */
- int st_cachesize; /* cache size (in bytes) */
- int st_numblocks; /* # of cache blocks */
- int st_wrcancelns; /* # of write cancellations */
- int st_destaged; /* # of bytes destaged to disk */
- _sd_shared_t st_shared[1]; /* shared structures */
-} _sd_stats_t;
-
-typedef struct _sd_stats_32 {
- int net_dirty;
- int net_pending;
- int net_free;
- int st_count; /* number of opens for device */
- int st_loc_count; /* number of open devices */
- int st_rdhits; /* number of read hits */
- int st_rdmiss; /* number of read misses */
- int st_wrhits; /* number of write hits */
- int st_wrmiss; /* number of write misses */
- int st_blksize; /* cache block size (in bytes) */
- uint_t st_lru_blocks;
- uint_t st_lru_noreq;
- uint_t st_lru_req;
- int st_wlru_inq; /* number of write blocks */
- int st_cachesize; /* cache size (in bytes) */
- int st_numblocks; /* # of cache blocks */
- int st_wrcancelns; /* # of write cancellations */
- int st_destaged; /* # of bytes destaged to disk */
- _sd_shared_t st_shared[1]; /* shared structures */
-} _sd_stats32_t;
-
-
-#if defined(_KERNEL) || defined(_KMEMUSER)
-
-/*
- * The map structure contains mapping between a mask and relevent information
- * that would take some computation at runtime.
- * Given a mask, what is the first LSB set (stpos)
- * Given a mask, what are the consecutive number of LSB bits set (len)
- * Given a mask, what would be a new mask if the consecutive LSB bits are reset
- * Given a mask, how many ios would be needed to flush this block.
- * Given a mask, how many buffer descriptor lists (bdls) would be needed
- * on a read.
- */
-
-typedef struct _sd_map_info {
- unsigned char mi_stpos; /* position of first LSB set */
- unsigned char mi_len; /* Length of consecutive LSB set */
- unsigned char mi_dirty_count; /* number of fragmented bits */
- unsigned char mi_io_count; /* number of bdls for a given mask */
- _sd_bitmap_t mi_mask; /* new mask with cons. LSB's reset */
-} _sd_map_info_t;
-
-
-/*
- * cc_inuse is set with atomic exchange instruction
- * when clearing, must check for waiters.
- * sd_serialize prohibits speculative reads
- */
-#define CENTRY_INUSE(centry) ((centry)->cc_inuse)
-#define SET_CENTRY_INUSE(centry) \
- ((centry)->cc_inuse || atomic_swap(CC_INUSE, &(centry)->cc_inuse))
-#define CLEAR_CENTRY_INUSE(centry) { \
- (centry)->cc_inuse = 0; \
- sd_serialize(); \
- if ((centry)->cc_await_use) { \
- mutex_enter(&(centry)->cc_lock); \
- cv_broadcast(&(centry)->cc_blkcv); \
- mutex_exit(&(centry)->cc_lock); \
- } \
-}
-
-
-/*
- * cc_pageio is set with atomic exchange instruction
- * when clearing, must check for waiters.
- * sd_serialize prohibits speculative reads
- */
-#define CENTRY_PAGEIO(centry) ((centry)->cc_pageio)
-#define SET_CENTRY_PAGEIO(centry) \
- ((centry)->cc_pageio || atomic_swap(CC_PAGEIO, &(centry)->cc_pageio))
-#define WAIT_CENTRY_PAGEIO(centry, stat) { \
- while (SET_CENTRY_PAGEIO(centry)) { \
- (stat)++; \
- _sd_cc_wait(CENTRY_CD(centry), CENTRY_BLK(centry), \
- centry, CC_PAGEIO); \
- } \
-}
-#define CLEAR_CENTRY_PAGEIO(centry) { \
- (centry)->cc_pageio = 0; \
- sd_serialize(); \
- if ((centry)->cc_await_page) { \
- mutex_enter(&(centry)->cc_lock); \
- cv_broadcast(&(centry)->cc_blkcv); \
- mutex_exit(&(centry)->cc_lock); \
- } \
-}
-
-
-#define CENTRY_DIRTY_PENDING(centry) ((centry)->cc_flag & CC_PEND_DIRTY)
-#define CENTRY_PINNED(centry) ((centry)->cc_flag & CC_PINNED)
-#define CENTRY_PINNABLE(centry) ((centry)->cc_flag & CC_PINNABLE)
-#define CENTRY_QHEAD(centry) ((centry)->cc_flag & CC_QHEAD)
-
-#define CENTRY_DIRTY(centry) ((centry)->cc_dirty)
-#define CENTRY_CD(centry) ((centry)->cc_head.hh_cd)
-#define CENTRY_BLK(centry) ((centry)->cc_head.hh_blk_num)
-#define CENTRY_IO_INPROGRESS(centry) ((centry)->cc_iostatus)
-
-#define HANDLE_CD(handle) ((handle)->bh_cd)
-
-#endif /* _KERNEL || _KMEMUSER */
-
-#if defined(_KERNEL)
-
-#define CENTRY_SET_FTPOS(centry) \
- (centry)->cc_write->sc_cd = CENTRY_CD(centry), \
- (centry)->cc_write->sc_fpos = CENTRY_BLK(centry)
-
-#define CC_CD_BLK_MATCH(cd, blk, centry) \
- (((centry)->cc_head.hh_cd == cd) && \
- ((centry)->cc_head.hh_blk_num == blk))
-
-
-#define _SD_ZEROADDR ((ucaddr_t)(_sd_net_config.sn_zeroaddr))
-
-
-#define ASSERT_LEN(len) \
- if (len > _SD_MAX_FBAS) {\
- cmn_err(CE_WARN, \
- "!sdbc(ASSERT_LEN) fba exceeds limits. fba_len %" \
- NSC_SZFMT ". Max %d", len, _SD_MAX_FBAS); \
- return (EIO); }
-
-#define ASSERT_IO_SIZE(fba_num, fba_len, cd) \
- if ((fba_num + fba_len) > \
- (_sd_cache_files[(cd)].cd_info->sh_filesize)) { \
- cmn_err(CE_WARN, \
- "!sdbc(ASSERT_IO_SIZE) io beyond end of file." \
- " fpos %" NSC_SZFMT " len %" NSC_SZFMT " file size 0 - %" \
- NSC_SZFMT "\n", fba_num, fba_len, \
- (_sd_cache_files[(cd)].cd_info->sh_filesize)); \
- return (EIO); \
- }
-
-
-#define ASSERT_HANDLE_LIMITS(m_h1, m_fpos, m_flen) \
- if (((m_fpos) < (m_h1)->bh_fba_pos) || \
- (((m_fpos) + (m_flen)) > \
- ((m_h1)->bh_fba_pos + (m_h1)->bh_fba_len))) { \
- cmn_err(CE_WARN, \
- "!sdbc(ASSERT_HANDLE_LIMITS) operation out of bounds" \
- " cd %x want %" NSC_SZFMT " to %" NSC_SZFMT ". Handle %" \
- NSC_SZFMT " to %" NSC_SZFMT, HANDLE_CD(m_h1), m_fpos,\
- m_flen, (m_h1)->bh_fba_pos, (m_h1)->bh_fba_len); \
- return (EINVAL); \
- }
-
-
-#define _SD_HANDLE_ACTIVE(handle) ((handle)->bh_flag & NSC_HACTIVE)
-
-#define _SD_CD_HINTS(cd) (_sd_cache_files[(cd)].cd_hint)
-#define _SD_NODE_HINTS (_sd_node_hint)
-
-#define _SD_SETUP_HANDLE(hndl, cd, fpos, flen, flag) { \
- hndl->bh_cd = cd; \
- hndl->bh_vec = hndl->bh_bufvec; \
- hndl->bh_fba_pos = fpos; \
- hndl->bh_fba_len = flen; \
- hndl->bh_busy_thread = nsc_threadp(); \
- if (cd == _CD_NOHASH) \
- hndl->bh_flag |= \
- (flag | _SD_NODE_HINTS | NSC_HACTIVE); \
- else \
- hndl->bh_flag |= \
- (flag | _SD_CD_HINTS(cd) | \
- _SD_NODE_HINTS | NSC_HACTIVE); \
- }
-
-#define _SD_NOT_WRTHRU(handle) (((handle)->bh_flag & _SD_WRTHRU_MASK) == 0)
-#define _SD_IS_WRTHRU(handle) ((handle)->bh_flag & _SD_WRTHRU_MASK)
-
-#define FILE_OPENED(cd) (((cd) >= 0) && ((cd) < (sdbc_max_devs)) && \
- (_sd_cache_files[(cd)].cd_info != NULL) && \
- (_sd_cache_files[(cd)].cd_info->sh_alloc \
- & CD_ALLOCATED))
-
-/*
- * bitmap stuff
- */
-
-#define SDBC_LOOKUP_STPOS(mask) (_sd_lookup_map[(mask)].mi_stpos)
-#define SDBC_LOOKUP_LEN(mask) (_sd_lookup_map[(mask)].mi_len)
-#define SDBC_LOOKUP_MASK(mask) (_sd_lookup_map[(mask)].mi_mask)
-#define SDBC_LOOKUP_DTCOUNT(mask) (_sd_lookup_map[(mask)].mi_dirty_count)
-#define SDBC_LOOKUP_IOCOUNT(mask) (_sd_lookup_map[(mask)].mi_io_count)
-#define SDBC_LOOKUP_MODIFY(mask) (mask &= ~(_sd_lookup_map[(mask)].mi_mask))
-
-#define SDBC_IS_FRAGMENTED(bmap) (!_sd_contig_bmap[(bmap)])
-#define SDBC_IS_CONTIGUOUS(bmap) (_sd_contig_bmap[(bmap)])
-
-#endif /* _KERNEL */
-
-#if defined(_KERNEL) || defined(_KMEMUSER)
-
-#define SDBC_GET_BITS(fba_off, fba_len) \
- (_fba_bits[(fba_len)] << (fba_off))
-
-#define SDBC_SET_VALID_BITS(fba_off, fba_len, cc_entry) \
- (cc_entry)->cc_valid |= SDBC_GET_BITS(fba_off, fba_len)
-
-#define SDBC_SET_DIRTY(fba_off, fba_len, cc_entry) { \
- _sd_bitmap_t dirty, newdb = SDBC_GET_BITS(fba_off, fba_len); \
- ss_centry_info_t *gl = (cc_entry)->cc_write; \
- (cc_entry)->cc_valid |= newdb; \
- dirty = ((cc_entry)->cc_dirty |= newdb); \
- gl->sc_dirty = dirty; \
- gl->sc_flag = (int)(cc_entry)->cc_flag; \
- SSOP_SETCENTRY(sdbc_safestore, gl); }
-
-#define SDBC_SET_TOFLUSH(fba_off, fba_len, cc_entry) { \
- _sd_bitmap_t dirty, newdb = SDBC_GET_BITS(fba_off, fba_len); \
- ss_centry_info_t *gl = (cc_entry)->cc_write; \
- (cc_entry)->cc_toflush |= newdb; \
- (cc_entry)->cc_valid |= newdb; \
- dirty = (cc_entry)->cc_toflush | (cc_entry)->cc_dirty; \
- gl->sc_dirty = dirty; \
- SSOP_SETCENTRY(sdbc_safestore, gl); }
-
-#define SDBC_VALID_BITS(fba_off, fba_len, cc_entry) \
- ((((cc_entry)->cc_valid) & (SDBC_GET_BITS(fba_off, fba_len))) \
- == (SDBC_GET_BITS(fba_off, fba_len)))
-
-
-#define SDBC_DIRTY_NEIGHBORS(last, next) \
- ((SDBC_IS_CONTIGUOUS((last)->cc_dirty)) && \
- (SDBC_IS_CONTIGUOUS((next)->cc_dirty)) && \
-(((last)->cc_dirty & (1 << (BLK_FBAS - 1))) && ((next)->cc_dirty & 0x01)))
-
-
-#define FULLY_VALID(cc_entry) ((cc_entry)->cc_valid == BLK_FBA_BITS)
-#define SET_FULLY_VALID(cc_entry) \
- ((cc_entry)->cc_valid = BLK_FBA_BITS)
-
-#define FULLY_DIRTY(cc_entry) ((cc_entry)->cc_dirty == BLK_FBA_BITS)
-
-#define _SD_BIT_ISSET(bmap, bit) ((bmap & (1 << bit)) ? 1 : 0)
-#define _SD_BMAP_ISFULL(bmap) (bmap == BLK_FBA_BITS)
-
-#endif /* _KERNEL || _KMEMUSER */
-
-#if defined(_KERNEL)
-
-#if !defined(_SD_NOSTATS)
-#define CACHE_FBA_READ(cd, blks) \
- if (((cd) >= 0) && ((cd) < sdbc_max_devs))\
- _sd_cache_stats->st_shared[(cd)].sh_cache_read += (blks)
-#define DISK_FBA_READ(cd, blks) \
- if (((cd) >= 0) && ((cd) < sdbc_max_devs))\
- _sd_cache_stats->st_shared[(cd)].sh_disk_read += (blks)
-#define CACHE_FBA_WRITE(cd, blks) \
- if (((cd) >= 0) && ((cd) < sdbc_max_devs))\
- _sd_cache_stats->st_shared[(cd)].sh_cache_write += (blks)
-#define DISK_FBA_WRITE(cd, blks) \
- if (((cd) >= 0) && ((cd) < sdbc_max_devs))\
- _sd_cache_stats->st_shared[(cd)].sh_disk_write += (blks)
-#define CACHE_READ_HIT _sd_cache_stats->st_rdhits++
-#define CACHE_READ_MISS _sd_cache_stats->st_rdmiss++
-#define CACHE_WRITE_HIT _sd_cache_stats->st_wrhits++
-#define CACHE_WRITE_MISS _sd_cache_stats->st_wrmiss++
-
-#define CACHE_WRITE_CANCELLATION(cd) {\
- if ((cd) < sdbc_max_devs)\
- _sd_cache_stats->st_shared[(cd)].sh_wrcancelns++;\
- _sd_cache_stats->st_wrcancelns++;\
-}
-
-#define WRITE_DESTAGED(cd, bytes) {\
- if (((cd) >= 0) && ((cd) < sdbc_max_devs))\
- _sd_cache_stats->st_shared[(cd)].sh_destaged += (bytes);\
- _sd_cache_stats->st_destaged += (bytes);\
-}
-
-#define FBA_READ_IO_KSTATS(cd, bytes) {\
- if (((cd) >= 0) && ((cd) < sdbc_max_devs) && sdbc_cd_io_kstats[(cd)]) {\
- KSTAT_IO_PTR(sdbc_cd_io_kstats[(cd)])->reads++;\
- KSTAT_IO_PTR(sdbc_cd_io_kstats[(cd)])->nread += (bytes);\
- }\
- if (sdbc_global_io_kstat) {\
- KSTAT_IO_PTR(sdbc_global_io_kstat)->reads++;\
- KSTAT_IO_PTR(sdbc_global_io_kstat)->nread += (bytes);\
- }\
-}
-
-#define FBA_WRITE_IO_KSTATS(cd, bytes) {\
- if (((cd) >= 0) && ((cd) < sdbc_max_devs) && sdbc_cd_io_kstats[(cd)]) {\
- KSTAT_IO_PTR(sdbc_cd_io_kstats[(cd)])->writes++;\
- KSTAT_IO_PTR(sdbc_cd_io_kstats[(cd)])->nwritten += (bytes);\
- }\
- if (sdbc_global_io_kstat) {\
- KSTAT_IO_PTR(sdbc_global_io_kstat)->writes++;\
- KSTAT_IO_PTR(sdbc_global_io_kstat)->nwritten += (bytes);\
- }\
-}
-
-/* start timer measuring amount of time spent in the cache */
-#define KSTAT_RUNQ_ENTER(cd) {\
- if (((cd) >= 0) && ((cd) < sdbc_max_devs) && \
- sdbc_cd_io_kstats[(cd)] && sdbc_cd_io_kstats_mutexes) {\
- mutex_enter(sdbc_cd_io_kstats[(cd)]->ks_lock);\
- kstat_runq_enter(KSTAT_IO_PTR(sdbc_cd_io_kstats[(cd)]));\
- mutex_exit(sdbc_cd_io_kstats[(cd)]->ks_lock);\
- }\
- if (sdbc_global_io_kstat) {\
- mutex_enter(sdbc_global_io_kstat->ks_lock);\
- kstat_runq_enter(KSTAT_IO_PTR(sdbc_global_io_kstat));\
- mutex_exit(sdbc_global_io_kstat->ks_lock);\
- }\
-}
-
-/* stop timer measuring amount of time spent in the cache */
-#define KSTAT_RUNQ_EXIT(cd) {\
- if (((cd) >= 0) && ((cd) < sdbc_max_devs) && \
- sdbc_cd_io_kstats[(cd)] && sdbc_cd_io_kstats_mutexes) {\
- mutex_enter(sdbc_cd_io_kstats[(cd)]->ks_lock);\
- kstat_runq_exit(KSTAT_IO_PTR(sdbc_cd_io_kstats[(cd)]));\
- mutex_exit(sdbc_cd_io_kstats[(cd)]->ks_lock);\
- }\
- if (sdbc_global_io_kstat) {\
- mutex_enter(sdbc_global_io_kstat->ks_lock);\
- kstat_runq_exit(KSTAT_IO_PTR(sdbc_global_io_kstat));\
- mutex_exit(sdbc_global_io_kstat->ks_lock);\
- }\
-}
-
-#else
-#define CACHE_FBA_READ(cd, blks)
-#define DISK_FBA_READ(cd, blks)
-#define CACHE_FBA_WRITE(cd, blks)
-#define DISK_FBA_WRITE(cd, blks)
-#define CACHE_READ_HIT
-#define CACHE_READ_MISS
-#define CACHE_WRITE_HIT
-#define CACHE_WRITE_MISS
-#define CACHE_WRITE_CANCELLATION(cd)
-#define WRITE_DESTAGED(cd, bytes)
-#endif
-
-#endif /* _KERNEL */
-
-/* defines for sh_alloc */
-
-#define CD_ALLOC_IN_PROGRESS 0x0001
-#define CD_ALLOCATED 0x0002
-#define CD_CLOSE_IN_PROGRESS 0x0010
-
-/* defines for sh_flag */
-
-#define CD_ATTACHED 0x0001
-
-#ifdef _KERNEL
-
-typedef void (*sdbc_ea_fn_t) (blind_t, nsc_off_t, nsc_size_t, int);
-
-#define _SD_DISCONNECT_CALLBACK(hndl) \
- if ((hndl)->bh_disconnect_cb) { \
- SDTRACE(SDF_DISCONNECT, (hndl)->bh_cd, (hndl)->bh_fba_len, \
- (hndl)->bh_fba_pos, (hndl)->bh_flag, 0); \
- ((*((hndl)->bh_disconnect_cb))(hndl)); \
- }
-#define _SD_READ_CALLBACK(hndl) \
- if ((hndl)->bh_read_cb) \
- ((*((hndl)->bh_read_cb))(hndl)); \
- else cmn_err(CE_WARN, \
- "!sdbc(_SD_READ_CALLBACK) not registered. io lost");
-#define _SD_WRITE_CALLBACK(hndl) \
- if ((hndl)->bh_write_cb) \
- ((*((hndl)->bh_write_cb))(hndl)); \
- else cmn_err(CE_WARN, \
- "!sdbc(_SD_WRITE_CALLBACK) not registered. io lost");
-
-#endif /* _KERNEL */
-
-
-#if defined(_SD_LRU_OPTIMIZE)
-/*
- * Do not requeue if we fall into the tail 25% of the lru
- */
-#define LRU_REQ_LIMIT(q) (q->sq_inq >> 2)
-
-#define _sd_lru_reinsert(q, ent) \
- (((q->sq_seq - ent->cc_seq) > LRU_REQ_LIMIT(q)) ?\
- 1 : ((q->sq_noreq_stat)++, 0))
-#else
-#define _sd_lru_reinsert(ent) 1
-#endif
-
-#if defined(_KERNEL)
-#define SD_WR_NUMIO 100
-#define SD_DCON_THRESH 0x10000 /* Disconnect if io len greater than 64 */
-
-/*
- * These defines are the hardwired values after sd_config_param was
- * zapped. Ought to remove the use of these entirely ....
- */
-
-#define _SD_CD_WRITER(cd) ((_sd_cache_files[(cd)].cd_info->sh_numdirty>\
- SD_WR_NUMIO) ? \
- cd_writer(cd) : 0)
-#define _SD_FORCE_DISCONNECT(len) (SD_DCON_THRESH < FBA_SIZE(len))
-
-/* -------------------------------- END sd_config_param defines ---------- */
-
-#define _SD_CD_WBLK_USED(cd) (_sd_cache_stats->st_shared[(cd)].sh_numio +\
- _sd_cache_stats->st_shared[(cd)].sh_numdirty)
-
-#define _SD_CD_ALL_WRITES(cd) (_sd_cache_stats->st_shared[(cd)].sh_numio +\
- _sd_cache_stats->st_shared[(cd)].sh_numdirty+\
- _sd_cache_stats->st_shared[(cd)].sh_numfail)
-
-
-
-/*
- * ncall usage
- */
-#define SD_ENABLE (NCALL_SDBC + 0)
-#define SD_DISABLE (NCALL_SDBC + 1)
-#define SD_DUAL_WRITE (NCALL_SDBC + 2)
-#define SD_DUAL_READ (NCALL_SDBC + 3)
-#define SD_SET_CD (NCALL_SDBC + 4)
-#define SD_GETSIZE (NCALL_SDBC + 5)
-#define SD_DUAL_OPEN (NCALL_SDBC + 6)
-#define SD_REMOTE_FLUSH (NCALL_SDBC + 7)
-#define SD_SGREMOTE_FLUSH (NCALL_SDBC + 8)
-#define SD_DISK_IO (NCALL_SDBC + 9)
-#define SD_GET_BMAP (NCALL_SDBC + 10)
-#define SD_CD_DISCARD (NCALL_SDBC + 11)
-#define SD_PING (NCALL_SDBC + 12)
-#define SD_DC_MAIN_LOOP (NCALL_SDBC + 13)
-#define SD_DATA (NCALL_SDBC + 14)
-#define SD_BDATA (NCALL_SDBC + 15)
-#define SD_UPDATE (NCALL_SDBC + 16)
-#define SD_GET_SYSID (NCALL_SDBC + 17)
-
-#ifdef lint
-#include <sys/nsctl/nsctl.h>
-#define LINTUSED(x) (void)(x)++
-#else
-#define LINTUSED(x)
-#endif
-
-
-extern int BLK_FBAS;
-extern _sd_bitmap_t BLK_FBA_BITS;
-extern _sd_bitmap_t _fba_bits[];
-extern _sd_cctl_t *_sd_cctl[];
-extern _sd_cd_info_t *_sd_cache_files;
-extern _sd_hash_table_t *_sd_htable;
-extern _sd_map_info_t _sd_lookup_map[];
-extern _sd_net_t _sd_net_config;
-extern _sd_queue_t _sd_lru_q;
-extern _sd_stats_t *_sd_cache_stats;
-extern char _sd_contig_bmap[];
-extern int CACHE_BLOCK_SIZE;
-extern int CBLOCKS;
-extern int _sd_cctl_groupsz;
-extern int sdbc_static_cache;
-extern kmutex_t _sd_cache_lock;
-extern nsc_def_t _sd_sdbc_def[];
-extern nsc_io_t *sdbc_io;
-extern nsc_mem_t *sdbc_iobuf_mem, *sdbc_hash_mem;
-extern uint_t _sd_node_hint;
-extern int _sd_minidsp;
-extern krwlock_t sdbc_queue_lock;
-extern safestore_ops_t *sdbc_safestore;
-extern ss_common_config_t safestore_config;
-extern ss_voldata_t *_sdbc_gl_file_info;
-
-extern int _sdbc_cache_configure(int cblocks, spcs_s_info_t kstatus);
-extern void _sdbc_cache_deconfigure(void);
-extern void _sd_requeue(_sd_cctl_t *centry);
-extern void _sd_requeue_head(_sd_cctl_t *centry);
-extern int _sd_open(char *filename, int flag);
-extern int _sd_open_cd(char *filename, const int cd, const int flag);
-extern int _sd_close(int cd);
-extern int _sdbc_remote_store_pinned(int cd);
-extern int _sdbc_io_attach_cd(blind_t xcd);
-extern int _sdbc_io_detach_cd(blind_t xcd);
-extern int _sd_get_pinned(blind_t cd);
-extern void _sd_cc_copy(_sd_cctl_t *cc_real, _sd_cctl_t *cc_shadow);
-extern _sd_buf_handle_t *_sd_allocate_buf(int cd, nsc_off_t fba_pos,
- nsc_size_t fba_len, int flag, int *sts);
-extern void _sd_cc_wait(int cd, nsc_off_t cblk, _sd_cctl_t *centry, int flag);
-extern int _sd_alloc_buf(blind_t xcd, nsc_off_t fba_pos, nsc_size_t fba_len,
- int flag, _sd_buf_handle_t **handle_p);
-extern int _sd_free_buf(_sd_buf_handle_t *handle);
-extern _sd_cctl_t *_sd_centry_alloc(int, int, int *, int, int);
-extern int _sd_centry_setup_dm(_sd_cctl_t *, int, int);
-extern void _sdbc_dealloc_deconfigure_dm(void);
-extern int _sdbc_dealloc_configure_dm(void);
-extern _sd_cctl_t *_sd_shadow_centry(_sd_cctl_t *, _sd_cctl_t *, int, int, int);
-extern void _sd_centry_release(_sd_cctl_t *centry);
-extern int _sd_alloc_write(_sd_cctl_t *centry, int *stall);
-extern int _sd_read(_sd_buf_handle_t *handle, nsc_off_t fba_pos,
- nsc_size_t fba_len, int flag);
-extern void _sd_read_complete(_sd_buf_handle_t *handle, nsc_off_t fba_pos,
- nsc_size_t fba_len, int error);
-extern int _sd_write(_sd_buf_handle_t *handle, nsc_off_t fba_pos,
- nsc_size_t fba_len, int flag);
-extern int _sd_zero(_sd_buf_handle_t *handle, nsc_off_t fba_pos,
- nsc_size_t fba_len, int flag);
-extern int _sd_copy(_sd_buf_handle_t *handle1, _sd_buf_handle_t *handle2,
- nsc_off_t fba_pos1, nsc_off_t fba_pos2, nsc_size_t fba_len);
-extern void _sd_enqueue_dirty(int cd, _sd_cctl_t *chain, _sd_cctl_t *cc_last,
- int numq);
-extern void _sd_enqueue_dirty_chain(int cd, _sd_cctl_t *chain_first,
- _sd_cctl_t *chain_last, int numq);
-extern int _sd_get_stats(_sd_stats_t *uptr, int convert_32);
-extern int _sd_set_hint(int cd, uint_t hint);
-extern int _sd_clear_hint(int cd, uint_t hint);
-extern int _sd_get_cd_hint(int cd, uint_t *hint);
-extern int _sd_set_node_hint(uint_t hint);
-extern int _sd_clear_node_hint(uint_t hint);
-extern int _sd_get_node_hint(uint_t *hint);
-extern int _sd_get_partsize(blind_t cd, nsc_size_t *ptr);
-extern int _sd_get_maxfbas(blind_t cd, int flag, nsc_size_t *ptr);
-extern int _sd_discard_pinned(blind_t cd, nsc_off_t fba_pos,
- nsc_size_t fba_len);
-extern void _sdbc_handles_unload(void);
-extern int _sdbc_handles_load(void);
-extern int _sdbc_handles_configure();
-extern void _sdbc_handles_deconfigure(void);
-extern _sd_buf_handle_t *_sd_alloc_handle(sdbc_callback_fn_t d_cb,
- sdbc_callback_fn_t r_cb, sdbc_callback_fn_t w_cb);
-extern int _sd_free_handle(_sd_buf_handle_t *handle);
-extern void _sd_init_contig_bmap(void);
-extern void _sd_init_lookup_map(void);
-extern int sd_get_file_info_size(void *uaddrp);
-extern int sd_get_file_info_data(char *uaddrp);
-extern int sd_get_glmul_sizes(int *uaddrp);
-extern int sd_get_glmul_info(char *uaddrp);
-extern _sd_cctl_t *sdbc_centry_alloc(int, nsc_off_t, nsc_size_t, int *,
- sdbc_allocbuf_t *, int);
-extern _sd_cctl_t *sdbc_centry_alloc_blks(int, nsc_off_t, nsc_size_t, int);
-extern int _sdbc_ft_hold_io;
-extern kcondvar_t _sdbc_ft_hold_io_cv;
-extern kmutex_t _sdbc_ft_hold_io_lk;
-
-#ifdef DEBUG
-/* for testing only */
-extern int _sdbc_flush_flag; /* inhibit flush for testing */
-extern int _sdbc_clear_ioerr(int);
-extern int _sdbc_inject_ioerr(int, int, int);
-extern void _sdbc_ioj_set_dev(int, dev_t);
-extern void _sdbc_ioj_load();
-extern void _sdbc_ioj_unload();
-#endif
-
-#endif /* _KERNEL */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SD_BCACHE_H */
diff --git a/usr/src/uts/common/avs/ns/sdbc/sd_bio.c b/usr/src/uts/common/avs/ns/sdbc/sd_bio.c
deleted file mode 100644
index a82a19f6f7..0000000000
--- a/usr/src/uts/common/avs/ns/sdbc/sd_bio.c
+++ /dev/null
@@ -1,1305 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-/*
- * Copyright (c) 2017 by Delphix. All rights reserved.
- */
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/ksynch.h>
-#include <sys/kmem.h>
-#include <sys/stat.h>
-#include <sys/buf.h>
-#include <sys/open.h>
-#include <sys/conf.h>
-#include <sys/file.h>
-#include <sys/cmn_err.h>
-#include <sys/errno.h>
-#include <sys/ddi.h>
-
-#include <sys/nsc_thread.h>
-#include <sys/nsctl/nsctl.h>
-
-#include <sys/sdt.h> /* dtrace is S10 or later */
-
-#include <vm/seg_kmem.h>
-#include "sd_bcache.h"
-#include "sd_trace.h"
-#include "sd_io.h"
-#include "sd_iob.h"
-#include "sd_misc.h"
-#if defined(_SD_DEBUG) /* simulate disk errors */
-#include "sd_tdaemon.h"
-#endif
-
-#ifndef DS_DDICT
-extern uintptr_t kobj_getsymvalue(char *, int); /* DDI violation */
-#endif
-
-#define DO_PAGE_LIST sdbc_do_page /* enable pagelist code */
-
-int sdbc_do_page = 0;
-
-#define SGIO_MAX 254
-
-static kmutex_t sdbc_bio_mutex;
-static int sdbc_bio_count;
-
-static unsigned long page_size, page_offset_mask;
-
-#ifdef _SD_BIO_STATS
-static __start_io_count = 0;
-#endif /* _SD_BIO_STATS */
-
-/*
- * Forward declare all statics that are used before defined to enforce
- * parameter checking. Also forward-declare all functions that have 64-bit
- * argument types to enforce correct parameter checking.
- *
- * Some (if not all) of these could be removed if the code were reordered
- */
-
-static int _sd_sync_ea(struct buf *, iob_hook_t *);
-static int _sd_async_ea(struct buf *, iob_hook_t *);
-static void _sd_pack_pages(struct buf *bp, struct buf *list, sd_addr_t *addr,
- nsc_off_t offset, nsc_size_t size);
-static void _sd_pack_pages_nopageio(struct buf *bp, struct buf *list,
- sd_addr_t *addr, nsc_off_t offset, nsc_size_t size);
-static void _sd_setup_iob(struct buf *bp, dev_t dev, nsc_off_t pos, int flag);
-
-#ifdef DEBUG
-static int _sdbc_ioj_lookup(dev_t);
-static void _sdbc_ioj_clear_err(int);
-#endif
-
-static int SD_WRITES_TOT = 0;
-static int SD_WRITES_LEN[100];
-
-_sd_buf_list_t _sd_buflist;
-
-/*
- * _sd_add_vm_to_bp_plist - add the page corresponding to the
- * virtual address "v" (kernel virtaddr) to the pagelist linked
- * to buffer "bp".
- *
- * The virtual address "v" is "known" to be allocated by segkmem
- * and we can look up the page by using the segkmem vnode kvp.
- * This violates the ddi/ddk but is workable for now anyway.
- *
- *
- */
-static void
-_sd_add_vm_to_bp_plist(struct buf *bp, unsigned char *v)
-{
- page_t *pp;
- page_t *one_pg = NULL;
-
- pp = page_find(&kvp, (u_offset_t)((uintptr_t)v & ~page_offset_mask));
- if (!pp) {
- cmn_err(CE_PANIC,
- "_sd_add_vm_to_bp_plist: couldn't find page for 0x%p",
- (void *)v);
- }
-
- page_add(&one_pg, pp);
- page_list_concat(&(bp->b_pages), &one_pg);
-
-}
-
-#ifdef _SD_BIO_STATS
-static int
-_sd_count_pages(page_t *pp)
-{
- int cnt = 0;
- page_t *pp1;
- if (pp == NULL)
- return (cnt);
-
- for (cnt = 1, pp1 = pp->p_next; pp != pp1; cnt++, pp1 = pp1->p_next)
- ;
-
- return (cnt);
-}
-#endif /* _SD_BIO_STATS */
-
-
-/*
- * _sdbc_iobuf_load - load time initialization of io bufs structures.
- *
- *
- * RETURNS:
- * 0 - success.
- * -1 - failure.
- *
- * USAGE:
- * This routine initializes load time buf structures.
- * Should be called when the cache is loaded.
- */
-
-int
-_sdbc_iobuf_load(void)
-{
- mutex_init(&sdbc_bio_mutex, NULL, MUTEX_DRIVER, NULL);
-
- /*
- * HACK add a ref to kvp, to prevent VN_RELE on it from panicing
- * the system
- */
- VN_HOLD(&kvp);
-
- return (0);
-}
-
-/*
- * _sdbc_iobuf_unload - unload time cleanup of io buf structures.
- *
- *
- * USAGE:
- * This routine removes load time buf structures.
- * Should be called when the cache is unloaded.
- */
-void
-_sdbc_iobuf_unload(void)
-{
- mutex_enter(&kvp.v_lock);
- ASSERT(kvp.v_count == 1);
- VN_RELE_LOCKED(&kvp);
- mutex_exit(&kvp.v_lock);
-
- mutex_destroy(&sdbc_bio_mutex);
- bzero(&_sd_buflist, sizeof (_sd_buf_list_t));
-}
-
-/*
- * _sdbc_iobuf_configure - configure a list of io bufs for later use.
- *
- * ARGUMENTS:
- * num_bufs - number of buffers. (from the configuration file)
- *
- * RETURNS:
- * 0 - success.
- * <0 - failure.
- *
- * USAGE:
- * This routine configures the buf structures for io.
- * Should be called when the cache is configured.
- */
-
-int
-_sdbc_iobuf_configure(int num)
-{
- int i;
- _sd_buf_list_t *buflist;
- iob_hook_t *hook;
- char symbol_name[32];
-
- if (!num || (num > _SD_DEFAULT_IOBUFS))
- num = _SD_DEFAULT_IOBUFS;
-
- if ((_sd_buflist.hooks = (iob_hook_t *)nsc_kmem_zalloc(
- num * sizeof (iob_hook_t), KM_SLEEP, sdbc_iobuf_mem)) == NULL) {
- return (-1);
- }
-
- buflist = &_sd_buflist;
- buflist->bl_init_count = num;
- buflist->bl_hooks_avail = num;
- buflist->bl_hook_lowmark = num;
- hook = buflist->hooks;
- buflist->hook_head = hook;
- for (i = 0; i < num; i++, hook++) {
- cv_init(&hook->wait, NULL, CV_DRIVER, NULL);
- (void) sprintf(symbol_name, "sd_iob_dcb%d", i);
- hook->iob_drv_iodone = (dcb_t)kobj_getsymvalue(symbol_name, 0);
- if (!hook->iob_drv_iodone) {
- return (-2);
- }
- hook->next_hook = hook+1;
- }
- (hook-1)->next_hook = NULL;
-
- for (i = 0; i < MAX_HOOK_LOCKS; i++)
- mutex_init(&_sd_buflist.hook_locks[i], NULL, MUTEX_DRIVER,
- NULL);
-
- cv_init(&_sd_buflist.hook_wait, NULL, CV_DRIVER, NULL);
- _sd_buflist.hook_waiters = 0;
-
- sdbc_bio_count = 0;
- SD_WRITES_TOT = 0;
- bzero(SD_WRITES_LEN, sizeof (SD_WRITES_LEN));
-
- /* pagelist i/o pages must be done in cache_init */
-
- page_size = ptob(1);
- page_offset_mask = page_size - 1;
-
- return (0);
-}
-
-/*
- * _sdbc_iobuf_deconfigure - release all memory allocated for buf list
- *
- * ARGUMENTS:
- * None.
- *
- * RETURNS:
- * 0
- */
-void
-_sdbc_iobuf_deconfigure(void)
-{
- ushort_t i;
-
- if (_sd_buflist.hooks) {
- for (i = 0; i < _sd_buflist.bl_init_count; i ++) {
- cv_destroy(&_sd_buflist.hooks[i].wait);
- }
- cv_destroy(&_sd_buflist.hook_wait);
- nsc_kmem_free(_sd_buflist.hooks,
- _sd_buflist.bl_init_count * sizeof (iob_hook_t));
- for (i = 0; i < MAX_HOOK_LOCKS; i ++) {
- mutex_destroy(&_sd_buflist.hook_locks[i]);
- }
- }
-
- _sd_buflist.hooks = NULL;
-
-#ifdef DEBUG
- {
- void _sdbc_ioj_clear_err(int);
- _sdbc_ioj_clear_err(-1); /* clear any injected i/o errors */
- _sdbc_ioj_set_dev(-1, 0); /* clear dev entries */
- }
-#endif
-
-}
-
-/*
- * _sd_pending_iobuf()
- *
- * Return the number of I/O bufs outstanding
- */
-int
-_sd_pending_iobuf(void)
-{
- return (sdbc_bio_count);
-}
-
-/*
- * _sd_get_iobuf - allocate a buf.
- *
- * ARGUMENTS:
- * None.
- *
- * RETURNS:
- * NULL - failure.
- * buf ptr otherwise.
- *
- * ASSUMPTIONS - process could block if we run out.
- *
- */
-/*ARGSUSED*/
-static struct buf *
-_sd_get_iobuf(int num_bdl)
-{
- struct buf *bp;
-
- /* Get a buffer, ready for page list i/o */
-
- if (DO_PAGE_LIST)
- bp = pageio_setup(NULL, 0, &kvp, 0);
- else
- bp = getrbuf(KM_SLEEP);
-
- if (bp == NULL)
- return (NULL);
- mutex_enter(&sdbc_bio_mutex);
- sdbc_bio_count++;
- mutex_exit(&sdbc_bio_mutex);
- return (bp);
-}
-
-/*
- * _sd_put_iobuf - put a buf back in the freelist.
- *
- * ARGUMENTS:
- * bp - buf pointer.
- *
- * RETURNS:
- * 0
- *
- */
-static void
-_sd_put_iobuf(struct buf *bp)
-{
- mutex_enter(&sdbc_bio_mutex);
- sdbc_bio_count--;
- mutex_exit(&sdbc_bio_mutex);
- if (DO_PAGE_LIST)
- pageio_done(bp);
- else
- freerbuf(bp);
-}
-
-
-/* use for ORing only */
-#define B_KERNBUF 0
-
-static void
-_sd_setup_iob(struct buf *bp, dev_t dev, nsc_off_t pos, int flag)
-{
- bp->b_pages = NULL;
- bp->b_un.b_addr = 0;
-
- flag &= (B_READ | B_WRITE);
-
- /*
- * if pagelist i/o, _sd_get_iobuf()/pageio_setup() has already
- * set b_flags to
- * B_KERNBUF | B_PAGEIO | B_NOCACHE | B_BUSY (sol 6,7,8)
- * or
- * B_PAGEIO | B_NOCACHE | B_BUSY (sol 9)
- */
-
- bp->b_flags |= B_KERNBUF | B_BUSY | flag;
-
- bp->b_error = 0;
-
- bp->b_forw = NULL;
- bp->b_back = NULL;
-
- bp->b_lblkno = (diskaddr_t)pos;
- bp->b_bufsize = 0;
- bp->b_resid = 0;
- bp->b_proc = NULL;
- bp->b_edev = dev;
-}
-
-
-/*
- * _sd_get_hook - get an iob hook from the free list.
- *
- * ARGUMENTS:
- * none
- *
- * RETURNS:
- * the newly allocated iob_hook.
- *
- */
-static iob_hook_t *
-_sd_get_hook(void)
-{
-
- iob_hook_t *ret;
-
- mutex_enter(&sdbc_bio_mutex);
-
-retry:
- ret = _sd_buflist.hook_head;
- if (ret)
- _sd_buflist.hook_head = ret->next_hook;
- else {
- ++_sd_buflist.hook_waiters;
- if (_sd_buflist.max_hook_waiters < _sd_buflist.hook_waiters)
- _sd_buflist.max_hook_waiters = _sd_buflist.hook_waiters;
- cv_wait(&_sd_buflist.hook_wait, &sdbc_bio_mutex);
- --_sd_buflist.hook_waiters;
- goto retry;
- }
-
- if (_sd_buflist.bl_hook_lowmark > --_sd_buflist.bl_hooks_avail)
- _sd_buflist.bl_hook_lowmark = _sd_buflist.bl_hooks_avail;
-
- mutex_exit(&sdbc_bio_mutex);
- ret->skipped = 0;
-
- ret->count = 0;
-
-#ifdef _SD_BIO_STATS
- ret->PAGE_IO = 0;
- ret->NORM_IO = 0;
- ret->NORM_IO_SIZE = 0;
- ret->SKIP_IO = 0;
- ret->PAGE_COMBINED = 0;
-#endif /* _SD_BIO_STATS */
-
- return (ret);
-}
-
-/*
- * _sd_put_hook - put an iob hook back on the free list.
- *
- * ARGUMENTS:
- * hook - an iob_hook to be returned to the freelist.
- *
- *
- */
-static void
-_sd_put_hook(iob_hook_t *hook)
-{
-
- mutex_enter(&sdbc_bio_mutex);
-
- if (_sd_buflist.hook_waiters) {
- cv_signal(&_sd_buflist.hook_wait);
- }
- hook->next_hook = _sd_buflist.hook_head;
- _sd_buflist.hook_head = hook;
-
- ++_sd_buflist.bl_hooks_avail;
-
- mutex_exit(&sdbc_bio_mutex);
-}
-
-/*
- * _sd_extend_iob - the i/o block we are handling needs a new struct buf to
- * describe the next hunk of i/o. Get a new struct buf initialize it based
- * on the state in the struct buf we are passed as an arg.
- * ARGUMENTS:
- * head_bp - a buffer header in the current i/o block we are handling.
- * (generally the initial header but in fact could be any
- * of the ones [if any] that were chained to the initial
- * one).
- */
-static struct buf *
-_sd_extend_iob(struct buf *head_bp)
-{
- struct buf *bp;
- iob_hook_t *hook = (iob_hook_t *)head_bp->b_private;
-
-
- if (!(bp = _sd_get_iobuf(0)))
- return (0);
-
- bp->b_pages = NULL;
- bp->b_un.b_addr = 0;
-
- bp->b_flags |= (head_bp->b_flags & (B_READ | B_WRITE));
-
- if (!DO_PAGE_LIST)
- bp->b_flags |= B_KERNBUF | B_BUSY;
-
- bp->b_error = 0;
-
- /*
- * b_forw/b_back will form a doubly linked list of all the buffers
- * associated with this block of i/o.
- * hook->tail points to the last buffer in the chain.
- */
- bp->b_forw = NULL;
- bp->b_back = hook->tail;
- hook->tail->b_forw = bp;
- hook->tail = bp;
- hook->count++;
-
- ASSERT(BLK_FBA_OFF(hook->size) == 0);
-
- bp->b_lblkno = (diskaddr_t)hook->start_fba +
- (diskaddr_t)FBA_NUM(hook->size);
-
- bp->b_bufsize = 0;
- bp->b_resid = 0;
- bp->b_proc = NULL;
- bp->b_edev = head_bp->b_edev;
-
- bp->b_iodone = NULL; /* for now */
- bp->b_private = hook;
-
- return (bp);
-}
-
-/*
- * sd_alloc_iob - start processing a block of i/o. This allocates an initial
- * buffer header for describing the i/o and a iob_hook for collecting
- * information about all the i/o requests added to this buffer.
- *
- * ARGUMENTS:
- * dev - the device all the i/o is destined for.
- * fba_pos - the initial disk block to read.
- * blks - ignored
- * flag - signal whether this is a read or write request.
- *
- * RETURNS:
- * pointer to free struct buf which will be used to describe i/o request.
- */
-/* ARGSUSED */
-struct buf *
-sd_alloc_iob(dev_t dev, nsc_off_t fba_pos, int blks, int flag)
-{
- struct buf *bp;
- iob_hook_t *hook;
-
- if (!(bp = _sd_get_iobuf(0)))
- return (0);
-
- _sd_setup_iob(bp, dev, fba_pos, flag);
-
- bp->b_iodone = NULL; /* for now */
- hook = _sd_get_hook();
- if (!hook) {
- /* can't see how this could happen */
- _sd_put_iobuf(bp);
- return (0);
- }
-
- /*
- * pick an arbitrary lock
- */
- hook->lockp = &_sd_buflist.hook_locks[((long)hook >> 9) &
- (MAX_HOOK_LOCKS - 1)];
- hook->start_fba = fba_pos;
- hook->last_fba = fba_pos;
- hook->size = 0;
- hook->tail = bp;
- hook->chain = bp;
- hook->count = 1;
- hook->error = 0;
- bp->b_private = hook;
-
- return (bp);
-}
-
-/*
- * _sd_pack_pages - produce i/o requests that will perform the type of i/o
- * described by bp (READ/WRITE). It attempt to tack the i/o onto the
- * buf pointer to by list to minimize the number of bufs required.
- *
- * ARGUMENTS:
- * bp - is the i/o description i.e. head
- * list - is where to start adding this i/o request (null if we should extend)
- * addr - address describing where the data is.
- * offset - offset from addr where data begins
- * size - size of the i/o request.
- */
-static void
-_sd_pack_pages(struct buf *bp, struct buf *list, sd_addr_t *addr,
- nsc_off_t offset, nsc_size_t size)
-{
- uintptr_t start_addr, end_addr;
- int page_end_aligned;
-#ifdef _SD_BIO_STATS
- iob_hook_t *hook = (iob_hook_t *)bp->b_private;
- struct buf *orig_list = list;
-#endif /* _SD_BIO_STATS */
-
- start_addr = (uintptr_t)addr->sa_virt + offset;
- end_addr = start_addr + size;
-
- page_end_aligned = !(end_addr & page_offset_mask);
-
- if (!list && !(list = _sd_extend_iob(bp))) {
- /*
- * we're hosed since we have no error return...
- * though we could ignore stuff from here on out
- * and return ENOMEM when we get to sd_start_io.
- * This will do for now.
- */
- cmn_err(CE_PANIC, "_sd_pack_pages: couldn't extend iob");
- }
-
- /*
- * We only want to do pagelist i/o if we end on a page boundary.
- * If we don't end on a page boundary we won't combine with the
- * next request and so we may as well do it as normal as it
- * will only use one buffer.
- */
-
- if (DO_PAGE_LIST && page_end_aligned) {
- if (start_addr & page_offset_mask) {
- /*
- * handle the partial page
- */
- if (list->b_bufsize) {
- if (!(list = _sd_extend_iob(bp))) {
- /*
- * we're hosed since we have no error
- * return though we could ignore stuff
- * from here on out and return ENOMEM
- * when we get to sd_start_io.
- * This will do for now.
- */
- cmn_err(CE_PANIC,
- "_sd_pack_pages: couldn't extend iob");
- }
- }
-#ifdef _SD_BIO_STATS
- hook->PAGE_IO++;
-#endif /* _SD_BIO_STATS */
- _sd_add_vm_to_bp_plist(list,
- (unsigned char *) start_addr);
- list->b_bufsize = page_size -
- (start_addr & page_offset_mask);
- list->b_un.b_addr = (caddr_t)
- (start_addr & page_offset_mask);
- size -= list->b_bufsize;
- start_addr += list->b_bufsize;
- }
- /*
- * Now fill with all the full pages remaining.
- */
- for (; size > 0; size -= page_size) {
-#ifdef _SD_BIO_STATS
- hook->PAGE_IO++;
-#endif /* _SD_BIO_STATS */
-
- _sd_add_vm_to_bp_plist(list,
- (unsigned char *) start_addr);
- start_addr += page_size;
- list->b_bufsize += page_size;
-#ifdef _SD_BIO_STATS
- if (list == orig_list)
- hook->PAGE_COMBINED++;
-#endif /* _SD_BIO_STATS */
- }
- if (size)
- cmn_err(CE_PANIC, "_sd_pack_pages: bad size: %"
- NSC_SZFMT, size);
- } else {
- /*
- * Wasn't worth it as pagelist i/o, do as normal
- */
- if (list->b_bufsize && !(list = _sd_extend_iob(bp))) {
- /*
- * we're hosed since we have no error return...
- * though we could ignore stuff from here on out
- * and return ENOMEM when we get to sd_start_io.
- * This will do for now.
- */
- cmn_err(CE_PANIC,
- "_sd_pack_pages: couldn't extend iob");
- }
-
- /* kernel virtual */
- list->b_flags &= ~(B_PHYS | B_PAGEIO);
- list->b_un.b_addr = (caddr_t)start_addr;
-#ifdef _SD_BIO_STATS
- hook->NORM_IO++;
- hook->NORM_IO_SIZE += size;
-#endif /* _SD_BIO_STATS */
- list->b_bufsize = (size_t)size;
- }
-
-}
-
-/*
- * perform same function as _sd_pack_pages() when not doing pageio
- */
-static void
-_sd_pack_pages_nopageio(struct buf *bp, struct buf *list, sd_addr_t *addr,
- nsc_off_t offset, nsc_size_t size)
-{
- uintptr_t start_addr;
-#ifdef _SD_BIO_STATS
- iob_hook_t *hook = (iob_hook_t *)bp->b_private;
- struct buf *orig_list = list;
-#endif /* _SD_BIO_STATS */
-
- start_addr = (uintptr_t)addr->sa_virt + offset;
-
- if (!list && !(list = _sd_extend_iob(bp))) {
- /*
- * we're hosed since we have no error return...
- * though we could ignore stuff from here on out
- * and return ENOMEM when we get to sd_start_io.
- * This will do for now.
- */
- cmn_err(CE_PANIC, "_sd_pack_pages_nopageio: couldn't "
- "extend iob");
- }
-
- if (list->b_bufsize &&
- (start_addr == (uintptr_t)(list->b_un.b_addr + list->b_bufsize))) {
- /* contiguous */
- list->b_bufsize += (size_t)size;
- } else {
- /*
- * not contiguous mem (extend) or first buffer (bufsize == 0).
- */
- if (list->b_bufsize && !(list = _sd_extend_iob(bp))) {
- /*
- * we're hosed since we have no error return...
- * though we could ignore stuff from here on out
- * and return ENOMEM when we get to sd_start_io.
- * This will do for now.
- */
- cmn_err(CE_PANIC, "_sd_pack_pages_nopageio: couldn't "
- "extend iob");
- }
- list->b_un.b_addr = (caddr_t)start_addr;
- list->b_bufsize = (size_t)size;
- }
-
-#ifdef _SD_BIO_STATS
- hook->NORM_IO++;
- hook->NORM_IO_SIZE += size;
-#endif /* _SD_BIO_STATS */
-}
-
-/*
- * sd_add_fba - add an i/o request to the block of i/o described by bp.
- * We try and combine this request with the previous request. In
- * Addition we try and do the i/o as PAGELIST_IO if it satisfies
- * the restrictions for it. If the i/o request can't be combined
- * we extend the i/o description with a new buffer header and add
- * it to the chain headed by bp.
- *
- * ARGUMENTS:
- * bp - the struct buf describing the block i/o we are collecting.
- * addr - description of the address where the data will read/written to.
- * A NULL indicates that this i/o request doesn't need to actually
- * happen. Used to mark reads when the fba is already in cache and
- * dirty.
- *
- * fba_pos - offset from address in addr where the i/o is to start.
- *
- * fba_len - number of consecutive fbas to transfer.
- *
- * NOTE: It is assumed that the memory is physically contiguous but may span
- * multiple pages (should a cache block be larger than a page).
- *
- */
-void
-sd_add_fba(struct buf *bp, sd_addr_t *addr, nsc_off_t fba_pos,
- nsc_size_t fba_len)
-{
- nsc_off_t offset;
- nsc_size_t size;
- iob_hook_t *hook = (iob_hook_t *)bp->b_private;
-
- size = FBA_SIZE(fba_len);
- offset = FBA_SIZE(fba_pos);
-
- if (addr) {
- /*
- * See if this can be combined with previous request(s)
- */
- if (!bp->b_bufsize) {
- if (DO_PAGE_LIST)
- _sd_pack_pages(bp, bp, addr, offset, size);
- else
- _sd_pack_pages_nopageio(bp, bp, addr, offset,
- size);
- } else {
- if (DO_PAGE_LIST) {
- if (hook->tail->b_flags & B_PAGEIO) {
- /*
- * Last buffer was a pagelist. Unless a
- * skip was detected the last request
- * ended on a page boundary. If this
- * one starts on one we combine the
- * best we can.
- */
- if (hook->skipped)
- _sd_pack_pages(bp, NULL, addr,
- offset, size);
- else
- _sd_pack_pages(bp, hook->tail,
- addr, offset, size);
- } else {
- /*
- * Last buffer was vanilla i/o or worse
- * (sd_add_mem)
- */
- _sd_pack_pages(bp, NULL, addr, offset,
- size);
- }
- } else {
- if (hook->skipped)
- _sd_pack_pages_nopageio(bp, NULL,
- addr, offset, size);
- else
- _sd_pack_pages_nopageio(bp,
- hook->tail, addr, offset, size);
- }
- }
- hook->skipped = 0;
- } else {
- /* Must be a read of dirty block we want to discard */
-
- ASSERT(bp->b_flags & B_READ);
-#ifdef _SD_BIO_STATS
- hook->SKIP_IO++;
-#endif /* _SD_BIO_STATS */
- hook->skipped = 1;
- if (!bp->b_bufsize)
- bp->b_lblkno += fba_len;
- }
- hook->size += size;
-
-}
-
-/*
- * sd_add_mem - add an i/o request to the block of i/o described by bp.
- * The memory target for this i/o may span multiple pages and may
- * not be physically contiguous.
- * also the len might also not be a multiple of an fba.
- *
- * ARGUMENTS:
- * bp - the struct buf describing the block i/o we are collecting.
- *
- * buf - target of this i/o request.
- *
- * len - number of bytes to transfer.
- *
- */
-void
-sd_add_mem(struct buf *bp, char *buf, nsc_size_t len)
-{
- nsc_size_t n;
- uintptr_t start;
- iob_hook_t *hook = (iob_hook_t *)bp->b_private;
-
- start = (uintptr_t)buf & page_offset_mask;
-
- for (; len > 0; buf += n, len -= n, start = 0) {
- n = min((nsc_size_t)len, (nsc_size_t)(page_size - start));
- /*
- * i/o size must be multiple of an FBA since we can't
- * count on lower level drivers to understand b_offset
- */
- if (BLK_FBA_OFF(n) != 0) {
- cmn_err(CE_WARN,
- "!sdbc(sd_add_mem) i/o request not FBA sized (%"
- NSC_SZFMT ")", n);
- }
-
- if (!bp->b_bufsize) {
- /* first request */
- bp->b_flags &= ~(B_PHYS | B_PAGEIO);
- bp->b_un.b_addr = buf;
- bp->b_bufsize = (size_t)n;
- } else {
- struct buf *new_bp;
- if (!(new_bp = _sd_extend_iob(bp))) {
- /* we're hosed */
- cmn_err(CE_PANIC,
- "sd_add_mem: couldn't extend iob");
- }
- new_bp->b_flags &= ~(B_PHYS | B_PAGEIO);
- new_bp->b_un.b_addr = buf;
- new_bp->b_bufsize = (size_t)n;
- }
- hook->size += n;
- }
-}
-
-
-/*
- * sd_start_io - start all the i/o needed to satisfy the i/o request described
- * by bp. If supplied the a non-NULL fn then this is an async request
- * and we will return NSC_PENDING and call fn when all the i/o complete.
- * Otherwise this is a synchronous request and we sleep until all the
- * i/o is complete. If any buffer in the chain gets an error we return
- * the first error we see (once all the i/o is complete).
- *
- * ARGUMENTS:
- * bp - the struct buf describing the block i/o we are collecting.
- *
- * strategy - strategy function to call if known by the user, or NULL.
- *
- * fn - user's callback function. NULL implies synchronous request.
- *
- * arg - an argument passed to user's callback function.
- *
- */
-int
-sd_start_io(struct buf *bp, strategy_fn_t strategy, sdbc_ea_fn_t fn,
- blind_t arg)
-{
- int err;
- iob_hook_t *hook = (iob_hook_t *)bp->b_private;
- struct buf *bp_next;
- int (*ea_fn)(struct buf *, iob_hook_t *);
-#ifdef _SD_BIO_STATS
- static int total_pages, total_pages_combined, total_norm;
- static int total_norm_combined, total_skipped;
- static nsc_size_t total_norm_size;
-
- static int total_bufs;
- static int total_xpages_w, total_ypages_w;
- static int total_xpages_r, total_ypages_r;
- static int max_run_r, max_run_w;
-
-#endif /* _SD_BIO_STATS */
-
- hook->func = fn;
- hook->param = arg;
- if (fn != NULL)
- ea_fn = _sd_async_ea;
- else
- ea_fn = _sd_sync_ea;
-
- hook->iob_hook_iodone = ea_fn;
-
-#ifdef _SD_BIO_STATS
- __start_io_count++;
- total_pages += hook->PAGE_IO;
- total_pages_combined += hook->PAGE_COMBINED;
- total_norm += hook->NORM_IO;
- total_norm_size += hook->NORM_IO_SIZE;
- total_skipped += hook->SKIP_IO;
-#endif /* _SD_BIO_STATS */
-
- for (; bp; bp = bp_next) {
-
- DTRACE_PROBE4(sd_start_io_bufs, struct buf *, bp, long, bp->b_bufsize,
- int, bp->b_flags, iob_hook_t *, hook);
-
- bp_next = bp->b_forw;
- if (!(bp->b_flags & B_READ)) {
- SD_WRITES_TOT++;
- SD_WRITES_LEN[(bp->b_bufsize/32768) %
- (sizeof (SD_WRITES_LEN)/sizeof (int))]++;
- }
- bp->b_iodone = hook->iob_drv_iodone;
- bp->b_bcount = bp->b_bufsize;
- bp->b_forw = NULL;
- bp->b_back = NULL;
- bp->b_private = NULL;
-
-#ifdef _SD_BIO_STATS
- total_bufs ++;
- if (bp->b_flags & B_PAGEIO) {
- int i;
- i = _sd_count_pages(bp->b_pages);
- if (bp->b_flags & B_READ) {
- if (i > max_run_r)
- max_run_r = i;
- total_xpages_r += i;
- total_ypages_r++;
- } else {
- if (i > max_run_w)
- max_run_w = i;
- total_xpages_w += i;
- total_ypages_w++;
- }
- }
-#endif /* _SD_BIO_STATS */
-
-
- /*
- * It's possible for us to be told to read a dirty block
- * where all the i/o can go away (e.g. read one fba, it's
- * in cache and dirty) so we really have nothing to do but
- * say we're done.
- */
- if (bp->b_bcount) {
- if (!strategy) {
- strategy =
- nsc_get_strategy(getmajor(bp->b_edev));
- }
-
- if (!strategy) {
- bp->b_flags |= B_ERROR;
- bp->b_error = ENXIO;
- (*bp->b_iodone)(bp);
- } else
-#ifdef DEBUG
- /* inject i/o error for testing */
- if (bp->b_error = _sdbc_ioj_lookup(bp->b_edev)) {
- bp->b_flags |= B_ERROR;
- (*bp->b_iodone)(bp);
- } else
-#endif
- {
- (*strategy)(bp);
- }
- } else {
- (*bp->b_iodone)(bp);
- }
-
- }
-
-#ifdef _SD_BIO_STATS
- if (__start_io_count == 2000) {
- __start_io_count = 0;
- cmn_err(CE_WARN,
- "!sdbc(sd_start_io) t_bufs %d pages %d "
- "combined %d norm %d norm_size %" NSC_SZFMT " skipped %d",
- total_bufs,
- total_pages, total_pages_combined, total_norm,
- total_norm_size, total_skipped);
-
- total_bufs = 0;
- total_pages = 0;
- total_pages_combined = 0;
- total_norm = 0;
- total_norm_combined = 0;
- total_skipped = 0;
- total_norm_size = 0;
-
- cmn_err(CE_WARN,
- "!sdbc(sd_start_io)(r) max_run %d, total_xp %d total yp %d",
- max_run_r, total_xpages_r, total_ypages_r);
-
- total_xpages_r = 0;
- total_ypages_r = 0;
- max_run_r = 0;
-
- cmn_err(CE_WARN,
- "!sdbc(sd_start_io)(w) max_run %d, total_xp %d total yp %d",
- max_run_w, total_xpages_w, total_ypages_w);
-
- total_xpages_w = 0;
- total_ypages_w = 0;
- max_run_w = 0;
- }
-#endif /* _SD_BIO_STATS */
-
- if (ea_fn == _sd_async_ea) {
- DTRACE_PROBE(sd_start_io_end);
-
- return (NSC_PENDING);
- }
-
- mutex_enter(hook->lockp);
-
- while (hook->count) {
- cv_wait(&hook->wait, hook->lockp);
- }
- mutex_exit(hook->lockp);
-
- err = hook->error ? hook->error : NSC_DONE;
- bp = hook->tail;
- _sd_put_hook(hook);
- _sd_put_iobuf(bp);
-
- return (err);
-}
-
-/*
- * _sd_sync_ea - called when a single i/o operation is complete. If this
- * is the last outstanding i/o we wakeup the sleeper.
- * If this i/o had an error then we store the error result in the
- * iob_hook if this was the first error.
- *
- * ARGUMENTS:
- * bp - the struct buf describing the block i/o that just completed.
- *
- * Comments:
- * This routine is called at interrupt level when the io is done.
- */
-
-static int
-_sd_sync_ea(struct buf *bp, iob_hook_t *hook)
-{
-
- int error;
- int done;
-
- /*
- * We get called for each buf that completes. When they are all done.
- * we wakeup the waiter.
- */
- error = (bp->b_flags & B_ERROR) ? bp->b_error : 0;
-
- mutex_enter(hook->lockp);
-
- if (!hook->error)
- hook->error = error;
-
- done = !(--hook->count);
- if (done) {
- /* remember the last buffer so we can free it later */
- hook->tail = bp;
- cv_signal(&hook->wait);
- }
- mutex_exit(hook->lockp);
-
- /*
- * let sd_start_io free the final buffer so the hook can be returned
- * first.
- */
- if (!done)
- _sd_put_iobuf(bp);
-
- return (0);
-}
-
-/*
- * static int
- * _sd_async_ea - End action for async read/write.
- *
- * ARGUMENTS:
- * bp - io buf pointer.
- *
- * RETURNS:
- * NONE.
- *
- * Comments:
- * This routine is called at interrupt level when the io is done.
- * This is only called when the operation is asynchronous.
- */
-static int
-_sd_async_ea(struct buf *bp, iob_hook_t *hook)
-{
- int done, error;
-
- /*
- * We get called for each buf that completes. When they are all done.
- * we call the requestor's callback function.
- */
- error = (bp->b_flags & B_ERROR) ? bp->b_error : 0;
-
- mutex_enter(hook->lockp);
- done = !(--hook->count);
-
- if (!hook->error)
- hook->error = error;
-
- mutex_exit(hook->lockp);
-
- bp->b_forw = NULL;
- bp->b_back = NULL;
-
- if (done) {
- nsc_off_t fba_pos;
- nsc_size_t fba_len;
- int error;
- sdbc_ea_fn_t fn;
- blind_t arg;
-
- arg = hook->param;
- fn = hook->func;
- error = hook->error;
-#if defined(_SD_DEBUG) /* simulate disk errors */
- if (_test_async_fail == bp->b_edev) error = EIO;
-#endif
-
- /* MAKE SURE b_lblkno, b_count never changes!! */
- fba_pos = hook->start_fba;
- fba_len = FBA_LEN(hook->size);
-
- _sd_put_hook(hook);
- _sd_put_iobuf(bp);
- (*fn)(arg, fba_pos, fba_len, error);
- } else
- _sd_put_iobuf(bp);
-
- return (0);
-}
-
-#ifdef DEBUG
-typedef struct ioerr_inject_s {
- dev_t ioj_dev;
- int ioj_err;
- int ioj_cnt;
-} ioerr_inject_t;
-
-static ioerr_inject_t *ioerr_inject_table = NULL;
-
-void
-_sdbc_ioj_load()
-{
- ioerr_inject_table =
- kmem_zalloc(sdbc_max_devs * sizeof (ioerr_inject_t), KM_SLEEP);
-}
-
-void
-_sdbc_ioj_unload()
-{
- if (ioerr_inject_table != NULL) {
- kmem_free(ioerr_inject_table,
- sdbc_max_devs * sizeof (ioerr_inject_t));
- ioerr_inject_table = NULL;
- }
-}
-
-static int
-_sdbc_ioj_lookup(dev_t dev)
-{
- int cd;
-
- for (cd = 0; cd < sdbc_max_devs; ++cd)
- if (ioerr_inject_table[cd].ioj_dev == dev) {
- if (ioerr_inject_table[cd].ioj_cnt > 0) {
- --ioerr_inject_table[cd].ioj_cnt;
- return (0);
- } else {
- return (ioerr_inject_table[cd].ioj_err);
- }
- }
- return (0);
-}
-
-void
-_sdbc_ioj_set_dev(int cd, dev_t crdev)
-{
- int i;
-
- if (cd == -1) { /* all -- used for clearing table on shutdown */
- for (i = 0; i < sdbc_max_devs; ++i) {
- ioerr_inject_table[i].ioj_dev = crdev;
- }
- } else
- ioerr_inject_table[cd].ioj_dev = crdev; /* assume valid cd */
-}
-
-static
-void
-_sdbc_ioj_set_err(int cd, int err, int count)
-{
- int i;
-
- if (cd == -1) { /* all */
- for (i = 0; i < sdbc_max_devs; ++i) {
- ioerr_inject_table[i].ioj_err = err;
- ioerr_inject_table[i].ioj_cnt = count;
- }
- } else {
- ioerr_inject_table[cd].ioj_err = err;
- ioerr_inject_table[cd].ioj_cnt = count;
- }
-}
-
-static void
-_sdbc_ioj_clear_err(int cd)
-{
- _sdbc_ioj_set_err(cd, 0, 0);
-}
-
-int
-_sdbc_inject_ioerr(int cd, int ioj_err, int count)
-{
- if ((cd < -1) || (cd >= sdbc_max_devs))
- return (EINVAL);
-
- _sdbc_ioj_set_err(cd, ioj_err, count);
-
- return (0);
-}
-
-int
-_sdbc_clear_ioerr(int cd)
-{
- if ((cd < -1) || (cd >= sdbc_max_devs))
- return (EINVAL);
-
- _sdbc_ioj_clear_err(cd);
-
- return (0);
-}
-#endif
diff --git a/usr/src/uts/common/avs/ns/sdbc/sd_bio.h b/usr/src/uts/common/avs/ns/sdbc/sd_bio.h
deleted file mode 100644
index 132bb3152b..0000000000
--- a/usr/src/uts/common/avs/ns/sdbc/sd_bio.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SD_BIO_H
-#define _SD_BIO_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern int _sdbc_iobuf_load(void);
-extern void _sdbc_iobuf_unload(void);
-extern int _sdbc_iobuf_configure(int);
-extern void _sdbc_iobuf_deconfigure(void);
-extern int _sd_pending_iobuf(void);
-extern struct buf *sd_alloc_iob(dev_t, nsc_off_t, int, int);
-extern void sd_add_fba(struct buf *, sd_addr_t *, nsc_off_t, nsc_size_t);
-extern void sd_add_mem(struct buf *, char *, nsc_size_t);
-extern int sd_start_io(struct buf *, strategy_fn_t, sdbc_ea_fn_t, blind_t);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SD_BIO_H */
diff --git a/usr/src/uts/common/avs/ns/sdbc/sd_cache.h b/usr/src/uts/common/avs/ns/sdbc/sd_cache.h
deleted file mode 100644
index 2d45e3fbbc..0000000000
--- a/usr/src/uts/common/avs/ns/sdbc/sd_cache.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SD_CACHE_H
-#define _SD_CACHE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/debug.h>
-#include <sys/nsctl/nsctl.h>
-
-/*
- * Compiler defines
- */
-
-#define _SD_FAULT_RES /* Enable Fault tolerance */
-
-#define _SD_USE_THREADS /* Use own threadset */
-#define _SD_LRU_OPTIMIZE /* Enable LRU queue optimizations */
-#define _SD_HASH_OPTIMIZE /* Enable Hash optimizations */
-
-#if !defined(_SD_NO_GENERIC)
-#define _SD_MULTIUSER /* Block locking (concurrent/dual copy) */
-#endif /* (_SD_NO_GENERIC) */
-
-#if defined(_SD_OPTIM_ALLOC)
-#define _SD_NOCHECKS /* Disable handle allocation checks */
-#define _SD_NOTRACE /* Disable SDTRACE() macro */
-#undef _SD_MULTIUSER /* Disable Block locking */
-#if (_SD_OPTIM_ALLOC+0 > 1)
-#define _SD_NOSTATS /* Disable read/write counts */
-#endif
-#endif /* (_SD_OPTIM_ALLOC) */
-
-#if defined(_SD_CHECKS) /* Enable checks, stats, and tracing */
-#undef _SD_NOCHECKS
-#undef _SD_NOTRACE
-#undef _SD_NOSTATS
-#define _SD_STATS /* Enable cache hits/longevity stats */
-#if (_SD_CHECKS+0 > 1)
-#define _SD_DEBUG /* Extra debugging checks */
-#endif
-#endif /* (_SD_CHECKS) */
-
-#if defined(_SD_NOTRACE) && defined(_SD_STATS)
-#undef _SD_STATS /* _SD_STATS requires SDTRACE() macro */
-#endif
-
-/*
- * Other compiler defines currently not enabled.
- * #define _SD_FBA_DATA_LOG Enable data logging per 512 bytes.
- * Other compiler defines enabled in the Makefile.
- * #define _SD_8K_BLKSIZE Allow 8K cache block size
- */
-
-extern int _sd_cblock_shift;
-#define BLK_SHFT (_sd_cblock_shift)
-#define BLK_MASK ((1 << BLK_SHFT) - 1)
-#define BLK_SIZE(x) ((x) << BLK_SHFT)
-#define BLK_NUM(x) ((x) >> BLK_SHFT)
-#define BLK_LEN(x) ((x + BLK_MASK) >> BLK_SHFT)
-#define BLK_OFF(x) ((x) & BLK_MASK)
-
-
-
-#define BLK_FBA_SHFT (BLK_SHFT - FBA_SHFT)
-#define BLK_FBA_MASK ((1 << BLK_FBA_SHFT) - 1)
-#define BLK_TO_FBA_NUM(x) \
- ((x) << BLK_FBA_SHFT) /* block_num to fba_num */
-#define BLK_FBA_OFF(x) ((x) & BLK_FBA_MASK) /* fba offset within */
- /* a cache block */
-
-#define FBA_TO_BLK_NUM(x) \
- ((x) >> BLK_FBA_SHFT) /* fba_num to a */
- /* block_num */
-
-/* fba_num to the next higher block_num */
-#define FBA_TO_BLK_LEN(x) ((x + BLK_FBA_MASK) >> BLK_FBA_SHFT)
-
-/*
- * This is the set of flags that are valid. Anything else set in the
- * handle is invalid and the handle should be rejected during an allocation.
- */
-
-#define _SD_VALID_FLAGS (NSC_RDWRBUF | NSC_NOBLOCK | NSC_WRTHRU | NSC_NOCACHE\
- | NSC_HALLOCATED | NSC_BCOPY | NSC_PAGEIO \
- | NSC_PINNABLE | NSC_MIXED | NSC_FORCED_WRTHRU \
- | NSC_METADATA)
-
-
-#define _SD_FLAG_MASK (NSC_FLAGS)
-#define _SD_HINT_MASK (NSC_HINTS)
-#define _SD_WRTHRU_MASK (NSC_WRTHRU | NSC_FORCED_WRTHRU)
-#define _SD_NOCACHE_MASK (NSC_NOCACHE)
-
-
-
-#define _SD_INVALID_CD(cd) ((cd) > sdbc_max_devs)
-
-#define _INFSD_NODE_UP(i) (nsc_node_up(i))
-
-#ifdef m88k
-#define _sd_cache_initialized _INFSD_cache_initialized
-#endif
-
-#define _SD_MAX_FBAS 1024
-/*
- * Allow one entry for null terminator and another to handle
- * requests that are not cache block aligned.
- */
-#if defined(_SD_8K_BLKSIZE)
-#define _SD_MAX_BLKS (2 + ((_SD_MAX_FBAS) >> 4))
-#else
-#define _SD_MAX_BLKS (2 + ((_SD_MAX_FBAS) >> 3))
-#endif
-
-/* cd to use for _sd_centry_alloc to avoid entering hash table */
-
-#define _CD_NOHASH -1
-
-#if defined(_KERNEL) || defined(_KMEMUSER)
-
-struct _sd_buf_handle;
-typedef void (*sdbc_callback_fn_t)(struct _sd_buf_handle *);
-
-typedef struct _sd_buf_handle {
- nsc_buf_t bh_buf; /* Generic buffer - must be first */
- nsc_vec_t bh_bufvec[_SD_MAX_BLKS]; /* Scatter gather list */
- int bh_cd;
- sdbc_callback_fn_t bh_disconnect_cb;
- sdbc_callback_fn_t bh_read_cb;
- sdbc_callback_fn_t bh_write_cb;
- struct _sd_cctl *bh_centry;
- struct _sd_buf_handle *bh_next;
- struct _sd_buf_handle *bh_prev;
- void *bh_alloc_thread; /* debug: kthread that alloc'd this handle */
- void *bh_busy_thread; /* debug: kthread that is using this handle */
- void *bh_param;
-} _sd_buf_handle_t;
-
-#define bh_fba_pos bh_buf.sb_pos
-#define bh_fba_len bh_buf.sb_len
-#define bh_flag bh_buf.sb_flag
-#define bh_error bh_buf.sb_error
-#define bh_vec bh_buf.sb_vec
-
-#define _sd_bufvec_t nsc_vec_t
-#define buflen sv_len
-#define bufaddr sv_addr
-#define bufvmeaddr sv_vme
-
-#endif /* _KERNEL || _KMEMUSER */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SD_CACHE_H */
diff --git a/usr/src/uts/common/avs/ns/sdbc/sd_conf.c b/usr/src/uts/common/avs/ns/sdbc/sd_conf.c
deleted file mode 100644
index 120b295c03..0000000000
--- a/usr/src/uts/common/avs/ns/sdbc/sd_conf.c
+++ /dev/null
@@ -1,839 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/ksynch.h>
-#include <sys/cmn_err.h>
-#include <sys/errno.h>
-#include <sys/kmem.h>
-#include <sys/ddi.h>
-
-#include <sys/nsc_thread.h>
-#include "sd_bcache.h"
-#include "sd_ft.h"
-#include "sd_misc.h"
-#include "sd_pcu.h"
-#include "sd_io.h"
-#include "sd_bio.h"
-#include "sd_trace.h"
-#include "sd_tdaemon.h"
-#include <sys/nsctl/nsctl.h>
-
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_k.h>
-#include <sys/unistat/spcs_errors.h>
-#include <sys/nsctl/safestore.h>
-
-extern int sdbc_use_dmchain;
-
-int _sd_cblock_shift = 0;
-
-int _SD_SELF_HOST = _SD_NO_HOST;
-int _SD_MIRROR_HOST = _SD_NO_HOST;
-int _SD_NUM_REM;
-int _sd_nodes_configured;
-int _sdbc_gateway_wblocks;
-
-int _SD_NETS = 0;
-
-/*
- * Normally we unregister memory at deconfig time. By setting this non-zero
- * it will be delayed until unload time.
- */
-int _sdbc_memtype_deconfigure_delayed = 0;
-
-nsc_mem_t *sdbc_iobuf_mem, *sdbc_hash_mem;
-nsc_mem_t *sdbc_local_mem, *sdbc_stats_mem, *sdbc_cache_mem;
-nsc_mem_t *sdbc_info_mem;
-
-_sd_cache_param_t _sd_cache_config;
-
-kmutex_t _sdbc_config_lock;
-volatile int _sd_cache_dem_cnt;
-
-#if !defined(m88k) || defined(lint)
-volatile int _sd_cache_initialized;
-#endif
-
-static blind_t sdbc_power;
-
-static
-nsc_def_t _sdbc_power_def[] = {
- "Power_Lost", (uintptr_t)_sdbc_power_lost, 0,
- "Power_OK", (uintptr_t)_sdbc_power_ok, 0,
- "Power_Down", (uintptr_t)_sdbc_power_down, 0,
- 0, 0, 0
-};
-
-/*
- * Forward declare all statics that are used before defined to enforce
- * parameter checking
- * Some (if not all) of these could be removed if the code were reordered
- */
-
-int _sd_fill_pattern(caddr_t addr, uint_t pat, uint_t size);
-static void _sdbc_nodeid_deconfigure(void);
-static void _sdbc_nodeid_configure(void);
-static void _sdbc_thread_deconfigure(void);
-static int _sdbc_thread_configure(void);
-void sst_deinit();
-
-ss_common_config_t safestore_config;
-safestore_ops_t *sdbc_safestore;
-
-/*
- * _sdbc_memtype_configure - register with the sd layer the types of memory
- * we want to use. If any of the critical memory types can't be registered
- * we return non-zero otherwise 0.
- */
-static int
-_sdbc_memtype_configure(void)
-{
-
- if ((sdbc_info_mem = nsc_register_mem("sdbc:info",
- NSC_MEM_GLOBAL, KM_NOSLEEP)) == NULL) {
- return (EINVAL);
- }
-
- sdbc_local_mem = nsc_register_mem("sdbc:local", NSC_MEM_LOCAL, 0);
- sdbc_stats_mem = nsc_register_mem("sdbc:stats", NSC_MEM_LOCAL, 0);
- sdbc_iobuf_mem = nsc_register_mem("sdbc:iobuf", NSC_MEM_LOCAL, 0);
-
- sdbc_cache_mem = nsc_register_mem("sdbc:cache", NSC_MEM_LOCAL, 0);
-
- sdbc_hash_mem = nsc_register_mem("sdbc:hash", NSC_MEM_LOCAL, 0);
-
- return (0);
-}
-
-/*
- * _sdbc_memtype_deconfigure - undo the effects of _sdbc_memtype_configure.
- */
-void
-_sdbc_memtype_deconfigure(void)
-{
-
- if (sdbc_hash_mem)
- nsc_unregister_mem(sdbc_hash_mem);
- if (sdbc_iobuf_mem)
- nsc_unregister_mem(sdbc_iobuf_mem);
- if (sdbc_cache_mem)
- nsc_unregister_mem(sdbc_cache_mem);
- if (sdbc_stats_mem)
- nsc_unregister_mem(sdbc_stats_mem);
- if (sdbc_local_mem)
- nsc_unregister_mem(sdbc_local_mem);
- if (sdbc_info_mem)
- nsc_unregister_mem(sdbc_info_mem);
-
- sdbc_info_mem = NULL;
- sdbc_local_mem = sdbc_stats_mem = sdbc_cache_mem = NULL;
- sdbc_iobuf_mem = sdbc_hash_mem = NULL;
-
-}
-
-
-/*
- * figure out what kind of safe storage we need
- */
-uint_t
-sdbc_determine_safestore()
-{
- return (SS_M_RAM | SS_T_NONE);
-}
-
-static void
-sd_setup_ssconfig()
-{
- safestore_config.ssc_client_psize = BLK_SIZE(1);
-
- if (_sd_cache_config.write_cache)
- safestore_config.ssc_wsize =
- _sd_cache_config.write_cache * MEGABYTE;
- else
- safestore_config.ssc_wsize =
- (_sd_cache_config.cache_mem[_SD_NO_NET] * MEGABYTE)/2;
- safestore_config.ssc_maxfiles = sdbc_max_devs;
- safestore_config.ssc_pattern = _sd_cache_config.fill_pattern;
- safestore_config.ssc_flag = _sd_cache_config.gen_pattern ?
- SS_GENPATTERN : 0;
-}
-
-/*
- * _sdbc_configure - process the ioctl that describes the configuration
- * for the cache. This is the main driver routine for cache configuration
- * Return 0 on success, otherwise nonzero.
- *
- */
-int
-_sdbc_configure(_sd_cache_param_t *uptr,
- _sdbc_config_t *mgmt, spcs_s_info_t spcs_kstatus)
-{
- int cache_bytes;
- nsc_io_t *io;
- char itmp[16];
- char itmp2[16];
- int i;
- uint_t ss_type;
- int rc;
-
- ASSERT(MUTEX_HELD(&_sdbc_config_lock));
-
- _sd_print(1, "sdbc(_sdbc_configure) _SD_MAGIC 0x%x\n", _SD_MAGIC);
-
- _sd_ioset = 0;
- if (_sd_cache_initialized) {
- spcs_s_add(spcs_kstatus, SDBC_EALREADY);
- rc = EALREADY;
- goto out;
- }
-
- ASSERT((uptr != NULL) || (mgmt != NULL));
-
- if (uptr) {
- if (copyin(uptr, &_sd_cache_config,
- sizeof (_sd_cache_param_t))) {
- rc = EFAULT;
- goto out;
- }
- } else {
- bzero(&_sd_cache_config, sizeof (_sd_cache_config));
-
- /* copy in mgmt config info */
-
- _sd_cache_config.magic = mgmt->magic;
- _sd_cache_config.threads = mgmt->threads;
-
- for (i = 0; i < CACHE_MEM_PAD; i++) {
- _sd_cache_config.cache_mem[i] = mgmt->cache_mem[i];
- }
-
- /* fake the rest as a single node config */
-
- _sd_cache_config.nodes_conf[0] = nsc_node_id();
- _sd_cache_config.num_nodes = 1;
- }
-
- /*
- * Check that the requested cache size doesn't break the code.
- * This test can be refined once the cache size is stored in variables
- * larger than an int.
- */
- for (i = 0; i < MAX_CACHE_NET; i++) {
- if (_sd_cache_config.cache_mem[i] < 0) {
- cmn_err(CE_WARN, "!_sdbc_configure: "
- "negative cache size (%d) for net %d",
- _sd_cache_config.cache_mem[i], i);
- spcs_s_add(spcs_kstatus, SDBC_ENONETMEM);
- rc = SDBC_ENONETMEM;
- goto out;
- }
- if (_sd_cache_config.cache_mem[i] > MAX_CACHE_SIZE) {
- _sd_cache_config.cache_mem[i] = MAX_CACHE_SIZE;
- cmn_err(CE_WARN, "!_sdbc_configure: "
- "cache size limited to %d megabytes for net %d",
- MAX_CACHE_SIZE, i);
- }
- }
-
- if (_sd_cache_config.blk_size == 0)
- _sd_cache_config.blk_size = 8192;
-
- if (_sd_cache_config.procs == 0)
- _sd_cache_config.procs = 16;
-
-#if !defined(_SD_8K_BLKSIZE)
- if (_sd_cache_config.blk_size != 4096) {
-#else
- if (_sd_cache_config.blk_size != 8192) {
-#endif
- (void) spcs_s_inttostring(_sd_cache_config.blk_size, itmp,
- sizeof (itmp), 0);
- spcs_s_add(spcs_kstatus, SDBC_ESIZE, itmp);
- rc = SDBC_EENABLEFAIL;
- goto out;
- }
- if (((_sd_cblock_shift =
- get_high_bit(_sd_cache_config.blk_size)) == -1) ||
- (_sd_cache_config.blk_size != (1 << _sd_cblock_shift))) {
- (void) spcs_s_inttostring(_sd_cache_config.blk_size, itmp,
- sizeof (itmp), 0);
- spcs_s_add(spcs_kstatus, SDBC_ESIZE, itmp);
- rc = SDBC_EENABLEFAIL;
- goto out;
- }
-
- if (_sd_cache_config.magic != _SD_MAGIC) {
- rc = SDBC_EMAGIC;
- goto out;
- }
-
- sdbc_use_dmchain = (_sd_cache_config.reserved1 & CFG_USE_DMCHAIN);
- sdbc_static_cache = (_sd_cache_config.reserved1 & CFG_STATIC_CACHE);
-
- _sdbc_nodeid_configure();
-
- if (_SD_SELF_HOST > nsc_max_nodeid ||
- _SD_MIRROR_HOST > nsc_max_nodeid) {
- (void) spcs_s_inttostring((_SD_SELF_HOST > nsc_max_nodeid ?
- _SD_SELF_HOST : _SD_MIRROR_HOST), itmp, sizeof (itmp), 0);
- (void) spcs_s_inttostring(
- nsc_max_nodeid, itmp2, sizeof (itmp2), 0);
- spcs_s_add(spcs_kstatus, SDBC_EINVHOSTID, itmp, itmp2);
- rc = SDBC_EENABLEFAIL;
- goto out;
- }
-
-
- if (_SD_SELF_HOST == _SD_MIRROR_HOST) {
- (void) spcs_s_inttostring(
- _SD_SELF_HOST, itmp, sizeof (itmp), 0);
- (void) spcs_s_inttostring(
- _SD_MIRROR_HOST, itmp2, sizeof (itmp2), 0);
- spcs_s_add(spcs_kstatus, SDBC_ENOTSAME, itmp, itmp2);
- rc = SDBC_EENABLEFAIL;
- goto out;
- }
-
- /* initialize the safestore modules */
- sst_init();
-
- /* figure out which kind of safestore we need to use */
- ss_type = sdbc_determine_safestore();
-
-tryss:
- /* open and configure the safestore module */
- if ((sdbc_safestore = sst_open(ss_type, 0)) == NULL) {
- cmn_err(CE_WARN, "!cannot open safestore module for type %x",
- ss_type);
- rc = SDBC_EENABLEFAIL;
- goto out;
- } else {
- sd_setup_ssconfig();
- if (SSOP_CONFIGURE(sdbc_safestore, &safestore_config,
- spcs_kstatus)) {
- cmn_err(CE_WARN,
- "!cannot configure safestore module for type %x",
- ss_type);
- (void) sst_close(sdbc_safestore);
-
- /* try ram if possible, otherwise return */
- if ((ss_type & (SS_M_RAM | SS_T_NONE)) ==
- (SS_M_RAM | SS_T_NONE)) {
- rc = SDBC_EENABLEFAIL;
- goto out;
- }
-
- ss_type = (SS_M_RAM | SS_T_NONE);
- goto tryss;
- }
- }
-
- if (SAFESTORE_LOCAL(sdbc_safestore))
- _SD_MIRROR_HOST = _SD_NO_HOST;
-
- ASSERT(safestore_config.ssc_ss_psize <= UINT16_MAX); /* LINTED */
- _sd_net_config.sn_psize = safestore_config.ssc_ss_psize;
-
-
- _sd_net_config.sn_csize =
- _sd_cache_config.cache_mem[_SD_NO_NET] * MEGABYTE;
- _sd_net_config.sn_cpages =
- _sd_net_config.sn_csize / BLK_SIZE(1);
-
- _sd_net_config.sn_configured = 1;
- cache_bytes = _sd_net_config.sn_cpages * BLK_SIZE(1);
-
- if (_sdbc_memtype_configure()) {
- rc = EINVAL;
- goto out;
- }
-
- if ((rc = _sdbc_iobuf_configure(_sd_cache_config.iobuf))) {
- if (rc == -1) {
- rc = SDBC_ENOIOBMEM;
- goto out;
- }
- if (rc == -2) {
- rc = SDBC_ENOIOBCB;
- goto out;
- }
-
- }
-
- if (_sdbc_handles_configure()) {
- rc = SDBC_ENOHANDLEMEM;
- goto out;
- }
-
- _sd_cache_dem_cnt = 0;
-
-
- /*
- * nvmem support:
- * if the cache did not shutdown properly we mark it as dirty.
- * this must be done before _sdbc_cache_configure() so it can
- * refresh sd_info_mem and sd_file_mem from nvmem if necsssary,
- * and before _sdbc_ft_configure() so the ft thread will do a recovery.
- *
- */
- if (SAFESTORE_RECOVERY(sdbc_safestore)) {
- _sdbc_set_warm_start();
- _sdbc_ft_hold_io = 1;
- cmn_err(CE_WARN,
- "!sdbc(_sdbc_configure) cache marked dirty after"
- " incomplete shutdown");
- }
-
- if ((rc = _sdbc_cache_configure(cache_bytes / BLK_SIZE(1),
- spcs_kstatus))) {
- goto out;
- }
-
-
- /* ST_ALERT trace buffer */
- if (_sdbc_tr_configure(-1 /* SDT_INV_CD */) != 0) {
- rc = EINVAL;
- goto out;
- }
-
- if (_sdbc_thread_configure()) {
- rc = SDBC_EFLUSHTHRD;
- goto out;
- }
-
- if (_sdbc_flush_configure()) {
- rc = EINVAL;
- goto out;
- }
-
- if (rc = _sdbc_dealloc_configure_dm()) {
- goto out;
- }
-
- if (_sd_cache_config.test_demons)
- if (_sdbc_tdaemon_configure(_sd_cache_config.test_demons)) {
- rc = EINVAL;
- goto out;
- }
-
-
- _sd_cache_initialized = 1;
-
- sdbc_power = nsc_register_power("sdbc", _sdbc_power_def);
-
- if (_sdbc_ft_configure() != 0) {
- rc = EINVAL;
- goto out;
- }
-
- /*
- * try to control the race between the ft thread
- * and threads that will open the devices that the ft thread
- * may be recovering. this synchronizing with the ft thread
- * prevents sd_cadmin from returning until ft has opened
- * the recovery devices, so if other apps wait for sd_cadmin
- * to complete the race is prevented.
- */
- mutex_enter(&_sdbc_ft_hold_io_lk);
- while (_sdbc_ft_hold_io) {
- cv_wait(&_sdbc_ft_hold_io_cv, &_sdbc_ft_hold_io_lk);
- }
-
- io = nsc_register_io("sdbc", NSC_SDBC_ID|NSC_FILTER,
- _sd_sdbc_def);
-
- if (io) sdbc_io = io;
-
- mutex_exit(&_sdbc_ft_hold_io_lk);
-
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!sd_config: Cache has been configured");
-#endif
-
- rc = 0;
-
-out:
- return (rc);
-}
-
-/*
- * _sdbc_deconfigure - Put the cache back to the unconfigured state. Release
- * any memory we allocated as part of the configuration process (but not the
- * load/init process). Put globals back to unconfigured state and shut down
- * any processes/threads we have running.
- *
- * Since the cache has loaded we know that global lock/sv's are present and
- * we can use them to produce an orderly deconfiguration.
- *
- * NOTE: this routine and its callee should always be capable of reversing
- * the effects of _sdbc_configure no matter what partially configured
- * state might be present.
- *
- */
-int
-_sdbc_deconfigure(spcs_s_info_t spcs_kstatus)
-{
- int i;
- _sd_cd_info_t *cdi;
- int rc;
- int pinneddata = 0;
- uint_t saved_hint;
-
- ASSERT(MUTEX_HELD(&_sdbc_config_lock));
-
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!SD cache being deconfigured.");
-#endif
-
- /* check if there is pinned data and our mirror is down */
- if (_sd_cache_files && _sd_is_mirror_down()) {
- for (i = 0; i < sdbc_max_devs; i++) {
- cdi = &(_sd_cache_files[i]);
- if (cdi->cd_info == NULL)
- continue;
- /*
- * if (!(cdi->cd_info->sh_failed))
- * continue;
- */
- if (!(_SD_CD_ALL_WRITES(i)))
- continue;
- spcs_s_add(spcs_kstatus, SDBC_EPINNED,
- cdi->cd_info->sh_filename);
- rc = SDBC_EDISABLEFAIL;
- goto out;
- }
- }
-
- /* remember hint setting for restoration in case shutdown fails */
- (void) _sd_get_node_hint(&saved_hint);
-
- (void) _sd_set_node_hint(NSC_FORCED_WRTHRU);
-
-
- /* TODO - there is a possible race between deconfig and power hits... */
-
- if (sdbc_power)
- (void) nsc_unregister_power(sdbc_power);
-
-
- if (sdbc_io) {
- rc = nsc_unregister_io(sdbc_io, NSC_PCATCH);
- if (rc == 0)
- sdbc_io = NULL;
- else {
- if (rc == EUSERS)
- spcs_s_add(spcs_kstatus, SDBC_EABUFS);
-
- spcs_s_add(spcs_kstatus, SDBC_EUNREG);
-
- /* Re-register-power if it was register before. */
- if (sdbc_power) {
- sdbc_power = nsc_register_power("sdbc",
- _sdbc_power_def);
- }
-
- /* Remove NSC_FORCED_WRTHRU if we set it */
- (void) _sd_clear_node_hint(
- (~saved_hint) & _SD_HINT_MASK);
-
- rc = SDBC_EDISABLEFAIL;
- goto out;
- }
- }
-
- sdbc_power = NULL;
-
-#if defined(_SD_FAULT_RES)
- _sd_remote_disable(0); /* notify mirror to forced_wrthru */
-#endif
- /*
- * close devices, deconfigure processes, wait for exits
- */
- _sdbc_tdaemon_deconfigure();
-
- if (_sd_cache_files) {
- for (i = 0; i < sdbc_max_devs; i++) {
- if (FILE_OPENED(i) && ((rc = _sd_close(i)) > 0)) {
- cmn_err(CE_WARN, "!sdbc(_sd_deconfigure)"
- " %d not closed (%d)\n", i, rc);
- }
- }
- }
-
- /*
- * look for pinned data
- * TODO sort this out for multinode systems.
- * cannot shutdown with pinned data on multinode.
- * the state of pinned data should be determined in
- * the close operation.
- */
- if (_sd_cache_files) {
- for (i = 0; i < sdbc_max_devs; i++) {
- cdi = &(_sd_cache_files[i]);
- if (cdi->cd_info == NULL)
- continue;
- /*
- * if (!(cdi->cd_info->sh_failed))
- * continue;
- */
- if (!(_SD_CD_ALL_WRITES(i)))
- continue;
- cmn_err(CE_WARN,
- "!sdbc(_sd_deconfigure) Pinned Data on cd %d(%s)",
- i, cdi->cd_info->sh_filename);
- pinneddata++;
- }
- }
-
- _sd_cache_initialized = 0;
-
- _sdbc_ft_deconfigure();
-
- _sdbc_flush_deconfigure();
- _sdbc_thread_deconfigure();
-
- mutex_enter(&_sd_cache_lock);
-
- while (_sd_cache_dem_cnt > 0) {
- mutex_exit(&_sd_cache_lock);
- (void) nsc_delay_sig(HZ/2);
- mutex_enter(&_sd_cache_lock);
- }
- mutex_exit(&_sd_cache_lock);
-
- /*
- * remove all dynamically allocated cache data memory
- * there should be no i/o at this point
- */
- _sdbc_dealloc_deconfigure_dm();
- /*
- * At this point no thread of control should be active in the cache
- * but us (unless they are blocked on the config lock).
- */
-
-
-#if defined(_SD_FAULT_RES)
- _sd_remote_disable(1); /* notify mirror I/O shutdown complete */
-#endif
-
-#define KEEP_TRACES 0 /* set to 1 keep traces after deconfig */
-#if !KEEP_TRACES
- /*
- * This needs to happen before we unregister the memory.
- */
- _sdbc_tr_deconfigure();
-#endif
-
-
- /* delete/free hash table, cache blocks, etc */
- _sdbc_cache_deconfigure();
-
- _sdbc_handles_deconfigure();
-
- _sdbc_iobuf_deconfigure();
-
-#if !KEEP_TRACES
- if (!_sdbc_memtype_deconfigure_delayed)
- _sdbc_memtype_deconfigure();
-#else
- _sdbc_memtype_deconfigure_delayed = 1;
-#endif
-
- /*
- * Call ss deconfig(),
- * check for valid pointer in case _sdbc_configure()
- * failed before safestrore system was initialized.
- */
- if (sdbc_safestore)
- SSOP_DECONFIGURE(sdbc_safestore, pinneddata);
-
- /* tear down safestore system */
- sst_deinit();
-
- _sdbc_nodeid_deconfigure();
-
- bzero(&_sd_cache_config, sizeof (_sd_cache_param_t));
-
- _SD_SELF_HOST = _SD_MIRROR_HOST = _SD_NO_HOST;
- _SD_NETS = 0;
- _sd_cblock_shift = 0;
- _sd_node_hint = 0;
-
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!SD cache deconfigured.");
-#endif
-
- rc = 0;
-
-out:
- return (rc);
-}
-
-
-
-static int
-find_low_bit(int mask, int start)
-{
- for (; start < 32; start++)
- if ((mask & (1 << start)))
- break;
-
- return (start);
-}
-
-int
-get_high_bit(int size)
-{
- int lowbit;
- int newblk = size;
- int highbit = -1;
- int next_high = 0;
-
- while ((lowbit = find_low_bit(newblk, 0)) != 32) {
- if (highbit >= 0) next_high = 1;
- highbit = lowbit;
- newblk &= ~(1 << highbit);
- }
-
- if (highbit <= 0) {
- cmn_err(CE_WARN,
- "!sdbc(get_high_bit) invalid block size %x\n", size);
- return (-1);
- }
-
- if (next_high) highbit++;
-
- return (highbit);
-}
-
-
-int
-_sd_fill_pattern(caddr_t addr, uint_t pat, uint_t size)
-{
- caddr_t fmt_page;
- int i, page_size;
-
- page_size = (int)ptob(1);
-
- if ((fmt_page = (caddr_t)nsc_kmem_alloc(ptob(1),
- KM_SLEEP, sdbc_local_mem)) == NULL) {
- cmn_err(CE_WARN, "!sdbc(_sd_fill pattern) no more memory");
- return (-1);
- }
- for (i = 0; i < page_size; i += 4)
- *(int *)(void *)(fmt_page + i) = pat;
-
- while (size >= page_size) {
- bcopy(fmt_page, addr, ptob(1));
- addr += page_size;
- size -= page_size;
- }
- nsc_kmem_free(fmt_page, page_size);
- return (0);
-}
-
-
-/*
- * _sdbc_nodeid_deconfigure - merely a place holder until
- * such time as there is something to be undone w.r.t.
- * _sdbc_nodeid_configure.
- *
- */
-static void
-_sdbc_nodeid_deconfigure(void)
-{
- /* My but we're quick */
-}
-
-/*
- * _sdbc_nodeid_configure - configure the nodeid's we need to connect
- * to any other nodes in the network.
- *
- */
-void
-_sdbc_nodeid_configure(void)
-{
-
- if (_sd_cache_config.num_nodes == 0) {
- _sd_nodes_configured = 1;
- } else {
- _sd_nodes_configured = _sd_cache_config.num_nodes;
- }
-
- _SD_SELF_HOST = nsc_node_id();
- _SD_MIRROR_HOST = _sd_cache_config.mirror_host;
-}
-
-#define STACK_SIZE (32*1024)
-#define num_spin 0
-nstset_t *_sd_ioset;
-
-/*
- * _sdbc_thread_deconfigure - cache is being deconfigure, stop any
- * thread activity.
- *
- */
-static void
-_sdbc_thread_deconfigure(void)
-{
- ASSERT(MUTEX_HELD(&_sdbc_config_lock));
- nst_destroy(_sd_ioset);
- _sd_ioset = NULL;
-}
-
-/*
- * _sdbc_thread_configure - cache is being configured, initialize the
- * threads we need for flushing dirty cds.
- *
- */
-static int
-_sdbc_thread_configure(void)
-{
- ASSERT(MUTEX_HELD(&_sdbc_config_lock));
-
- if (!_sd_ioset)
- _sd_ioset = nst_init("sd_thr", _sd_cache_config.threads);
-
- if (!_sd_ioset)
- return (EINVAL);
-
- return (0);
-}
-
-int
-_sdbc_get_config(_sdbc_config_t *config_info)
-{
- int i;
-
- config_info->enabled = _sd_cache_initialized;
- config_info->magic = _SD_MAGIC;
- for (i = 0; i < CACHE_MEM_PAD; i++) {
- config_info->cache_mem[i] = _sd_cache_config.cache_mem[i];
- }
- config_info->threads = _sd_cache_config.threads;
-
- return (0);
-}
diff --git a/usr/src/uts/common/avs/ns/sdbc/sd_conf.h b/usr/src/uts/common/avs/ns/sdbc/sd_conf.h
deleted file mode 100644
index b3ad6648a4..0000000000
--- a/usr/src/uts/common/avs/ns/sdbc/sd_conf.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SD_CONF_H
-#define _SD_CONF_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if defined(_RCSID)
-static char *rcs_sd_conf_h = "@(#)(SMI) sd_conf.h 1.1 07/06/21 16:17:54";
-#endif
-
-#define MEGABYTE (1024*1024)
-
-#define DEFAULT_HANDLES 1000
-#define MAX_SD_NODES 256 /* max configured nodes */
-#define SD_MCIII 0
-#define SD_MCIV 1
-
-/* for initializing fields to an invalid host id */
-#define _SD_NO_HOST -1
-
-/* netaddr filler for mc_*() compatibility */
-#define _SD_NO_NETADDR 0
-/* dummy net for mc_*() compatibility */
-#define _SD_NO_NET 0
-
-#define _SD_VME_DEFAULT (1024*1024) /* default 1mb contiguous memory */
-
-#ifdef _KERNEL
-
-extern _sd_cache_param_t _sd_cache_config;
-extern int _SD_SELF_DSP, _SD_REM_DSP[], _SD_NUM_REM;
-extern int _SD_SELF_HOST, _SD_MIRROR_HOST;
-extern int _sd_nodes_configured, _SD_HOST_CONF[];
-extern int _sd_parallel_resync_cnt;
-extern int _sdbc_gateway_wblocks;
-extern int _sdbc_memtype_deconfigure_delayed;
-extern kmutex_t _sdbc_config_lock;
-extern nsc_mem_t *sdbc_info_mem;
-extern nsc_mem_t *sdbc_iobuf_mem, *sdbc_hash_mem;
-extern nsc_mem_t *sdbc_local_mem, *sdbc_stats_mem, *sdbc_cache_mem;
-#if defined(_SD_USE_THREADS)
-extern nstset_t *_sd_ioset;
-#endif /* _SD_USE_THREADS */
-extern ushort_t SD_AUTO_RESYNC;
-extern volatile int _sd_cache_dem_cnt;
-extern volatile int _sd_cache_initialized;
-
-extern void _sdbc_memtype_deconfigure(void);
-extern int _sdbc_configure(_sd_cache_param_t *,
- _sdbc_config_t *, spcs_s_info_t);
-extern int _sdbc_deconfigure(spcs_s_info_t);
-extern int _sdbc_get_config(_sdbc_config_t *);
-extern int get_high_bit(int size);
-
-#endif /* _KERNEL */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SD_CONF_H */
diff --git a/usr/src/uts/common/avs/ns/sdbc/sd_ft.c b/usr/src/uts/common/avs/ns/sdbc/sd_ft.c
deleted file mode 100644
index 184462208f..0000000000
--- a/usr/src/uts/common/avs/ns/sdbc/sd_ft.c
+++ /dev/null
@@ -1,1266 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/ksynch.h>
-#include <sys/cmn_err.h>
-#include <sys/errno.h>
-#include <sys/kmem.h>
-#include <sys/cred.h>
-#include <sys/ddi.h>
-
-#include <sys/nsc_thread.h>
-#include <sys/nsctl/nsctl.h>
-
-#include <sys/sdt.h> /* dtrace is S10 or later */
-
-#include "sd_bcache.h"
-#include "sd_ft.h"
-#include "sd_trace.h"
-#include "sd_io.h"
-#include "sd_misc.h"
-#include <sys/ncall/ncall.h>
-
-_sd_ft_info_t _sd_ft_data;
-
-static volatile int _sd_ft_exit = 0;
-static kcondvar_t _sd_ft_cv;
-int _sd_node_recovery; /* node recovery in progress */
-/*
- * _sd_async_recovery:
- * 0 = flush and wait
- * 1 = clone and async-write
- * 2 = quicksort, clone, and async-write
- * quicksort allows contiguous blocks to be joined,
- * which may greatly improve recovery time for raid devices.
- * if kmem_alloc fails, acts as _sd_async_recovery == 1
- */
-static int _sd_async_recovery = 2;
-static int xmem_inval_hit, xmem_inval_miss, xmem_inval_inuse;
-
-
-/*
- * flag to inhibit reset of remote SCSI buses and sending of
- * nodedown callback if mirror was deconfigured properly.
- * - prevents trashing any I/O that may be happening on the mirror
- * node during a normal shutdown and prevents undesired simckd failover.
- */
-static int mirror_clean_shutdown = 0;
-
-/*
- * Forward declare all statics that are used before defined to enforce
- * parameter checking
- * Some (if not all) of these could be removed if the code were reordered
- */
-
-static void _sd_health_thread(void);
-static void _sd_cache_recover(void);
-static int _sd_ft_clone(ss_centry_info_t *, int);
-static void _sd_remote_enable(void);
-static void sdbc_setmodeandftdata();
-static void _sd_cd_discard_mirror(int cd);
-static int _sd_failover_file_open(void);
-static void _sd_failover_done(void);
-static void _sd_wait_for_dirty(void);
-static void _sdbc_clear_warm_start(void);
-static int sdbc_recover_vol(ss_vol_t *, int);
-void _ncall_poke(int);
-
-int _sdbc_ft_hold_io;
-kcondvar_t _sdbc_ft_hold_io_cv;
-kmutex_t _sdbc_ft_hold_io_lk;
-extern int sdbc_use_dmchain;
-extern void sdbc_requeue_head_dm_try(_sd_cctl_t *cc_ent);
-
-/*
- * _sdbc_ft_unload - cache is being unloaded (or failed to load).
- * Deallocate any global lock/sv that we created.
- */
-void
-_sdbc_ft_unload(void)
-{
- cv_destroy(&_sd_ft_cv);
- mutex_destroy(&_sd_ft_data.fi_lock);
- cv_destroy(&_sd_ft_data.fi_rem_sv);
- mutex_destroy(&_sd_ft_data.fi_sleep);
- bzero(&_sd_ft_data, sizeof (_sd_ft_info_t));
-}
-
-/*
- * _sdbc_ft_load - cache is being loaded. Allocate all global lock/sv
- * that we need. Return 0 if we succeed. If we fail return -1 (don't
- * need to do the unload step as we expect our caller to do that).
- */
-int
-_sdbc_ft_load(void)
-{
- /* _sd_ft_data is sure to be zeroes, don't need to bzero it */
-
- mutex_init(&_sd_ft_data.fi_lock, NULL, MUTEX_DRIVER, NULL);
- cv_init(&_sd_ft_data.fi_rem_sv, NULL, CV_DRIVER, NULL);
- cv_init(&_sd_ft_cv, NULL, CV_DRIVER, NULL);
- mutex_init(&_sd_ft_data.fi_sleep, NULL, MUTEX_DRIVER, NULL);
- return (0);
-}
-
-
-int
-_sdbc_ft_configure(void)
-{
- _sd_ft_exit = 1;
- return (nsc_create_process(
- (void (*)(void *))_sd_health_thread, 0, TRUE));
-}
-
-
-void
-_sdbc_ft_deconfigure(void)
-{
- _sd_ft_exit = 0;
- _sd_unblock(&_sd_ft_cv);
- mutex_enter(&_sd_ft_data.fi_lock);
- _sd_node_recovery = 0;
- cv_broadcast(&_sd_ft_data.fi_rem_sv);
- mutex_exit(&_sd_ft_data.fi_lock);
-}
-
-
-/*
- * _sd_health_thread -- daemon thread on each node watches if mirror
- * node to has crashed, and it needs to flush the mirrors cache entries.
- * Note we do *not* detect that the node has come up again, but wait
- * for the node to inform us that it is up via _sd_cache_reenable().
- */
-static void
-_sd_health_thread(void)
-{
- int warm_started = 0;
-
- mutex_enter(&_sd_cache_lock);
- _sd_cache_dem_cnt++;
- mutex_exit(&_sd_cache_lock);
-
- /* clear _sd_ft_data in case this is a cache re-enable w/o unload */
-
- bzero(&_sd_ft_data, sizeof (_sd_ft_info_t));
-
- sdbc_setmodeandftdata();
-
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!sdbc(_sd_health_thread) safestore "
- "is %s. Fast writes %s",
- (_SD_MIRROR_CONFIGD) ? "up" : "down",
- (_SD_NODE_HINTS & _SD_WRTHRU_MASK) ?
- "disabled" : "enabled");
-#endif
-
- /* CONSTCOND */
- while (1) {
- _sd_timed_block(HZ/8, &_sd_ft_cv);
- if (_sd_ft_exit == 0) {
- mutex_enter(&_sd_cache_lock);
- _sd_cache_dem_cnt--;
- mutex_exit(&_sd_cache_lock);
- return;
- }
-
- /* NB evaluation order is important here for nvmem systems */
- if (_sd_is_mirror_crashed() ||
- (warm_started = _sdbc_warm_start())) {
-
- /*
- * Hash invalidate here. We do not want data from
- * previous failover incarnation to be cache hits, if
- * the 2 failover happens within a short time
- */
- _sd_hash_invalidate_cd(-1);
-
- /*
- * don't change mirror state when warm starting
- * nvmem systems. _sd_mirror_down() is called in
- * in _sd_remote_enable() on nvmem systems if the
- * media is down.
- */
- if (!warm_started)
- if (!mirror_clean_shutdown)
- _sd_mirror_down();
- else
- _sd_mirror_cache_down();
-
- (void) _sd_set_node_hint(NSC_FORCED_WRTHRU);
- if (!warm_started) {
- /* was FAST */
- mutex_enter(&_sd_ft_data.fi_lock);
- _sd_node_recovery = 0;
- /* was FAST */
- mutex_exit(&_sd_ft_data.fi_lock);
- /* Assume other side is still up */
- cmn_err(CE_WARN,
- "!sdbc(_sd_health_thread)"
- "Safestore is down. Fast writes %s",
- (_SD_NODE_HINTS & _SD_WRTHRU_MASK) ?
- "disabled" : "enabled");
- _sd_unblock(&_sd_flush_cv);
-
- if (SAFESTORE_LOCAL(sdbc_safestore))
- continue;
-
- /* Wait for cache to drain and panic */
- _sd_wait_for_dirty();
- cmn_err(CE_WARN,
- "!sdbc(_sd_health_thread)"
- " dirty blocks flushed");
- continue;
- }
- /* was FAST */
- mutex_enter(&_sd_ft_data.fi_lock);
- _sd_node_recovery = 1;
- /* was FAST */
- mutex_exit(&_sd_ft_data.fi_lock);
- if (!SAFESTORE_LOCAL(sdbc_safestore))
- cmn_err(CE_WARN,
- "!sdbc(_sd_health_thread)"
- " Cache on node %d is down. "
- "Fast writes %s",
- _SD_MIRROR_HOST,
- (_SD_NODE_HINTS & _SD_WRTHRU_MASK) ?
- "disabled" : "enabled");
- cmn_err(CE_NOTE,
- "!sdbc(_sd_health_thread)"
- " Cache recovery in progress");
- _sd_cache_recover();
-
- mutex_enter(&_sd_ft_data.fi_lock);
- _sd_node_recovery = 0;
- _sdbc_clear_warm_start(); /* nvmem systems */
- cv_broadcast(&_sd_ft_data.fi_rem_sv);
- mutex_exit(&_sd_ft_data.fi_lock);
- cmn_err(CE_NOTE,
- "!sdbc(_sd_health_thread) %s Cache recovery done",
- _sd_async_recovery ?
- "asynchronous" : "synchronous");
- /* restore previous state */
- if (warm_started && !_sd_is_mirror_down()) {
- (void) _sd_clear_node_hint(NSC_FORCED_WRTHRU);
- cmn_err(CE_NOTE,
- "!sdbc(_sd_health_thread) Fast writes %s",
- (_SD_NODE_HINTS & _SD_WRTHRU_MASK) ?
- "disabled" : "enabled");
- }
- warm_started = 0;
-
- } else if (_sd_is_mirror_node_down()) {
- _sd_mirror_down();
- }
- }
-}
-
-/*
- * _sdbc_recovery_io_wait - wait for i/o being done directly
- * out of safe storage to complete. If the i/o does not make any
- * progress within about 25 seconds we return EIO otherwise return 0.
- *
- */
-static
-int
-_sdbc_recovery_io_wait(void)
-{
- int tries = 0;
- int last_numio = 0;
-
- /*
- * Wait for numio to reach 0.
- * If numio has not changed for 85+ seconds,
- * break & pin blocks
- */
- while (_sd_ft_data.fi_numio > 0) {
- if (last_numio == _sd_ft_data.fi_numio) {
- if (++tries > 512) break;
- } else {
- last_numio = _sd_ft_data.fi_numio;
- tries = 0;
- }
- delay(HZ/8);
- }
- if (_sd_ft_data.fi_numio != 0) {
- cmn_err(CE_WARN, "!sdbc(_sdbc_recovery_io_wait) %d "
- "recovery i/o's not done", _sd_ft_data.fi_numio);
- return (EIO);
- }
- return (0);
-}
-
-
-#if defined(_SD_FAULT_RES)
-/*
- * _sd_recovery_wait()
- * while _sd_node_recovery is set, accesses to mirrored devices will block
- * (_sd_node_recovery-1) is count of blocked threads.
- */
-int
-_sd_recovery_wait(void)
-{
- int blk;
-
- mutex_enter(&_sd_ft_data.fi_lock);
- blk = _sd_node_recovery ? _sd_node_recovery++ : 0;
-
- if (blk)
- cv_wait(&_sd_ft_data.fi_rem_sv, &_sd_ft_data.fi_lock);
- mutex_exit(&_sd_ft_data.fi_lock);
-
- if (!_sd_cache_initialized)
- return (EINVAL);
- return (0);
-}
-
-/*
- * _sd_recovery_wblk_wait - wait for recovery i/o to a device
- * to cease. If the file is closed or the cache is disabled
- * first return an error otherwise return 0.
- *
- * A device is being recovered from our point of view either
- * during failover or by putting a disk back online after
- * a disk failure.
- *
- * This code is used to delay access to a device while recovery
- * writes are in progress from either a failover or while flushing
- * i/o after a failed disk has been repaired.
- */
-int
-_sd_recovery_wblk_wait(int cd)
-{
- _sd_cd_info_t *cdi = &_sd_cache_files[cd];
-
- while (_sd_cache_initialized &&
- FILE_OPENED(cd) && cdi->cd_recovering) {
- /* spawn writer if none */
- if (!cdi->cd_writer) (void) cd_writer(cd);
- delay(HZ/8);
- }
- if (!_sd_cache_initialized || !FILE_OPENED(cd))
- return (EINVAL);
- return (0);
-}
-
-/*
- * Recover from a crash of another node:
- *
- * 1) Open all remote files
- * 2) Allocate other node's buffers and new buffer headers
- * 3) Flush all dirty buffers to disk
- * 4) Deallocate resources
- */
-static void
-_sd_cache_recover(void)
-{
- int cblocks_processed;
-
- SDTRACE(ST_ENTER|SDF_RECOVER, SDT_INV_CD, 0, SDT_INV_BL, 0, 0);
-
- /* was FAST */
- mutex_enter(&_sd_ft_data.fi_lock);
- _sd_ft_data.fi_numio = 0;
- /* was FAST */
- mutex_exit(&_sd_ft_data.fi_lock);
-
-#ifdef _SD_DRIVE_RESP
- if (!mirror_clean_shutdown)
- _raw_reset_other();
-#endif
- mirror_clean_shutdown = 0;
-
- cblocks_processed = _sd_failover_file_open();
-
- /* allow cache config to proceed */
- mutex_enter(&_sdbc_ft_hold_io_lk);
- _sdbc_ft_hold_io = 0;
- cv_signal(&_sdbc_ft_hold_io_cv);
- mutex_exit(&_sdbc_ft_hold_io_lk);
-
- /* wait for sequential recovery to complete */
- if (!_sd_async_recovery && cblocks_processed)
- (void) _sdbc_recovery_io_wait();
-
- _sd_failover_done();
-
- if (cblocks_processed)
- cmn_err(CE_NOTE,
- "!sdbc %ssynchronous recovery complete "
- "%d cache blocks processed",
- _sd_async_recovery ? "a" : "",
- cblocks_processed);
-
- SDTRACE(ST_EXIT|SDF_RECOVER, SDT_INV_CD, 0, SDT_INV_BL, 0, 0);
-}
-
-void
-_sd_mirror_iodone(void)
-{
- /* was FAST */
- mutex_enter(&_sd_ft_data.fi_lock);
- _sd_ft_data.fi_numio--;
- /* was FAST */
- mutex_exit(&_sd_ft_data.fi_lock);
-}
-
-
-
-/*
- * _sd_ft_clone -- clone cache block from ft area, retry write or pin.
- */
-static int
-_sd_ft_clone(ss_centry_info_t *ft_cent, int async)
-{
- _sd_cctl_t *ent;
- int cd = ft_cent->sc_cd;
- nsc_off_t cblk = ft_cent->sc_fpos;
- int dirty = ft_cent->sc_dirty;
- ss_resource_t *res = ft_cent->sc_res;
- _sd_cd_info_t *cdi;
-
- SDTRACE(ST_ENTER|SDF_FT_CLONE, cd, BLK_FBAS, cblk, dirty, _SD_NO_NET);
- cdi = &(_sd_cache_files[cd]);
- if ((cdi->cd_info->sh_failed != 2) && !FILE_OPENED(cd)) {
- cmn_err(CE_WARN, "!sdbc(_sd_ft_clone) recovery "
- "write failed: cd %x; cblk %" NSC_SZFMT "; dirty %x",
- cd, cblk, dirty);
- SDTRACE(ST_EXIT|SDF_FT_CLONE,
- cd, BLK_FBAS, cblk, dirty, EINTR);
- return (-1);
- }
-
- /*
- * allocate new cache entry and read data
- */
- ent = sdbc_centry_alloc_blks(cd, cblk, 1, 0);
-
- if (SSOP_READ_CBLOCK(sdbc_safestore, res, (void *)ent->cc_data,
- CACHE_BLOCK_SIZE, 0) == SS_ERR) {
- cmn_err(CE_WARN, "!sdbc(_sd_ft_clone) read of "
- "pinned data block failed. cannot recover "
- "0x%p size 0x%x", (void *)res, CACHE_BLOCK_SIZE);
-
- /* _sd_process_failure ?? */
- _sd_centry_release(ent);
- return (-1);
- }
-
- ent->cc_write = ft_cent;
- ent->cc_dirty = ent->cc_valid = (ushort_t)dirty;
- ent->cc_flag |= (ft_cent->sc_flag & CC_PINNABLE);
-
- ent->cc_chain = NULL;
-
- /*
- * _sd_process_failure() adds to failed list & does pinned callback
- * otherwise async flush
- */
- if (cdi->cd_info->sh_failed) { /* raw device open/reserve failed */
- mutex_enter(&cdi->cd_lock);
- (cdi->cd_info->sh_numio)++;
- mutex_exit(&cdi->cd_lock);
- (void) _sd_process_failure(ent);
- } else {
-
- if (cdi->cd_global->sv_pinned != _SD_NO_HOST) {
- cdi->cd_global->sv_pinned = _SD_NO_HOST;
- SSOP_SETVOL(sdbc_safestore, cdi->cd_global);
- }
-
- if (async) {
- _sd_enqueue_dirty(cd, ent, ent, 1);
- } else {
- /*
- * this is sync write with asynchronous callback
- * (queue to disk and return).
- */
-
- mutex_enter(&(cdi->cd_lock));
- (cdi->cd_info->sh_numio)++;
- mutex_exit(&cdi->cd_lock);
- _sd_async_flcent(ent, cdi->cd_crdev);
- }
- }
- _sd_centry_release(ent);
- SDTRACE(ST_EXIT|SDF_FT_CLONE, cd, BLK_FBAS, cblk, dirty, _SD_NO_NET);
- return (0);
-}
-
-
-/*
- * _sd_repin_cd - scan for dirty blocks held by mirror node.
- *
- * sdbc on this node is being attached to cd. If sdbc on other
- * node had failed writes (pinnable or not) we need to take
- * responsbility for them now here.
- */
-int
-_sd_repin_cd(int cd)
-{
- ss_voldata_t *cd_gl;
- _sd_cd_info_t *cdi;
-
- if (!FILE_OPENED(cd))
- return (EINVAL);
-
- cdi = &_sd_cache_files[cd];
- if (cdi->cd_global->sv_pinned == _SD_NO_HOST)
- return (0);
-
- cd_gl = _sdbc_gl_file_info + cd;
-
- if (sdbc_recover_vol(cd_gl->sv_vol, cd))
- _sd_cd_discard_mirror(cd);
-
- return (0);
-}
-
-
-static int
-_sd_cache_mirror_enable(int host)
-{
- if (_sd_cache_initialized) {
- if (host != _SD_MIRROR_HOST) {
- cmn_err(CE_WARN, "!sdbc(_sd_cache_mirror_enable) "
- "Configured mirror %x. Got message from %x",
- _SD_MIRROR_HOST, host);
- return (-EINVAL);
- }
- if (_sd_node_recovery) (void) _sd_recovery_wait();
- if (_sd_cache_initialized && _sd_is_mirror_down()) {
- int i;
-
- /* make sure any pinned data we have is now refreshed */
- for (i = 0; i < sdbc_max_devs; i++)
- if (FILE_OPENED(i))
- (void) _sdbc_remote_store_pinned(i);
-
- cmn_err(CE_NOTE,
- "!sdbc(_sd_cache_mirror_enable) Cache on "
- "mirror node %d is up. Fast writes enabled",
- host);
- _sd_mirror_up();
- (void) _sd_clear_node_hint(NSC_FORCED_WRTHRU);
- }
- }
- _sd_ft_data.fi_host_state = _SD_HOST_CONFIGURED;
- return (_sd_cache_initialized);
-}
-
-
-/*
- * two stage mirror disable:
- * stage 0: set FORCED_WRTHRU hint (cache shutdown started)
- * stage 1: mirror shutdown completed
- */
-static int
-_sd_cache_mirror_disable(int host, int stage)
-{
- if (_sd_cache_initialized) {
-
- if (host != _SD_MIRROR_HOST)
- return (0);
- if (stage == 0) {
- (void) _sd_set_node_hint(NSC_FORCED_WRTHRU);
- return (0);
- }
- _sd_ft_data.fi_host_state = _SD_HOST_DECONFIGURED;
- mirror_clean_shutdown = 1;
- _sd_unblock(&_sd_ft_cv);
- } else {
- _sd_ft_data.fi_host_state = _SD_HOST_NONE;
- }
- return (0);
-}
-
-/*
- * set the fault tolerant data to indicate the state
- * of the safestore host. set mode to writethru if appropriate
- */
-static void
-sdbc_setmodeandftdata()
-{
- /*
- * if single node local safestore or ram safestore
- * then mark host state as carashed/_SD_HOST_NONE and set writethru
- */
- if (SAFESTORE_LOCAL(sdbc_safestore)) {
- if (!SAFESTORE_SAFE(sdbc_safestore)) {
- _sd_mirror_down(); /* mirror node down */
- (void) _sd_set_node_hint(NSC_FORCED_WRTHRU);
- } else {
- _sd_ft_data.fi_host_state = _SD_HOST_CONFIGURED;
- if (_sdbc_warm_start())
- (void) _sd_set_node_hint(NSC_FORCED_WRTHRU);
- }
- } else
- _sd_remote_enable();
-}
-
-static void
-_sd_remote_enable(void)
-{
- ncall_t *ncall;
- long r;
-
- if (ncall_alloc(_SD_MIRROR_HOST, 0, _SD_NO_NET, &ncall)) {
- _sd_mirror_down(); /* mirror node down */
- (void) _sd_set_node_hint(NSC_FORCED_WRTHRU);
- return;
- }
-
- r = ncall_send(ncall, 0, SD_ENABLE, _SD_SELF_HOST);
- if (!r) (void) ncall_read_reply(ncall, 1, &r);
- ncall_free(ncall);
-
- if (r == 1) { /* _sd_cache_initialized */
- if (!_sd_is_mirror_crashed() &&
- _sd_ft_data.fi_host_state == _SD_HOST_NONE)
- _sd_ft_data.fi_host_state = _SD_HOST_CONFIGURED;
- return;
- }
- if (r == ENOLINK)
- _sd_mirror_down(); /* mirror node down */
- else
- _sd_mirror_cache_down(); /* mirror up, but no cache */
- (void) _sd_set_node_hint(NSC_FORCED_WRTHRU);
-}
-
-
-void
-_sd_remote_disable(int stage)
-{
- ncall_t *ncall;
-
- if (ncall_alloc(_SD_MIRROR_HOST, 0, 0, &ncall) == 0)
- (void) ncall_send(ncall, NCALL_ASYNC, SD_DISABLE,
- _SD_SELF_HOST, stage);
-}
-
-void
-r_sd_ifs_cache_enable(ncall_t *ncall, int *ap)
-{
- ncall_reply(ncall, _sd_cache_mirror_enable(*ap));
-}
-
-
-
-void
-r_sd_ifs_cache_disable(ncall_t *ncall, int *ap)
-{
- (void) _sd_cache_mirror_disable(ap[0], ap[1]);
- ncall_done(ncall);
-}
-
-#else /* (_SD_FAULT_RES) */
-
-void r_sd_ifs_cache_enable() {; }
-void r_sd_ifs_cache_disable() {; }
-
-#endif /* (_SD_FAULT_RES) */
-
-/*
- * invalidate cache hash table entries for given device
- * or (-1) all devices belonging to mirrored node
- */
-void
-_sd_hash_invalidate_cd(int CD)
-{
- int i;
- _sd_cd_info_t *cdi;
- _sd_hash_hd_t *hptr;
- _sd_cctl_t *cc_ent, *ent;
- _sd_hash_bucket_t *bucket;
- int cd;
- nsc_off_t blk;
-
- for (i = 0; i < (_sd_htable->ht_size); i++) {
- bucket = (_sd_htable->ht_buckets + i);
- mutex_enter(bucket->hb_lock);
- hptr = bucket->hb_head;
- while (hptr) {
- cc_ent = (_sd_cctl_t *)hptr;
- cd = CENTRY_CD(cc_ent);
- blk = CENTRY_BLK(cc_ent);
- cdi = &_sd_cache_files[cd];
-
- /*
- * Skip if device doesn't match or pinned.
- * (-1) skip attached cd's
- */
- if ((CD != -1 && (cd != CD || CENTRY_PINNED(cc_ent))) ||
- (CD == -1 && nsc_held(cdi->cd_rawfd))) {
- hptr = hptr->hh_next;
- continue;
- }
- mutex_exit(bucket->hb_lock);
-
- ent = cc_ent;
- fl1:
- if (CC_CD_BLK_MATCH(cd, blk, ent) ||
- (ent = (_sd_cctl_t *)_sd_hash_search(cd, blk,
- _sd_htable))) {
- if (SET_CENTRY_INUSE(ent)) {
- xmem_inval_inuse++;
- _sd_cc_wait(cd, blk, ent, CC_INUSE);
- goto fl1; /* try again */
- }
-
- /* cc_inuse is set, delete on block match */
- if (CC_CD_BLK_MATCH(cd, blk, ent)) {
- xmem_inval_hit++;
- (void) _sd_hash_delete(
- (struct _sd_hash_hd *)ent,
- _sd_htable);
-
- if (sdbc_use_dmchain) {
-
- /* attempt to que head */
- if (ent->cc_alloc_size_dm) {
- sdbc_requeue_head_dm_try
- (ent);
- }
- } else
- _sd_requeue_head(ent);
-
- } else
- xmem_inval_miss++;
-
- CLEAR_CENTRY_INUSE(ent);
- }
- mutex_enter(bucket->hb_lock);
- hptr = bucket->hb_head;
- }
- mutex_exit(bucket->hb_lock);
- }
-}
-
-
-/*
- * _sd_cd_online(cd,discard)
- * clear local error state.
- * if (discard && _attached != _SD_SELF_HOST) then release buffers.
- * if (!discard && _attached != _SD_MIRROR_HOST) then re-issue I/Os
- * (add to dirty pending queue).
- * returns:
- * 0 success
- * EINVAL invalid device or not failed
- * EBUSY attached by this node, or by active mirror
- */
-static int
-_sd_cd_online(int cd, int discard)
-{
- _sd_cd_info_t *cdi = &_sd_cache_files[cd];
- int failed, num;
- _sd_cctl_t *cc_ent, *cc_next, *cc_last, *cc_first, *cc_next_chain;
-
- /*
- * in the case where a failed device has been closed and
- * then re-opened, sh_failed will be zero because it is
- * cleared in _sd_open_cd(). hence the test for
- * _pinned != _SD_SELF_HOST which allows the restore to
- * proceed in this scenario.
- */
- if (cd < 0 || cd >= sdbc_max_devs)
- return (EINVAL);
-
- if (!cdi->cd_info || !cdi->cd_global)
- return (EINVAL);
-
- if ((cdi->cd_info->sh_failed == 0) &&
- (cdi->cd_global->sv_pinned != _SD_SELF_HOST))
- return (0);
-
- if (_sd_nodes_configured > 1) {
-
- /* can't discard while attached on multinode systems */
- if (discard && (cdi->cd_global->sv_attached == _SD_SELF_HOST))
- return (EBUSY);
-
- if (!discard && /* attached by active mirror! */
- (cdi->cd_global->sv_attached == _SD_MIRROR_HOST) &&
- !_sd_is_mirror_down())
- return (EBUSY);
- }
-
- mutex_enter(&cdi->cd_lock);
-
- cc_ent = cdi->cd_fail_head;
- failed = cdi->cd_info->sh_numfail;
- cdi->cd_fail_head = NULL;
- cdi->cd_info->sh_numfail = 0;
- cdi->cd_info->sh_failed = 0;
- cdi->cd_global->sv_pinned = _SD_NO_HOST;
- SSOP_SETVOL(sdbc_safestore, cdi->cd_global);
-
- if (cc_ent == NULL) {
- mutex_exit(&cdi->cd_lock);
- return (0);
- }
- /* prevent any new i/o from arriving for this cd */
- if (!discard)
- cdi->cd_recovering = 1;
-
- mutex_exit(&cdi->cd_lock);
-
- num = 0;
- cc_first = cc_ent;
- for (; cc_ent; cc_ent = cc_next_chain) {
- cc_next_chain = cc_ent->cc_dirty_link;
-
- for (; cc_ent; cc_ent = cc_next) {
- cc_next = cc_ent->cc_dirty_next;
- cc_last = cc_ent;
- num++;
-
- if (discard) {
- ss_centry_info_t *wctl;
- /* was FAST */
- mutex_enter(&cc_ent->cc_lock);
- cc_ent->cc_valid = cc_ent->cc_dirty = 0;
- cc_ent->cc_flag &= ~(CC_PEND_DIRTY|CC_PINNED);
- cc_ent->cc_dirty_next = NULL;
- cc_ent->cc_dirty_link = NULL;
- wctl = cc_ent->cc_write;
- cc_ent->cc_write = NULL;
- /* was FAST */
- mutex_exit(&cc_ent->cc_lock);
- if (wctl) {
- wctl->sc_flag = 0;
- wctl->sc_dirty = 0;
-
- SSOP_SETCENTRY(sdbc_safestore, wctl);
- SSOP_DEALLOCRESOURCE(sdbc_safestore,
- wctl->sc_res);
- }
-
- continue;
- }
-
- /* Clear PEND_DIRTY, iocount & iostatus */
- if (SET_CENTRY_INUSE(cc_ent) == 0) {
- cc_ent->cc_flag &= ~CC_PEND_DIRTY;
- cc_ent->cc_iocount = 0;
- cc_ent->cc_iostatus = 0; /* _SD_IO_NONE */
- CLEAR_CENTRY_INUSE(cc_ent);
- } else {
- /* was FAST */
- mutex_enter(&cc_ent->cc_lock);
- cc_ent->cc_flag &= ~CC_PEND_DIRTY;
- cc_ent->cc_iocount = 0;
- cc_ent->cc_iostatus = 0; /* _SD_IO_NONE */
- /* was FAST */
- mutex_exit(&cc_ent->cc_lock);
- }
- }
- }
- if (num != failed)
- cmn_err(CE_WARN, "!sdbc(_sd_cd_online) count %d vs numfail %d",
- num, failed);
- if (discard) {
- _sd_hash_invalidate_cd(cd);
- return (0);
- }
-
- _sd_enqueue_dirty_chain(cd, cc_first, cc_last, num);
- /* make sure data gets flushed in case there is no new I/O */
- (void) nsc_reserve(cdi->cd_rawfd, NSC_MULTI);
- (void) _sd_wait_for_flush(cd);
- cdi->cd_recovering = 0;
- nsc_release(cdi->cd_rawfd);
-
- return (0);
-}
-
-#if defined(_SD_FAULT_RES)
-
-/*
- * This node has disk attached, discard pins held by mirror
- */
-static void
-_sd_cd_discard_mirror(int cd)
-{
- ncall_t *ncall;
- if (ncall_alloc(_SD_MIRROR_HOST, 0, 0, &ncall))
- return;
- (void) ncall_send(ncall, NCALL_ASYNC, SD_CD_DISCARD, cd);
-}
-
-void
-r_cd_discard(ncall_t *ncall, int *ap)
-{
- int r, cd = *ap;
- if (_sd_cache_initialized) {
- SDTRACE(ST_ENTER|SDF_ONLINE, cd, 1, SDT_INV_BL, 1, 0);
- r = _sd_cd_online(cd, 1);
- SDTRACE(ST_EXIT|SDF_ONLINE, cd, 1, SDT_INV_BL, 1, r);
- }
- ncall_done(ncall);
-}
-
-/*
- * _sd_failover_file_open -
- * on failover, open devices which are not attached by this node.
- */
-static int
-_sd_failover_file_open(void)
-{
- int rc, cd, flag = 0;
- ss_voldata_t *cd_gl;
- _sd_cd_info_t *cdi;
- int cblocks_processed = 0;
- extern ss_voldata_t *_sdbc_gl_file_info;
-
- for (cd = 0; cd < sdbc_max_devs; cd++) {
- cd_gl = _sdbc_gl_file_info + cd;
- cdi = &(_sd_cache_files[cd]);
-
- /*
- * If the cd is open and reserved we certainly don't
- * need to do it again. However the recovery code
- * must be racing some other cache usage which could
- * be bad. We really need to be able to lock out
- * all cache activity for this cd that is not tied
- * to the recovery process. This doesn't seem to be
- * feasible in sdbc since a competing thread could
- * already be finished doing an alloc_buf. If this
- * hole is to be closed sd-ctl must be more in
- * control of the failover process.
- */
- if (FILE_OPENED(cd) && nsc_held(cdi->cd_rawfd))
- continue;
-
- /*
- * this constuct says that, on non-nvmem systems,
- * if we are attempting to open a "local" device and
- * nothing is pinned, then continue. i.e. open only
- * remote devices or devices that have pinned data.
- * for recovery on nvmem systems we open all devices.
- */
- if ((!_sdbc_warm_start()) &&
- ((cd_gl->sv_attached != _SD_MIRROR_HOST) &&
- (cd_gl->sv_pinned != _SD_MIRROR_HOST) &&
- (cd_gl->sv_pinned != _SD_SELF_HOST)))
- continue;
- if (!cd_gl->sv_volname || !cd_gl->sv_volname[0])
- continue;
-
- if (_sd_open_cd(cd_gl->sv_volname, cd, flag) < 0) {
- cmn_err(CE_WARN, "!sdbc(_sd_failover_file_open) "
- "Unable to open disk partition %s",
- cd_gl->sv_volname);
- continue;
- }
-
- SDTRACE(ST_INFO|SDF_RECOVER, cd, 0, 0, 0, 0);
- rc = nsc_reserve(cdi->cd_rawfd, NSC_MULTI);
- if (rc == 0) {
- cdi->cd_failover = 1;
- }
-
- if (rc != 0) cdi->cd_info->sh_failed = 1;
-
- cblocks_processed += sdbc_recover_vol(cd_gl->sv_vol, cd);
- }
-
- return (cblocks_processed);
-}
-
-
-static int
-sdbc_recover_vol(ss_vol_t *vol, int cd)
-{
- ss_cdirkey_t key;
- ss_cdir_t cdir;
- ss_voldata_t *cd_gl = _sdbc_gl_file_info + cd;
- ss_centry_info_t *cinfo;
- ss_centry_info_t centry;
- int cblocks_processed = 0;
- int err;
- ss_centry_info_t *sdbc_get_cinfo_byres(ss_resource_t *);
-
- /* setup the key to get a volume directory stream of centrys */
- key.ck_type = CDIR_VOL;
- key.cdk_u.ck_vol = vol;
-
- if (SSOP_GETCDIR(sdbc_safestore, &key, &cdir)) {
- cmn_err(CE_WARN, "!sdbc(sdbc_recover_vol): "
- "cannot recover volume %s",
- cd_gl->sv_volname);
- return (0);
- }
-
- /* cycle through the cdir getting resource tokens and reading centrys */
- /*CONSTANTCONDITION*/
- while (1) {
-
- if ((err = SSOP_GETCDIRENT(sdbc_safestore, &cdir, &centry))
- == SS_ERR) {
- cmn_err(CE_WARN, "!sdbc(sdbc_recover_vol): "
- "cache entry read failure %s %p",
- cd_gl->sv_volname, (void *)centry.sc_res);
-
- continue;
- }
-
-
- if (err == SS_EOF)
- break; /* done */
-
-
- /*
- * this get into double caching consistency
- * need to resolve this jgk
- */
- if ((cinfo = sdbc_get_cinfo_byres(centry.sc_res)) == NULL) {
- /* should not happen */
- cmn_err(CE_WARN, "!sdbc(sdbc_recover_vol): "
- "invalid ss resource %p", (void *)centry.sc_res);
- continue;
- }
- bcopy(&centry, cinfo, sizeof (ss_centry_info_t));
-
- /*
- * note
- * ss should return a stream of dirty blocks ordered
- * by block number. if it turns out that ss will not support
- * this then sorting for async recovery will have to be
- * done here jgk
- */
- ASSERT(cinfo->sc_dirty);
-
- if (!cinfo->sc_dirty) /* should not happen */
- continue;
-
- /*
- * clone mirror cache entry and do
- * async I/O or sync I/O or pin if sh_failed
- */
- (void) _sd_ft_clone(cinfo, _sd_async_recovery);
- ++cblocks_processed;
- }
-
-
- if (cblocks_processed)
- cmn_err(CE_NOTE,
- "!sdbc(sdbc_recover_vol) %d cache blocks processed for "
- "volume %s", cblocks_processed, cd_gl->sv_volname);
-
- return (cblocks_processed);
-}
-
-/*
- * _sd_failover_done -
- * mark failover open'd devices as requiring nsc_release()
- * when all queued I/O's have drained.
- */
-static void
-_sd_failover_done(void)
-{
- _sd_cd_info_t *cdi;
- int cd;
-
- for (cd = 0; cd < sdbc_max_devs; cd++) {
- cdi = &(_sd_cache_files[cd]);
-
- if (FILE_OPENED(cd) && cdi->cd_failover)
- cdi->cd_failover = 2;
- }
-}
-
-#endif /* (_SD_FAULT_RES) */
-
-/*
- * _sd_uncommit - discard local buffer modifications
- * clear the valid bits.
- */
-int
-_sd_uncommit(_sd_buf_handle_t *handle, nsc_off_t fba_pos, nsc_size_t fba_len,
- int flag)
-{
- int cd;
- sdbc_cblk_fba_t st_cblk_len; /* FBA len of starting cache block */
- sdbc_cblk_fba_t end_cblk_len; /* FBA len of ending cache block */
- sdbc_cblk_fba_t st_cblk_off; /* FBA offset into starting cblock */
- nsc_size_t cc_len;
- int bits;
- _sd_cctl_t *cc_ent;
-
- cd = HANDLE_CD(handle);
-
- ASSERT_HANDLE_LIMITS(handle, fba_pos, fba_len);
-
- if ((handle->bh_flag & NSC_WRBUF) == 0) {
- DTRACE_PROBE(_sd_uncommit_end_handle_write);
-
- return (EINVAL);
- }
-
- if (fba_len == 0) {
- DTRACE_PROBE(_sd_uncommit_end_zero_len);
- return (NSC_DONE);
- }
-
- SDTRACE(ST_ENTER|SDF_UNCOMMIT, cd, fba_len, fba_pos, flag, 0);
-
- cc_ent = handle->bh_centry;
- while (CENTRY_BLK(cc_ent) != FBA_TO_BLK_NUM(fba_pos))
- cc_ent = cc_ent->cc_chain;
-
- cc_len = fba_len; /* current length */
- st_cblk_off = BLK_FBA_OFF(fba_pos);
- st_cblk_len = (BLK_FBAS - st_cblk_off);
- if ((nsc_size_t)st_cblk_len >= fba_len) {
- end_cblk_len = 0;
- st_cblk_len = (sdbc_cblk_fba_t)fba_len;
- }
- else
- end_cblk_len = BLK_FBA_OFF(fba_pos + fba_len);
-
- /*
- * Check if remote write-cache spool is dirty,
- * if not, we can just discard local valid bits.
- */
- bits = SDBC_GET_BITS(st_cblk_off, st_cblk_len);
- cc_ent->cc_valid &= ~bits;
-
- cc_len -= st_cblk_len;
- cc_ent = cc_ent->cc_chain;
- bits = SDBC_GET_BITS(0, BLK_FBAS);
-
- while (cc_len > (nsc_size_t)end_cblk_len) {
- cc_ent->cc_valid = 0;
- cc_ent = cc_ent->cc_chain;
- cc_len -= BLK_FBAS;
- }
-
-#if defined(_SD_DEBUG)
- if (cc_len != end_cblk_len)
- cmn_err(CE_WARN, "!fba_len %" NSC_SZFMT " end_cblk_len %d in "
- "_sd_write", fba_len, end_cblk_len);
-#endif
-
- if (cc_len) {
- bits = SDBC_GET_BITS(0, end_cblk_len);
- cc_ent->cc_valid &= ~bits;
- }
- SDTRACE(ST_EXIT|SDF_UNCOMMIT, cd, fba_len, fba_pos, flag, 0);
-
- return (NSC_DONE);
-}
-
-static void
-_sd_wait_for_dirty(void)
-{
- int cd;
-
- for (cd = 0; cd < sdbc_max_devs; cd++) {
- while (_SD_CD_WBLK_USED(cd))
- delay(HZ);
- }
-}
-
-/*
- * _sd_wait_for_flush - wait for all i/o for this cd to cease.
- * This function assumes that no further i/o are being issued
- * against this device. This assumption is enforced by sd-ctl
- * when called from _sd_flush_cd. Recovery also uses this
- * wait and it enforces this assumption (somewhat imperfectly)
- * by using cd_recovering.
- * We must see progress in getting i/o complete within 25 seconds
- * or we will return an error. If we complete normally (all i/o done)
- * we return 0.
- */
-int
-_sd_wait_for_flush(int cd)
-{
- _sd_cd_info_t *cdi = &(_sd_cache_files[cd]);
- int tries = 0, used, last_used = 0, inprogress = 0;
-
- if (!(_SD_CD_WBLK_USED(cd)))
- return (0);
- /*
- * Wait for WBLK_USED to reach 0.
- * If unchanged for 32+ seconds returns EAGAIN
- */
- if (!cdi->cd_writer)
- (void) cd_writer(cd); /* spawn writer if not already running */
-
- while (((used = _SD_CD_WBLK_USED(cd)) != 0) || cdi->cd_writer) {
- if (last_used == used &&
- inprogress == cdi->cd_write_inprogress) {
- if (cdi->cd_info->sh_failed)
- break;
- if (++tries > 128) {
- cmn_err(CE_WARN, "!sdbc(_sd_wait_for_flush) "
- "%s still has %d blocks pending %d"
- " in progress (@ %lx)",
- cdi->cd_info->sh_filename, last_used,
- inprogress, nsc_lbolt());
- return (EAGAIN);
- }
- } else {
- last_used = used;
- inprogress = cdi->cd_write_inprogress;
- tries = 0;
- }
- _sd_unblock(&_sd_flush_cv);
- delay(HZ/4);
- }
- if (cdi->cd_info->sh_failed)
- return (EIO);
- else
- return (0);
-}
-
-
-static
-int _sd_ft_warm_start;
-
-int
-_sdbc_warm_start(void)
-{
- return (_sd_ft_warm_start);
-}
-
-void
-_sdbc_clear_warm_start(void)
-{
- _sd_ft_warm_start = 0;
-}
-
-void
-_sdbc_set_warm_start(void)
-{
- _sd_ft_warm_start = 1;
-}
-
-/*ARGSUSED*/
-void
-_ncall_poke(int host)
-{
- cmn_err(CE_PANIC, " NYI - _ncall_poke");
-}
diff --git a/usr/src/uts/common/avs/ns/sdbc/sd_ft.h b/usr/src/uts/common/avs/ns/sdbc/sd_ft.h
deleted file mode 100644
index db8ce51187..0000000000
--- a/usr/src/uts/common/avs/ns/sdbc/sd_ft.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SD_FT_H
-#define _SD_FT_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/ncall/ncall.h>
-
-typedef struct _sd_ft_info {
- char fi_crashed; /* mirror cache state */
- char fi_host_state; /* mirror node state */
- kmutex_t fi_lock;
- kcondvar_t fi_rem_sv;
- volatile int fi_numio;
- kmutex_t fi_sleep;
-
-} _sd_ft_info_t;
-
-
-#define _SD_MIRROR_CONFIGD (_sd_ft_data.fi_host_state ==\
- _SD_HOST_CONFIGURED)
-#define _SD_MIRROR_DECONFIGD (_sd_ft_data.fi_host_state == \
- _SD_HOST_DECONFIGURED)
-#define _SD_MIRROR_NOCACHE (_sd_ft_data.fi_host_state == \
- _SD_HOST_NOCACHE)
-
-#define _SD_HOST_NONE 0x00 /* mirror node dead or state unknown */
-#define _SD_HOST_CONFIGURED 0x01 /* mirror cache configured */
-#define _SD_HOST_DECONFIGURED 0x02 /* mirror cache deconfigured */
-#define _SD_HOST_NOCACHE 0x03 /* mirror cache deconfigured and */
- /* waiting for node down or re-enable */
-
-/*
- * mirror node has paniced with cache enabled,
- * or mirror cache has been deconfigured.
- */
-#define _sd_is_mirror_crashed() ((!_INFSD_NODE_UP(_SD_MIRROR_HOST) &&\
- _SD_MIRROR_CONFIGD) || _SD_MIRROR_DECONFIGD)
-
-/*
- * mirror node has shutdown having previously
- * deconfigured its cache.
- */
-#define _sd_is_mirror_node_down() \
- (!_INFSD_NODE_UP(_SD_MIRROR_HOST) &&\
- _SD_MIRROR_NOCACHE)
-
-#define _sd_is_mirror_down() (_sd_ft_data.fi_crashed)
-#define _sd_mirror_cache_down() (_sd_ft_data.fi_crashed = 1,\
- _sd_ft_data.fi_host_state = _SD_HOST_NOCACHE)
-#define _sd_mirror_down() (_sd_ft_data.fi_crashed = 1,\
- _sd_ft_data.fi_host_state = _SD_HOST_NONE)
-#define _sd_mirror_up() (_sd_ft_data.fi_crashed = 0)
-#ifdef _KERNEL
-
-extern _sd_ft_info_t _sd_ft_data;
-extern int _sd_node_recovery;
-
-extern void _sdbc_ft_unload(void);
-extern int _sdbc_ft_load(void);
-extern int _sdbc_ft_configure(void);
-extern void _sdbc_ft_deconfigure(void);
-extern int _sd_recovery_wait(void);
-extern int _sd_recovery_wblk_wait(int cd);
-extern void _sd_mirror_iodone(void);
-extern int _sd_repin_cd(int);
-extern void _sd_remote_disable(int);
-extern void r_sd_ifs_cache_enable(ncall_t *, int *);
-extern void r_sd_ifs_cache_disable(ncall_t *, int *);
-extern void _sd_hash_invalidate_cd(int);
-extern void r_cd_discard(ncall_t *, int *);
-extern int _sd_uncommit(_sd_buf_handle_t *, nsc_off_t, nsc_size_t, int);
-extern int _sd_uncommit_refresh(_sd_cctl_t *, int);
-extern void r_sd_uncommit_refresh(ncall_t *, int *);
-extern int _sd_wait_for_flush(int);
-extern int _sdbc_warm_start(void);
-extern void _sdbc_set_warm_start(void);
-
-#endif /* _KERNEL */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SD_FT_H */
diff --git a/usr/src/uts/common/avs/ns/sdbc/sd_hash.c b/usr/src/uts/common/avs/ns/sdbc/sd_hash.c
deleted file mode 100644
index 93a4eac43a..0000000000
--- a/usr/src/uts/common/avs/ns/sdbc/sd_hash.c
+++ /dev/null
@@ -1,499 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/ksynch.h>
-#include <sys/cmn_err.h>
-#include <sys/kmem.h>
-#include <sys/ddi.h>
-#include <sys/nsc_thread.h>
-#include <sys/nsctl/nsctl.h>
-
-#include <sys/sdt.h> /* dtrace is S10 or later */
-
-#include "sd_bcache.h"
-#include "sd_hash.h"
-
-#if defined(_SD_DEBUG)
-int _sd_hash_max_inlist = 0;
-#endif
-
-
-#define _SD_HB_LOCKS 32
-static kmutex_t _sd_hb_locks[_SD_HB_LOCKS];
-
-
-/*
- * _sdbc_hash_load - allocate all the locks for buckets.
- *
- *
- */
-int
-_sdbc_hash_load(void)
-{
- int i;
- for (i = 0; i < _SD_HB_LOCKS; i++) {
- mutex_init(&_sd_hb_locks[i], NULL, MUTEX_DRIVER, NULL);
- }
- return (0);
-}
-
-/*
- * _sdbc_hash_unload - free all the locks for buckets.
- *
- *
- */
-void
-_sdbc_hash_unload(void)
-{
- int i;
- for (i = 0; i < _SD_HB_LOCKS; i++) {
- mutex_destroy(&_sd_hb_locks[i]);
- }
-}
-
-
-/*
- * _sdbc_hash_configure - create a hash table
- *
- * ARGUMENTS:
- * num_ents - Number of entries (or hash buckets)
- * htype - Type of memory to allocate.
- *
- * RETURNS:
- * The address of the hash table just created
- * or zero in the event of failure.
- *
- * USAGE:
- * This routine rounds of the number of entries to the next higher
- * power of 2. Allocate the hash buckets and initializes the locks
- * and returns the hash table that is created.
- * It is the caller's responsibility to save the hash_table and pass
- * it as a key for future accesses to the hash.
- * It is also the caller's responsibility to destroy the hash table
- * when appropriate.
- */
-
-
-_sd_hash_table_t *
-_sdbc_hash_configure(int num_ents)
-{
- _sd_hash_table_t *hash_table;
- _sd_hash_bucket_t *bucket;
- int i;
- int get_high_bit(int);
-
- if ((hash_table = (_sd_hash_table_t *)
- nsc_kmem_zalloc(sizeof (_sd_hash_table_t),
- KM_SLEEP, sdbc_hash_mem)) == NULL)
- return (NULL);
-
- hash_table->ht_bits = get_high_bit(num_ents);
- hash_table->ht_size = (1 << hash_table->ht_bits);
-
- /*
- * this is where we compute the mask used in the hash function
- * the ht_nmask is basically an not of ht_mask used in hash
- * function.
- */
- hash_table->ht_mask = (hash_table->ht_size - 1);
- hash_table->ht_nmask = (~0 & ~(hash_table->ht_mask));
-
- if ((hash_table->ht_buckets = (_sd_hash_bucket_t *)
- nsc_kmem_zalloc(hash_table->ht_size *
- sizeof (_sd_hash_bucket_t), KM_SLEEP,
- sdbc_hash_mem)) == NULL)
- return (NULL);
-
- for (i = 0; i < (hash_table->ht_size); i++) {
- bucket = (hash_table->ht_buckets + i);
-
- bucket->hb_lock = &_sd_hb_locks[i % _SD_HB_LOCKS];
- bucket->hb_head = bucket->hb_tail = NULL;
- bucket->hb_inlist = 0;
- }
-
- return (hash_table);
-}
-
-
-/*
- * _sdbc_hash_deconfigure - deconfigure a hash table
- *
- * ARGUMENTS:
- * hash_table - hash table that was created earlier on.
- *
- * RETURNS:
- * None.
- *
- * USAGE:
- * this routine deallocates memory that was allocated during the
- * hash create.
- */
-
-void
-_sdbc_hash_deconfigure(_sd_hash_table_t *hash_table)
-{
- if (!hash_table)
- return;
-
- nsc_kmem_free(hash_table->ht_buckets,
- hash_table->ht_size * sizeof (_sd_hash_bucket_t));
-
- nsc_kmem_free(hash_table, sizeof (_sd_hash_table_t));
-}
-
-static int _sd_forced_hash_miss;
-static int _sd_hash_collision;
-
-
-/*
- * _sd_hash_search - search the hash table for an entry
- *
- * ARGUMENTS:
- * cd - device that we are interested in.
- * block_num - block number we are interested in.
- * hash_table - hash table to search in.
- *
- * RETURNS:
- * returns a hash header if a match was found in the hash table
- * for the device & block_num.
- * Else returns 0.
- *
- * USAGE:
- * This routine is called to check if a block already exists for
- * the device, block_num combination. If the block does not exist,
- * then a new block needs to be allocated and inserted into the hash
- * table for future references.
- */
-
-_sd_hash_hd_t *
-_sd_hash_search(int cd, nsc_off_t block_num, _sd_hash_table_t *table)
-{
- int i;
- _sd_hash_bucket_t *bucket;
- _sd_hash_hd_t *hptr;
-#if defined(_SD_HASH_OPTIMIZE)
-#define MAX_HSEARCH_RETRIES 30
- int tries = 0;
- _sd_hash_hd_t *hnext;
- unsigned int seq;
-
- i = HASH(cd, block_num, table);
- bucket = (table->ht_buckets + i);
-retry_search:
- seq = bucket->hb_seq;
- for (hptr = bucket->hb_head; hptr; hptr = hnext) {
- /*
- * Save pointer for next before checking the seq counter.
- */
- hnext = hptr->hh_next;
- /*
- * enforce ordering of load of hptr->hh_next
- * above and bucket->hb_seq below
- */
- sd_serialize();
- if (bucket->hb_seq != seq) {
- /*
- * To avoid looping forever, break out if a certain
- * limit is reached. Its okay to return miss
- * since the insert will do a proper search.
- */
- if (++tries < MAX_HSEARCH_RETRIES) goto retry_search;
- else {
- _sd_forced_hash_miss++;
- DTRACE_PROBE1(_sd_hash_search_end,
- int, _sd_forced_hash_miss);
- return (NULL);
- }
- }
- if ((hptr->hh_cd == cd) && (hptr->hh_blk_num == block_num))
- break;
- if (hptr->hh_blk_num > block_num) {
- DTRACE_PROBE1(_sd_hash_search_end,
- _sd_hash_hd_t *, hptr);
- return (NULL);
- }
- }
-
- DTRACE_PROBE1(_sd_hash_search_end,
- _sd_hash_hd_t *, hptr);
- return (hptr);
-#else
-
- i = HASH(cd, block_num, table);
- bucket = (table->ht_buckets + i);
-
- mutex_enter(bucket->hb_lock);
-
- for (hptr = bucket->hb_head; hptr; hptr = hptr->hh_next) {
- if ((hptr->hh_cd == cd) && (hptr->hh_blk_num == block_num))
- break;
- /*
- * the list is ordered. If we go beyond our block, no
- * point searching
- */
- if (hptr->hh_blk_num > block_num) {
- hptr = NULL;
- break;
- }
- }
- mutex_exit(bucket->hb_lock);
-
- return (hptr);
-#endif
-}
-
-
-/*
- * _sd_hash_insert - insert an entry into the hash table
- *
- * ARGUMENTS:
- * cd - device that we are interested in.
- * block_num - block number we are interested in.
- * hptr - pointer to block that we are inserting.
- * table - hash table to search in.
- *
- * RETURNS:
- * Pointer to block that was passed in, except if the cd, block_num
- * already exists in the hash. Caller must check for return
- * not equal hptr.
- *
- * USAGE:
- * this routine inserts the hptr into the appropriate hash bucket and
- * sets the cd, block_num in the block for future references.
- */
-
-_sd_hash_hd_t *
-_sd_hash_insert(int cd,
- nsc_off_t block_num,
- _sd_hash_hd_t *hptr,
- _sd_hash_table_t *table)
-{
- int i;
- _sd_hash_hd_t *p;
- _sd_hash_bucket_t *bucket;
-
- i = HASH(cd, block_num, table);
- bucket = (table->ht_buckets + i);
-
-#if defined(_SD_DEBUG)
- if (hptr->hh_hashed) {
- cmn_err(CE_WARN, "_sd_err: hptr %p bucket %p already hashed",
- hptr, bucket);
- }
-#endif
- hptr->hh_cd = (ushort_t)cd;
- hptr->hh_blk_num = block_num;
-
- mutex_enter(bucket->hb_lock);
-
- for (p = bucket->hb_head; (p && (p->hh_blk_num <= block_num));
- p = p->hh_next) {
- if ((p->hh_cd == cd) && (p->hh_blk_num == block_num)) {
- mutex_exit(bucket->hb_lock);
- _sd_hash_collision++;
- DTRACE_PROBE2(_sd_hash_insert_end,
- _sd_hash_hd_t *, p,
- int, _sd_hash_collision);
-
- return (p);
- }
- }
- hptr->hh_hashed = 1;
- /*
- * At this point, (p) points to the next higher block number or is
- * NULL. If it is NULL, we are queueing to the tail of list.
- * Else, insert just before p
- */
- if (p) {
- hptr->hh_next = p;
- if ((hptr->hh_prev = p->hh_prev) != NULL)
- p->hh_prev->hh_next = hptr;
- else
- bucket->hb_head = hptr;
- p->hh_prev = hptr;
- } else {
- hptr->hh_next = NULL;
- hptr->hh_prev = bucket->hb_tail;
- if (bucket->hb_head)
- bucket->hb_tail->hh_next = hptr;
- else
- bucket->hb_head = hptr;
- bucket->hb_tail = hptr;
- }
-#if defined(_SD_HASH_OPTIMIZE)
- bucket->hb_seq++;
-#endif
-#if defined(_SD_DEBUG)
- if (_sd_hash_max_inlist < (int)++(bucket->hb_inlist))
- _sd_hash_max_inlist = bucket->hb_inlist;
-#endif
- mutex_exit(bucket->hb_lock);
-
- return (hptr);
-}
-
-
-
-/*
- * _sd_hash_delete - delete an entry from the hash table
- *
- * ARGUMENTS:
- * hptr - pointer to delete from hash table.
- * hash_table - hash table that was created earlier on.
- *
- * RETURNS:
- * 0 on success. -1 on errors.
- *
- * USAGE:
- * this routine deletes a hash entry from the hash table.
- */
-
-int
-_sd_hash_delete(_sd_hash_hd_t *hptr, _sd_hash_table_t *table)
-{
- int i;
- _sd_hash_bucket_t *bucket;
-
- if (hptr->hh_hashed == 0) {
- DTRACE_PROBE(_sd_hash_delete_end1);
- return (-1);
- }
-
- i = HASH(hptr->hh_cd, hptr->hh_blk_num, table);
- bucket = (table->ht_buckets + i);
-
- /* was FAST */
- mutex_enter(bucket->hb_lock);
- if (hptr->hh_hashed == 0) {
- /* was FAST */
- mutex_exit(bucket->hb_lock);
- DTRACE_PROBE(_sd_hash_delete_end2);
- return (-1);
- }
- hptr->hh_hashed = 0;
-#if defined(_SD_HASH_OPTIMIZE)
- /*
- * Increment sequence counter on bucket. This will signal a lookup
- * to redo the lookup since we might have broken the link used
- * during the lookup.
- */
- bucket->hb_seq++;
-#endif
-
- if (hptr->hh_prev)
- hptr->hh_prev->hh_next = hptr->hh_next;
- else
- bucket->hb_head = hptr->hh_next;
- if (hptr->hh_next)
- hptr->hh_next->hh_prev = hptr->hh_prev;
- else
- bucket->hb_tail = hptr->hh_prev;
-#if defined(_SD_DEBUG)
- bucket->hb_inlist--;
-#endif
- /* was FAST */
- mutex_exit(bucket->hb_lock);
-
- return (0);
-}
-
-/*
- * _sd_hash_replace - replace 'old' with 'new' entry.
- *
- * ARGUMENTS:
- * old - pointer to block being deleted (to be anonymous)
- * new - pointer to block inserting in place.
- * table - hash table to search in.
- *
- * RETURNS:
- * pointer to inserted block.
- *
- * USAGE:
- * expects old & new to refer to same block.
- * new must not be already hashed.
- */
-
-_sd_hash_hd_t *
-_sd_hash_replace(_sd_hash_hd_t *old, _sd_hash_hd_t *new,
- _sd_hash_table_t *table)
-{
- int i;
- _sd_hash_bucket_t *bucket;
-
- if ((old->hh_cd != new->hh_cd) || (old->hh_blk_num != new->hh_blk_num))
- cmn_err(CE_PANIC, "_sd_hash_replace: mismatch %p %p",
- (void *)old, (void *)new);
- if (new->hh_hashed)
- cmn_err(CE_PANIC, "_sd_hash_replace: new %p already hashed",
- (void *)new);
- if (old->hh_hashed == 0) {
- _sd_hash_hd_t *hptr;
- hptr = _sd_hash_insert(new->hh_cd, new->hh_blk_num, new, table);
-
- DTRACE_PROBE1(_sd_hash_replace_end,
- _sd_hash_hd_t *, hptr);
-
- return (hptr);
- }
-
- i = HASH(old->hh_cd, old->hh_blk_num, table);
- bucket = (table->ht_buckets + i);
-
- /* was FAST */
- mutex_enter(bucket->hb_lock);
- if (old->hh_hashed == 0) {
- _sd_hash_hd_t *hptr;
- /* was FAST */
- mutex_exit(bucket->hb_lock);
-
- hptr = _sd_hash_insert(new->hh_cd, new->hh_blk_num, new, table);
-
- DTRACE_PROBE1(_sd_hash_replace_end,
- _sd_hash_hd_t *, hptr);
- return (hptr);
- }
- old->hh_hashed = 0;
- new->hh_hashed = 1;
- new->hh_prev = old->hh_prev;
- new->hh_next = old->hh_next;
-
- if (new->hh_prev)
- new->hh_prev->hh_next = new;
- else
- bucket->hb_head = new;
- if (new->hh_next)
- new->hh_next->hh_prev = new;
- else
- bucket->hb_tail = new;
-#if defined(_SD_HASH_OPTIMIZE)
- bucket->hb_seq++;
-#endif
- /* was FAST */
- mutex_exit(bucket->hb_lock);
-
- return (new);
-}
diff --git a/usr/src/uts/common/avs/ns/sdbc/sd_hash.h b/usr/src/uts/common/avs/ns/sdbc/sd_hash.h
deleted file mode 100644
index fa57dc0f90..0000000000
--- a/usr/src/uts/common/avs/ns/sdbc/sd_hash.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SD_HASH_H
-#define _SD_HASH_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/nsctl/nsctl.h>
-
-#if defined(_KERNEL) || defined(_KMEMUSER)
-
-typedef struct _sd_hash_hd {
- unsigned short hh_hashed; /* Is this block in hash */
- unsigned short hh_cd; /* The cache descriptor */
- nsc_off_t hh_blk_num; /* Cache block number */
- struct _sd_hash_hd *hh_prev; /* for chaining withing */
- struct _sd_hash_hd *hh_next; /* hash table */
-} _sd_hash_hd_t;
-
-
-typedef struct _sd_hash_bucket {
- struct _sd_hash_hd *hb_head;
- struct _sd_hash_hd *hb_tail;
- kmutex_t *hb_lock;
- unsigned short hb_inlist;
- volatile unsigned int hb_seq;
-} _sd_hash_bucket_t;
-
-
-typedef struct _sd_hash_table {
- int ht_size;
- int ht_bits;
- int ht_mask;
- int ht_nmask;
- struct _sd_hash_bucket *ht_buckets;
-} _sd_hash_table_t;
-
-
-#endif /* _KERNEL && _KMEMUSER */
-
-
-#if defined(_KERNEL)
-
-#define HASH(cd, blk, table) \
- (((cd << 6) ^ ((blk) ^ ((blk) >> table->ht_bits))) \
- & (table->ht_mask))
-
-#define HT_SEARCH 0
-#define HT_NOSEARCH 1
-
-extern int _sdbc_hash_load(void);
-extern void _sdbc_hash_unload(void);
-extern _sd_hash_table_t *_sdbc_hash_configure(int num_ents);
-extern void _sdbc_hash_deconfigure(_sd_hash_table_t *hash_table);
-extern _sd_hash_hd_t *_sd_hash_search(int cd, nsc_off_t block_num,
- _sd_hash_table_t *table);
-extern _sd_hash_hd_t *_sd_hash_insert(int cd, nsc_off_t block_num,
- _sd_hash_hd_t *hptr, _sd_hash_table_t *table);
-extern int _sd_hash_delete(_sd_hash_hd_t *hptr, _sd_hash_table_t *table);
-extern _sd_hash_hd_t *_sd_hash_replace(_sd_hash_hd_t *old, _sd_hash_hd_t *new,
- _sd_hash_table_t *table);
-#endif /* _KERNEL */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SD_HASH_H */
diff --git a/usr/src/uts/common/avs/ns/sdbc/sd_io.c b/usr/src/uts/common/avs/ns/sdbc/sd_io.c
deleted file mode 100644
index 05884467a9..0000000000
--- a/usr/src/uts/common/avs/ns/sdbc/sd_io.c
+++ /dev/null
@@ -1,2009 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/ksynch.h>
-#include <sys/cmn_err.h>
-#include <sys/kmem.h>
-#include <sys/buf.h>
-#include <sys/cred.h>
-#include <sys/errno.h>
-#include <sys/ddi.h>
-
-#include <sys/nsc_thread.h>
-#include <sys/nsctl/nsctl.h>
-
-#include <sys/sdt.h> /* dtrace is S10 or later */
-
-#include "sd_bcache.h"
-#include "sd_trace.h"
-#include "sd_io.h"
-#include "sd_bio.h"
-#include "sd_misc.h"
-#include "sd_ft.h"
-#include "sd_pcu.h"
-
-/*
- * dynamic memory support
- */
-_dm_process_vars_t dynmem_processing_dm;
-static int sd_dealloc_flag_dm = NO_THREAD_DM;
-static void _sd_dealloc_dm(void);
-static int _sd_entry_availability_dm(_sd_cctl_t *cc_ent, int *nodata);
-
-extern void sdbc_requeue_dmchain(_sd_queue_t *, _sd_cctl_t *, int, int);
-extern void sdbc_ins_dmqueue_front(_sd_queue_t *q, _sd_cctl_t *cc_ent);
-extern void sdbc_remq_dmchain(_sd_queue_t *q, _sd_cctl_t *cc_ent);
-extern void sdbc_requeue_head_dm_try(_sd_cctl_t *);
-extern int sdbc_use_dmchain;
-extern _sd_queue_t *sdbc_dm_queues;
-
-kcondvar_t _sd_flush_cv;
-static volatile int _sd_flush_exit;
-
-/* secret flush toggle flag for testing */
-#ifdef DEBUG
-int _sdbc_flush_flag = 1; /* 0 ==> noflushing, 1 ==> flush */
-#endif
-
-static int sdbc_flush_pageio;
-
-
-
-/*
- * Forward declare all statics that are used before defined to enforce
- * parameter checking
- * Some (if not all) of these could be removed if the code were reordered
- */
-
-static void _sd_flcent_ea(blind_t xcc_ent, nsc_off_t fba_pos,
- nsc_size_t fba_len, int error);
-static void _sd_flclist_ea(blind_t xcc_ent, nsc_off_t fba_pos,
- nsc_size_t fba_len, int error);
-static void _sd_process_reflush(_sd_cctl_t *cc_ent);
-static void _sd_flush_thread(void);
-
-int
-_sdbc_flush_configure(void)
-{
- _sd_flush_exit = 1;
- sdbc_flush_pageio = 0;
- return (nsc_create_process(
- (void (*)(void *))_sd_flush_thread, 0, TRUE));
-}
-
-
-void
-_sdbc_flush_deconfigure(void)
-{
- _sd_unblock(&_sd_flush_cv);
- _sd_flush_exit = 0;
-}
-
-static int
-sdbc_alloc_static_cache(int reqblks)
-{
- _sd_cctl_t *centry;
- _sd_cctl_t *next_centry;
-
- if (centry = sdbc_centry_alloc_blks(_CD_NOHASH, 0, reqblks,
- ALLOC_NOWAIT)) {
- /* release the blocks to the queue */
- while (centry) {
- next_centry = centry->cc_chain;
- _sd_centry_release(centry);
- centry = next_centry;
- }
- return (reqblks);
- }
- return (0);
-}
-
-int
-_sdbc_dealloc_configure_dm(void)
-{
- int rc = 0;
- int reqblks = MEGABYTE/BLK_SIZE(1); /* alloc in mb chunks */
- int i;
- int blk_groups; /* number of ~MB groups */
- int blks_remaining;
- int blks_allocd = 0;
-
- dynmem_processing_dm.alloc_ct = 0;
- dynmem_processing_dm.dealloc_ct = 0;
-
- if (sdbc_static_cache) { /* alloc all static cache memory here */
- dynmem_processing_dm.max_dyn_list = reqblks;
-
- blk_groups = CBLOCKS / reqblks;
- blks_remaining = CBLOCKS % reqblks;
-
- for (i = 0; i < blk_groups; ++i) {
- if (!sdbc_alloc_static_cache(reqblks))
- break;
- blks_allocd += reqblks;
- }
- DTRACE_PROBE2(_sdbc_dealloc_configure_dm1,
- int, i, int, blks_allocd);
-
- /* if successful then allocate any remaining blocks */
- if ((i == blk_groups) && blks_remaining)
- if (sdbc_alloc_static_cache(blks_remaining))
- blks_allocd += blks_remaining;
-
- DTRACE_PROBE2(_sdbc_dealloc_configure_dm2,
- int, i, int, blks_allocd);
-
- sd_dealloc_flag_dm = NO_THREAD_DM;
-
- if (blks_allocd < CBLOCKS) {
- cmn_err(CE_WARN, "!Failed to allocate sdbc cache "
- "memory.\n requested mem: %d MB; actual mem: %d MB",
- CBLOCKS/reqblks, blks_allocd/reqblks);
- rc = ENOMEM;
- }
-
-
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!sdbc(_sdbc_dealloc_configure_dm) %d bytes "
- "(%d cache blocks) allocated for static cache, "
- "block size %d", blks_allocd * BLK_SIZE(1), blks_allocd,
- BLK_SIZE(1));
-#endif /* DEBUG */
- } else {
- sd_dealloc_flag_dm = PROCESS_CACHE_DM;
- rc = nsc_create_process((void (*)(void *))_sd_dealloc_dm, 0,
- TRUE);
- if (rc != 0)
- sd_dealloc_flag_dm = NO_THREAD_DM;
- }
- return (rc);
-}
-
-/*
- * sdbc_dealloc_dm_shutdown - deallocate cache memory.
- *
- * ARGUMENTS: none
- *
- * RETURNS: nothing
- *
- * USAGE:
- * this function is intended for use after all i/o has stopped and all
- * other cache threads have terminated. write cache resources, if any
- * are released, except in the case of pinned data.
- */
-static void
-sdbc_dealloc_dm_shutdown()
-{
- _sd_cctl_t *cc_ent;
- ss_centry_info_t *wctl;
-
- cc_ent = _sd_cctl[0];
-
- if (!cc_ent)
- return;
-
- do {
- if (cc_ent->cc_alloc_size_dm) {
- /* HOST or OTHER */
-
- if (cc_ent->cc_data)
- kmem_free(cc_ent->cc_data,
- cc_ent->cc_alloc_size_dm);
-
- cc_ent->cc_alloc_size_dm = 0;
-
- dynmem_processing_dm.dealloc_ct++;
-
- DTRACE_PROBE2(sdbc_dealloc_dm_shutdown, char *,
- cc_ent->cc_data, int, cc_ent->cc_alloc_size_dm);
- }
-
- /* release safestore resource, if any. preserve pinned data */
- if (!(CENTRY_DIRTY(cc_ent)) && (wctl = cc_ent->cc_write)) {
- wctl->sc_flag = 0;
- wctl->sc_dirty = 0;
-
- SSOP_SETCENTRY(sdbc_safestore, wctl);
- SSOP_DEALLOCRESOURCE(sdbc_safestore, wctl->sc_res);
- }
- cc_ent = cc_ent->cc_link_list_dm;
- } while (cc_ent != _sd_cctl[0]);
-}
-
-void
-_sdbc_dealloc_deconfigure_dm(void)
-{
- int one_sec;
-
- if (sdbc_static_cache) {
- sdbc_dealloc_dm_shutdown();
- return;
- }
-
- if (sd_dealloc_flag_dm == NO_THREAD_DM)
- return; /* thread never started */
- one_sec = HZ; /* drv_usectohz(1000000); */
-
- mutex_enter(&dynmem_processing_dm.thread_dm_lock);
- sd_dealloc_flag_dm = CACHE_SHUTDOWN_DM;
- cv_broadcast(&dynmem_processing_dm.thread_dm_cv);
- mutex_exit(&dynmem_processing_dm.thread_dm_lock);
-
- while (sd_dealloc_flag_dm != CACHE_THREAD_TERMINATED_DM)
- delay(one_sec);
-
- sd_dealloc_flag_dm = NO_THREAD_DM;
-}
-
-/*
- * This complicated - possibly overly complicated routine works as follows:
- * In general the routine sleeps a specified amount of time then wakes and
- * examines the entire centry list. If an entry is avail. it ages it by one
- * tick else it clears the aging flag completely. It then determines if the
- * centry has aged sufficiently to have its memory deallocated and for it to
- * be placed at the top of the lru.
- *
- * There are two deallocation schemes in place depending on whether the
- * centry is a standalone entry or it is a member of a host/parasite chain.
- *
- * The behavior for a standalone entry is as follows:
- * If the given centry is selected it will age normally however at full
- * aging it will only be placed at the head of the lru. It's memory will
- * not be deallocated until a further aging level has been reached. The
- * entries selected for this behavior are goverend by counting the number
- * of these holdovers in existence on each wakeup and and comparing it
- * to a specified percentage. This comparision is always one cycle out of
- * date and will float in the relative vicinity of the specified number.
- *
- * The behavior for a host/parasite chain is as follows:
- * The chain is examined. If all entries are fully aged the entire chain
- * is removed - ie mem is dealloc. from the host entry and all memory ref.
- * removed from the parasitic entries and each entry requeued on to the lru.
- *
- * There are three delay timeouts and two percentage levels specified. Timeout
- * level 1 is honored between 100% free and pcnt level 1. Timeout level 2 is
- * honored between pcnt level 1 and pcnt level 2, Timeout level 3 is
- * honored between pcnt level 2 and 0% free. In addition there exist an
- * accelerated
- * aging flag which mimics hysterisis behavior. If the available centrys fall
- * between pcnt1 and pcnt2 an 8 bit counter is switched on. The effect is to
- * keep the timer value at timer level 2 for 8 cycles even if the number
- * available cache entries drifts above pcnt1. If it falls below pcnt2 an
- * additional 8 bit counter is switched on. This causes the sleep timer to
- * remain at timer level 3 for at least 8 cycles even if it floats above
- * pcnt2 or even pcnt1. The effect of all this is to accelerate the release
- * of system resources under a heavy load.
- *
- * All of the footwork can be stubbed out by a judicious selection of values
- * for the times, aging counts and pcnts.
- *
- * All of these behavior parameters are adjustable on the fly via the kstat
- * mechanism. In addition there is a thread wakeup msg available through the
- * same mechanism.
- */
-
-static void
-_sd_dealloc_dm(void)
-{
- int one_sec_tics, tic_delay;
- int sleep_tics_lvl1, sleep_tics_lvl2, sleep_tics_lvl3;
- int transition_lvl1, transition_lvl2;
- int host_cache_aging_ct, meta_cache_aging_ct, hold_cache_aging_ct;
- int max_holds_ct;
- int cache_aging_ct, hold_candidate, last_holds_ct;
- _sd_cctl_t *cc_ent, *next_ccentry, *cur_ent, *nxt_ent;
- ss_centry_info_t *wctl;
- int current_breakout_count, number_cache_entries;
- int dealloc;
- _dm_process_vars_t *ppvars;
-
- int write_dealloc; /* remove after debugging */
-
- ppvars = &dynmem_processing_dm;
-
- /* setup a one sec time var */
- one_sec_tics = HZ; /* drv_usectohz(1000000); */
-
- ppvars->history = 0;
-
- cc_ent = _sd_cctl[0];
-
- number_cache_entries = _sd_net_config.sn_cpages;
-
- last_holds_ct = 0;
-
- /*CONSTANTCONDITION*/
- while (1) {
- if (sd_dealloc_flag_dm == CACHE_SHUTDOWN_DM) {
- /* finished. shutdown - get out */
- sdbc_dealloc_dm_shutdown(); /* free all memory */
- sd_dealloc_flag_dm = CACHE_THREAD_TERMINATED_DM;
- return;
- }
-
- /* has the world changed */
-
- /*
- * get num cctl entries (%) below which different sleep
- * rates kick in
- */
- transition_lvl1 =
- (ppvars->cache_aging_pcnt1*number_cache_entries) / 100;
- transition_lvl2 =
- (ppvars->cache_aging_pcnt2*number_cache_entries) / 100;
-
- /* get sleep rates for each level */
- sleep_tics_lvl1 = ppvars->cache_aging_sec1 * one_sec_tics;
- sleep_tics_lvl2 = ppvars->cache_aging_sec2 * one_sec_tics;
- sleep_tics_lvl3 = ppvars->cache_aging_sec3 * one_sec_tics;
-
- /* get num of cycles for full normal aging */
- host_cache_aging_ct = ppvars->cache_aging_ct1;
-
- /* get num of cycles for full meta aging */
- meta_cache_aging_ct = ppvars->cache_aging_ct2;
-
- /* get num of cycles for full extended holdover aging */
- hold_cache_aging_ct = ppvars->cache_aging_ct3;
-
- /* get maximum holds count in % */
- max_holds_ct = (ppvars->max_holds_pcnt*number_cache_entries)
- / 100;
-
- /* apply the delay */
- tic_delay = sleep_tics_lvl1;
- if (sd_dealloc_flag_dm == TIME_DELAY_LVL1)
- tic_delay = sleep_tics_lvl2;
- else
- if (sd_dealloc_flag_dm == TIME_DELAY_LVL2)
- tic_delay = sleep_tics_lvl3;
-
- mutex_enter(&ppvars->thread_dm_lock);
- (void) cv_reltimedwait(&ppvars->thread_dm_cv,
- &ppvars->thread_dm_lock, tic_delay, TR_CLOCK_TICK);
- mutex_exit(&ppvars->thread_dm_lock);
-
- /* check for special directives on wakeup */
- if (ppvars->process_directive &
- MAX_OUT_ACCEL_HIST_FLAG_DM) {
- ppvars->process_directive &=
- ~MAX_OUT_ACCEL_HIST_FLAG_DM;
- ppvars->history =
- (HISTORY_LVL1|HISTORY_LVL2);
- }
-
- /* Start of deallocation loop */
- current_breakout_count = 0;
-
- ppvars->nodatas = 0;
- write_dealloc = 0;
- ppvars->deallocs = 0;
- ppvars->candidates = 0;
- ppvars->hosts = 0;
- ppvars->pests = 0;
- ppvars->metas = 0;
- ppvars->holds = 0;
- ppvars->others = 0;
- ppvars->notavail = 0;
-
- while (sd_dealloc_flag_dm != CACHE_SHUTDOWN_DM &&
- current_breakout_count < number_cache_entries) {
-
- next_ccentry = cc_ent->cc_link_list_dm;
-
- if (_sd_entry_availability_dm(cc_ent, &ppvars->nodatas)
- == FALSE) {
- ppvars->notavail++;
- goto next_dealloc_entry;
- }
-
- cache_aging_ct = host_cache_aging_ct;
- hold_candidate = FALSE;
- if (cc_ent->cc_aging_dm & HOST_ENTRY_DM)
- ppvars->hosts++;
- else
- if (cc_ent->cc_aging_dm & PARASITIC_ENTRY_DM)
- ppvars->pests++;
- else
- if (cc_ent->cc_aging_dm & STICKY_METADATA_DM) {
- cache_aging_ct = meta_cache_aging_ct;
- ppvars->metas++;
- } else {
- if (last_holds_ct < max_holds_ct)
- hold_candidate = TRUE;
- ppvars->others++;
- }
-
- ppvars->candidates++;
-
- if ((cc_ent->cc_aging_dm & FINAL_AGING_DM) <
- cache_aging_ct) {
- cc_ent->cc_aging_dm += FIRST_AGING_DM;
- CLEAR_CENTRY_PAGEIO(cc_ent);
- CLEAR_CENTRY_INUSE(cc_ent);
- goto next_dealloc_entry;
- }
-
- /* bonafide aged entry - examine its chain */
- dealloc = TRUE;
- cur_ent = cc_ent->cc_head_dm;
- while (cur_ent) {
- if (cur_ent == cc_ent)
- cur_ent->cc_aging_dm |= AVAIL_ENTRY_DM;
- else {
- if (_sd_entry_availability_dm(cur_ent,
- 0) == TRUE) {
- cur_ent->cc_aging_dm |=
- AVAIL_ENTRY_DM;
- if ((cur_ent->cc_aging_dm &
- FINAL_AGING_DM) <
- cache_aging_ct)
- dealloc = FALSE;
- } else
- dealloc = FALSE;
- }
-
- cur_ent = cur_ent->cc_next_dm;
- }
- cur_ent = cc_ent->cc_head_dm;
-
- /* chain not fully free - free inuse for all entries */
- if (dealloc == FALSE) {
- while (cur_ent) {
- nxt_ent = cur_ent->cc_next_dm;
-
- if (cur_ent->cc_aging_dm &
- AVAIL_ENTRY_DM) {
- cur_ent->cc_aging_dm &=
- ~AVAIL_ENTRY_DM;
- CLEAR_CENTRY_PAGEIO(cur_ent);
- CLEAR_CENTRY_INUSE(cur_ent);
- }
- cur_ent = nxt_ent;
- }
- } else { /* OK - free memory */
- if (hold_candidate == TRUE &&
- (cur_ent->cc_aging_dm & FINAL_AGING_DM) <
- hold_cache_aging_ct) {
- ppvars->holds++;
-
- ASSERT(cur_ent == cc_ent);
-
- cc_ent->cc_aging_dm += FIRST_AGING_DM;
-
- cur_ent->cc_aging_dm &= ~AVAIL_ENTRY_DM;
-
- wctl = cur_ent->cc_write;
-
- CLEAR_CENTRY_PAGEIO(cur_ent);
- CLEAR_CENTRY_INUSE(cur_ent);
-
- if (wctl) {
- write_dealloc++;
- wctl->sc_flag = 0;
- wctl->sc_dirty = 0;
- SSOP_SETCENTRY(sdbc_safestore,
- wctl);
- SSOP_DEALLOCRESOURCE(
- sdbc_safestore,
- wctl->sc_res);
- }
- goto next_dealloc_entry;
- } /* if (hold_candidate == TRUE */
-
- while (cur_ent) {
-
- DTRACE_PROBE4(_sd_dealloc_dm,
- _sd_cctl_t *, cur_ent,
- int, CENTRY_CD(cur_ent),
- int, CENTRY_BLK(cur_ent),
- uint_t, cur_ent->cc_aging_dm);
-
- if ((cur_ent->cc_aging_dm
- & BAD_CHAIN_DM)) {
- (void) _sd_hash_delete(
- (_sd_hash_hd_t *)cur_ent,
- _sd_htable);
-
- nxt_ent = cur_ent->cc_next_dm;
- CLEAR_CENTRY_PAGEIO(cur_ent);
- CLEAR_CENTRY_INUSE(cur_ent);
- cur_ent = nxt_ent;
- continue;
- }
-
- ppvars->deallocs++;
-
- if (cur_ent->cc_alloc_size_dm) {
- int qidx;
- _sd_queue_t *q;
-
- /* HOST or OTHER */
-
- /* debugging */
- ppvars->dealloc_ct++;
- cur_ent->cc_dealloc_ct_dm++;
- kmem_free(cur_ent->cc_data,
- cur_ent->cc_alloc_size_dm);
-
- /*
- * remove from queue
- * in preparation for putting
- * on the 0 queue after
- * memory is freed
- */
- if (sdbc_use_dmchain) {
-
- qidx =
- cur_ent->cc_cblocks;
- q = &sdbc_dm_queues
- [qidx];
-
- sdbc_remq_dmchain(q,
- cur_ent);
- }
- }
-
- wctl = cur_ent->cc_write;
- cur_ent->cc_write = 0;
- cur_ent->cc_data = 0;
- cur_ent->cc_alloc_size_dm = 0;
- cur_ent->cc_head_dm = NULL;
- cur_ent->cc_aging_dm &=
- ~(FINAL_AGING_DM | ENTRY_FIELD_DM |
- CATAGORY_ENTRY_DM | AVAIL_ENTRY_DM |
- PREFETCH_BUF_I | PREFETCH_BUF_E);
-
- (void) _sd_hash_delete(
- (_sd_hash_hd_t *)cur_ent,
- _sd_htable);
- cur_ent->cc_valid = 0;
-
- if (sdbc_use_dmchain) {
- _sd_queue_t *q;
-
- nxt_ent = cur_ent->cc_next_dm;
-
- cur_ent->cc_next_dm = NULL;
-
- CLEAR_CENTRY_PAGEIO(cur_ent);
- CLEAR_CENTRY_INUSE(cur_ent);
-
- q = &sdbc_dm_queues[0];
- sdbc_ins_dmqueue_front(q,
- cur_ent);
- } else {
- _sd_requeue_head(cur_ent);
-
- nxt_ent = cur_ent->cc_next_dm;
- cur_ent->cc_next_dm = NULL;
-
- CLEAR_CENTRY_PAGEIO(cur_ent);
- CLEAR_CENTRY_INUSE(cur_ent);
- }
-
- cur_ent = nxt_ent;
-
- if (wctl) {
- write_dealloc++;
- wctl->sc_flag = 0;
- wctl->sc_dirty = 0;
- SSOP_SETCENTRY(sdbc_safestore,
- wctl);
- SSOP_DEALLOCRESOURCE(
- sdbc_safestore,
- wctl->sc_res);
- }
- } /* while (cur_ent) */
- } /* else OK - free memory */
-next_dealloc_entry:
- current_breakout_count++;
-
- cc_ent = next_ccentry;
- } /* while (entries) */
-
- if (ppvars->monitor_dynmem_process & RPT_DEALLOC_STATS1_DM) {
- cmn_err(CE_NOTE,
- "!notavl=%x, nodat=%x, cand=%x, hosts=%x,"
- " pests=%x, metas=%x, holds=%x, others=%x,"
- " deallo=%x",
- ppvars->notavail, ppvars->nodatas,
- ppvars->candidates, ppvars->hosts, ppvars->pests,
- ppvars->metas, ppvars->holds, ppvars->others,
- ppvars->deallocs);
- }
-
- if (ppvars->monitor_dynmem_process & RPT_DEALLOC_STATS2_DM) {
- cmn_err(CE_NOTE,
- "!hist=%x, gross a/d=%x %x", ppvars->history,
- ppvars->alloc_ct, ppvars->dealloc_ct);
- }
-
- if (sd_dealloc_flag_dm == CACHE_SHUTDOWN_DM)
- continue;
-
- last_holds_ct = ppvars->holds;
-
- /* set the history flag which will govern the sleep rate */
- if (ppvars->nodatas > transition_lvl1) {
- /* upper - lots of virgin cctls */
- if (ppvars->history)
- ppvars->history >>= 1;
- } else {
- if (ppvars->nodatas > transition_lvl2) {
- /* middle - not so many virgin cctls */
- if (ppvars->history & (HISTORY_LVL1-1))
- ppvars->history >>= 1;
- else
- ppvars->history = HISTORY_LVL1;
-
- } else {
- /*
- * appear to be running low - accelerate the
- * aging to free more
- */
- if (ppvars->history & HISTORY_LVL2)
- ppvars->history >>= 1;
- else
- ppvars->history =
- (HISTORY_LVL1|HISTORY_LVL2);
- }
- }
-
- sd_dealloc_flag_dm = TIME_DELAY_LVL0;
- if (ppvars->history & HISTORY_LVL2)
- sd_dealloc_flag_dm = TIME_DELAY_LVL2;
- else
- if (ppvars->history & HISTORY_LVL1)
- sd_dealloc_flag_dm = TIME_DELAY_LVL1;
-
- } /* while (TRUE) */
-}
-
-int
-_sd_entry_availability_dm(_sd_cctl_t *cc_ent, int *nodata)
-{
- /*
- * if using dmchaining return immediately and do not attempt
- * to acquire the cc_ent if there is no memory associated with
- * this cc_ent.
- * this avoids conflicts for centrys on the 0 queue.
- * see sdbc_get_dmchain()
- */
-
- if ((sdbc_use_dmchain) && (cc_ent->cc_data == 0)) {
-
- if (nodata)
- (*nodata)++;
-
- DTRACE_PROBE(sdbc_availability_dm_end1);
- return (FALSE);
- }
-
- if ((SET_CENTRY_INUSE(cc_ent))) {
-
- DTRACE_PROBE(sdbc_availability_dm_end2);
-
- return (FALSE);
- }
-
-
- if ((SET_CENTRY_PAGEIO(cc_ent))) {
-
- CLEAR_CENTRY_INUSE(cc_ent);
-
- DTRACE_PROBE(sdbc_availability_dm_end3);
-
- return (FALSE);
- }
-
- /*
- * we allow the QHEAD flag as it does not affect the availabilty
- * of memory for aging
- */
- if ((CENTRY_DIRTY(cc_ent)) || (CENTRY_IO_INPROGRESS(cc_ent)) ||
- (cc_ent->cc_flag & ~(CC_QHEAD)) ||
- cc_ent->cc_dirty_next || cc_ent->cc_dirty_link ||
- cc_ent->cc_data == 0) {
-
- cc_ent->cc_aging_dm &= ~FINAL_AGING_DM;
- if (nodata)
- if (cc_ent->cc_data == 0) {
- (*nodata)++;
- }
-
- CLEAR_CENTRY_PAGEIO(cc_ent);
- CLEAR_CENTRY_INUSE(cc_ent);
-
- DTRACE_PROBE(sdbc_availability_dm_end4);
-
- return (FALSE);
- }
-
- return (TRUE);
-}
-
-/*
- * function below to prohibit code movement by compiler
- * and avoid using spinlocks for syncronization
- */
-static void
-_sd_cc_iostatus_initiate(_sd_cctl_t *cc_ent)
-{
- cc_ent->cc_iostatus = _SD_IO_INITIATE;
- sd_serialize();
-}
-
-/*
- * Yet another switch!
- * alloc mem and coalesce if at least this number of frags
- */
-static int sdbc_coalesce_backend = 1;
-
-/*
- * optimization for _sd_async_flclist()
- * called only if not doing pageio and sdbc_coalesce_backend > 0
- *
- * returns with pagio bit set in the centrys in list
- */
-static unsigned char *
-sdbc_alloc_io_mem(_sd_cctl_t *cc_ent, int first_dirty, int last_dirty)
-{
- unsigned char *prev_addr = NULL;
- _sd_cctl_t *cc_ent_orig = cc_ent;
- int fba_len;
- int total_len_bytes = 0;
- unsigned char *start_addr = NULL; /* function return value */
- unsigned char *next_addr;
- int num_frags = 0;
-
- if (first_dirty && (!_SD_BMAP_ISFULL(first_dirty))) {
- WAIT_CENTRY_PAGEIO(cc_ent, sdbc_flush_pageio);
-
- fba_len = SDBC_LOOKUP_LEN(first_dirty);
- total_len_bytes += FBA_SIZE(fba_len);
-
- prev_addr = cc_ent->cc_data;
- cc_ent = cc_ent->cc_dirty_next;
- }
-
- while (cc_ent) {
-
- WAIT_CENTRY_PAGEIO(cc_ent, sdbc_flush_pageio);
- /* check for contiguity */
- if (prev_addr &&
- !((prev_addr + CACHE_BLOCK_SIZE) == cc_ent->cc_data))
- ++num_frags;
-
- /* compute length */
- if (FULLY_DIRTY(cc_ent)) {
- total_len_bytes += CACHE_BLOCK_SIZE;
- } else {
- fba_len = SDBC_LOOKUP_LEN(last_dirty);
- total_len_bytes += FBA_SIZE(fba_len);
- }
-
- prev_addr = cc_ent->cc_data;
- cc_ent = cc_ent->cc_dirty_next;
- }
-
- if (num_frags >= sdbc_coalesce_backend) {
- /*
- * TODO - determine metric for deciding
- * whether to coalesce memory or do separate i/o's
- */
-
- DTRACE_PROBE(sdbc_io_mem_kmem_start);
-
- if (start_addr = kmem_alloc(total_len_bytes, KM_NOSLEEP)) {
- int sblk, offset;
-
- cc_ent = cc_ent_orig;
-
- cc_ent->cc_anon_addr.sa_virt = start_addr;
- cc_ent->cc_anon_len = total_len_bytes;
-
- next_addr = start_addr;
-
- DTRACE_PROBE2(sdbc_io_mem_bcopy_start,
- int, num_frags, int, total_len_bytes);
-
- /* copy the first dirty piece */
- if (first_dirty && (!_SD_BMAP_ISFULL(first_dirty))) {
-
- fba_len = SDBC_LOOKUP_LEN(first_dirty);
- sblk = SDBC_LOOKUP_STPOS(first_dirty);
- offset = FBA_SIZE(sblk);
-
- bcopy(cc_ent->cc_data + offset, next_addr,
- FBA_SIZE(fba_len));
- cc_ent = cc_ent->cc_dirty_next;
- next_addr += FBA_SIZE(fba_len);
- }
-
- /* copy the rest of data */
- while (cc_ent) {
- if (FULLY_DIRTY(cc_ent)) {
- bcopy(cc_ent->cc_data, next_addr,
- CACHE_BLOCK_SIZE);
- next_addr += CACHE_BLOCK_SIZE;
- } else {
- fba_len = SDBC_LOOKUP_LEN(last_dirty);
- bcopy(cc_ent->cc_data, next_addr,
- FBA_SIZE(fba_len));
- next_addr += FBA_SIZE(fba_len);
- }
-
- cc_ent = cc_ent->cc_dirty_next;
- }
-
- DTRACE_PROBE(sdbc_io_mem_bcopy_end);
- }
-
- DTRACE_PROBE(sdbc_io_mem_kmem_end);
- }
-
- return (start_addr);
-}
-
-void
-_sd_async_flclist(_sd_cctl_t *cclist, dev_t rdev)
-{
- int flushed, i, cd;
- uint_t first_dirty, last_dirty;
- _sd_cctl_t *cc_ent, *cc_prev = NULL;
- struct buf *bp;
- int dblk, fba_len;
- int len;
- int toflush;
- int coalesce; /* convenience boolean */
- unsigned char *anon_mem = NULL;
- extern int sdbc_do_page;
-
-
- SDTRACE(ST_ENTER|SDF_FLCLIST, CENTRY_CD(cclist),
- 0, BLK_TO_FBA_NUM(CENTRY_BLK(cclist)), 0, 0);
-
- coalesce = (!sdbc_do_page && sdbc_coalesce_backend);
-
- cc_ent = cclist;
- _sd_cc_iostatus_initiate(cc_ent);
- first_dirty = CENTRY_DIRTY(cc_ent);
- if (SDBC_IS_FRAGMENTED(first_dirty)) {
- cclist = cc_ent->cc_dirty_next;
- cc_ent->cc_dirty_next = NULL;
- _sd_async_flcent(cc_ent, rdev);
- cc_ent = cclist;
- first_dirty = 0;
- }
-
- toflush = 0;
- while (cc_ent->cc_dirty_next) {
- if (cc_ent->cc_iocount)
- SDALERT(SDF_FLCLIST, CENTRY_CD(cc_ent), 0,
- BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent)),
- cc_ent->cc_iocount, 0);
- cc_prev = cc_ent;
- cc_ent = cc_ent->cc_dirty_next;
- toflush++;
- }
- _sd_cc_iostatus_initiate(cc_ent);
- last_dirty = CENTRY_DIRTY(cc_ent);
- if (SDBC_IS_FRAGMENTED(last_dirty)) {
- if (cc_prev)
- cc_prev->cc_dirty_next = NULL;
- _sd_async_flcent(cc_ent, rdev);
- last_dirty = 0;
- }
- else
- toflush++;
-
- if (toflush == 0)
- return;
-
-
- dblk = BLK_TO_FBA_NUM(CENTRY_BLK(cclist));
- if (first_dirty && (!_SD_BMAP_ISFULL(first_dirty)))
- dblk += SDBC_LOOKUP_STPOS(first_dirty);
-
- cd = CENTRY_CD(cclist);
- bp = sd_alloc_iob(rdev, dblk, toflush, B_WRITE);
- cc_ent = cclist;
-
- if (coalesce && (anon_mem = sdbc_alloc_io_mem(cc_ent, first_dirty,
- last_dirty)))
- sd_add_fba(bp, &cc_ent->cc_anon_addr, 0,
- FBA_NUM(cc_ent->cc_anon_len));
-
- if (first_dirty && (!_SD_BMAP_ISFULL(first_dirty))) {
- cc_ent->cc_iocount = flushed = 1;
-
- /* pageio bit already set in sdbc_alloc_io_mem() above */
- if (!coalesce)
- WAIT_CENTRY_PAGEIO(cc_ent, sdbc_flush_pageio);
-
- fba_len = SDBC_LOOKUP_LEN(first_dirty);
-
- /* build buffer only if it was not done above */
- if (!anon_mem) {
- i = SDBC_LOOKUP_STPOS(first_dirty);
- sd_add_fba(bp, &cc_ent->cc_addr, i, fba_len);
- DATA_LOG(SDF_FLSHLIST, cc_ent, i, fba_len);
-
- DTRACE_PROBE4(_sd_async_flclist_data1, int,
- BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent)) + i,
- int, fba_len, char *,
- *(int64_t *)(cc_ent->cc_data + FBA_SIZE(i)),
- char *, *(int64_t *)(cc_ent->cc_data +
- FBA_SIZE(i + fba_len) - 8));
- }
-
- len = FBA_SIZE(fba_len);
- cc_ent = cc_ent->cc_dirty_next;
- } else {
- len = 0;
- flushed = 0;
- }
- while (cc_ent) {
- _sd_cc_iostatus_initiate(cc_ent);
-
- /* pageio bit already set in sdbc_alloc_io_mem() above */
- if (!coalesce)
- WAIT_CENTRY_PAGEIO(cc_ent, sdbc_flush_pageio);
-
- if (FULLY_DIRTY(cc_ent)) {
- flushed++;
- cc_ent->cc_iocount = 1;
-
- /* build buffer only if it was not done above */
- if (!anon_mem) {
- sd_add_fba(bp, &cc_ent->cc_addr, 0, BLK_FBAS);
- DATA_LOG(SDF_FLSHLIST, cc_ent, 0, BLK_FBAS);
-
- DTRACE_PROBE4(_sd_async_flclist_data2,
- int, BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent)),
- int, BLK_FBAS, char *,
- *(int64_t *)(cc_ent->cc_data),
- char *, *(int64_t *)(cc_ent->cc_data +
- FBA_SIZE(BLK_FBAS) - 8));
- }
-
- len += CACHE_BLOCK_SIZE;
- } else {
-#if defined(_SD_DEBUG)
- /*
- * consistency check.
- */
- if (!last_dirty || cc_ent->cc_dirty_next ||
- SDBC_IS_FRAGMENTED(last_dirty)) {
- SDALERT(SDF_FLCLIST, cd, 0,
- BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent)),
- cc_ent->cc_dirty_next, last_dirty);
- cmn_err(CE_WARN,
- "!_sd_err: flclist: last_dirty %x next %x",
- last_dirty, cc_ent->cc_dirty_next);
- }
-#endif
- flushed++;
- cc_ent->cc_iocount = 1;
-
- fba_len = SDBC_LOOKUP_LEN(last_dirty);
-
- /* build buffer only if it was not done above */
- if (!anon_mem) {
- sd_add_fba(bp, &cc_ent->cc_addr, 0, fba_len);
- DATA_LOG(SDF_FLSHLIST, cc_ent, 0, fba_len);
-
- DTRACE_PROBE4(_sd_async_flclist_data3, int,
- BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent)),
- int, fba_len, char *,
- *(int64_t *)(cc_ent->cc_data), char *,
- *(int64_t *)(cc_ent->cc_data +
- FBA_SIZE(fba_len) - 8));
- }
-
- len += FBA_SIZE(fba_len);
- }
- cc_ent = cc_ent->cc_dirty_next;
- }
-
-#ifdef DEBUG
- if (anon_mem)
- ASSERT(len == cclist->cc_anon_len);
-#endif
-
- /* SDTRACE(ST_INFO|SDF_FLCLIST, cd, FBA_NUM(len), dblk, flushed, bp); */
- (void) sd_start_io(bp, _sd_cache_files[cd].cd_strategy,
- _sd_flclist_ea, cclist);
-
- DISK_FBA_WRITE(cd, FBA_NUM(len));
- /* increment number of bytes destaged to disk */
- WRITE_DESTAGED(cd, FBA_NUM(len));
-
- _sd_enqueue_io_pending(cd, cclist);
-
- SDTRACE(ST_EXIT|SDF_FLCLIST, cd, FBA_NUM(len), dblk, flushed, 0);
-}
-
-
-void
-_sd_enqueue_io_pending(int cd, _sd_cctl_t *cclist)
-{
- _sd_cd_info_t *cdi;
-
- cdi = &(_sd_cache_files[cd]);
- if (cdi->cd_io_head == NULL)
- cdi->cd_io_head = cdi->cd_io_tail = cclist;
- else {
- cdi->cd_io_tail->cc_dirty_link = cclist;
- cdi->cd_io_tail = cclist;
- }
-}
-
-
-
-void
-_sd_async_flcent(_sd_cctl_t *cc_ent, dev_t rdev)
-{
- int dblk, len, sblk;
- int dirty;
- struct buf *bp;
- int cd;
-
- cd = CENTRY_CD(cc_ent);
-
- SDTRACE(ST_ENTER|SDF_FLCENT, cd, 0,
- BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent)), 0, 0);
-#if defined(_SD_DEBUG_PATTERN)
- check_write_consistency(cc_ent);
-#endif
- if (cc_ent->cc_iocount)
- SDALERT(SDF_FLCENT, cd, 0, BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent)),
- cc_ent->cc_iocount, 0);
- _sd_cc_iostatus_initiate(cc_ent);
- WAIT_CENTRY_PAGEIO(cc_ent, sdbc_flush_pageio);
-
- dirty = CENTRY_DIRTY(cc_ent);
-
- if (_SD_BMAP_ISFULL(dirty)) {
- cc_ent->cc_iocount = 1;
- dblk = BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent));
- bp = sd_alloc_iob(rdev, dblk, 1, B_WRITE);
- sd_add_fba(bp, &cc_ent->cc_addr, 0, BLK_FBAS);
- DATA_LOG(SDF_FLSHENT, cc_ent, 0, BLK_FBAS);
-
- DTRACE_PROBE4(_sd_async_flcent_data1,
- int, BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent)),
- int, BLK_FBAS, char *, *(int64_t *)(cc_ent->cc_data),
- char *, *(int64_t *)(cc_ent->cc_data +
- FBA_SIZE(BLK_FBAS) - 8));
- cc_ent->cc_iocount = 1;
- (void) sd_start_io(bp, _sd_cache_files[cd].cd_strategy,
- _sd_flcent_ea, cc_ent);
- DISK_FBA_WRITE(cd, BLK_FBAS);
- /* increment number of bytes destaged to disk */
- WRITE_DESTAGED(cd, BLK_FBAS);
- } else {
- cc_ent->cc_iocount = SDBC_LOOKUP_DTCOUNT(dirty);
-
- while (dirty) {
- sblk = SDBC_LOOKUP_STPOS(dirty);
- len = SDBC_LOOKUP_LEN(dirty);
- SDBC_LOOKUP_MODIFY(dirty);
-
- dblk = BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent)) + sblk;
- bp = sd_alloc_iob(rdev, dblk, 1, B_WRITE);
- sd_add_fba(bp, &cc_ent->cc_addr, sblk, len);
- DATA_LOG(SDF_FLSHENT, cc_ent, sblk, len);
-
- DTRACE_PROBE4(_sd_async_flcent_data2, int,
- BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent)) + sblk,
- int, len, char *,
- *(int64_t *)(cc_ent->cc_data + FBA_SIZE(sblk)),
- char *, *(int64_t *)(cc_ent->cc_data +
- FBA_SIZE(sblk + len) - 8));
-
- /* SDTRACE(ST_INFO|SDF_FLCENT, cd, len, dblk, 0, bp); */
-
- (void) sd_start_io(bp, _sd_cache_files[cd].cd_strategy,
- _sd_flcent_ea, cc_ent);
- DISK_FBA_WRITE(cd, len);
- /* increment number of bytes destaged to disk */
- WRITE_DESTAGED(cd, len);
- }
- }
- _sd_enqueue_io_pending(cd, cc_ent);
-
- SDTRACE(ST_EXIT|SDF_FLCENT, cd, 0, dblk, 0, 0);
-}
-
-static void
-_sd_process_pending(int cd)
-{
- _sd_cd_info_t *cdi;
- _sd_cctl_t *cc_ent, *cc_next;
- int dirty_enq;
- ss_centry_info_t *wctl;
- _sd_cctl_t *dirty_hd, **dirty_nxt;
- int sts, processed = 0;
-
- cdi = &(_sd_cache_files[cd]);
-
- SDTRACE(ST_ENTER|SDF_FLDONE, cd, 0,
- SDT_INV_BL, cdi->cd_info->sh_numio, 0);
-process_loop:
- if (cdi->cd_io_head == NULL) {
- if (processed) {
- mutex_enter(&cdi->cd_lock);
- cdi->cd_info->sh_numio -= processed;
- mutex_exit(&cdi->cd_lock);
- }
- SDTRACE(ST_EXIT|SDF_FLDONE, cd, 0,
- SDT_INV_BL, cdi->cd_info->sh_numio, processed);
- return;
- }
- cc_ent = cdi->cd_io_head;
- if ((sts = cc_ent->cc_iostatus) == _SD_IO_INITIATE) {
- if (processed) {
- mutex_enter(&cdi->cd_lock);
- cdi->cd_info->sh_numio -= processed;
- mutex_exit(&cdi->cd_lock);
- }
- SDTRACE(ST_EXIT|SDF_FLDONE, cd, 0,
- SDT_INV_BL, cdi->cd_info->sh_numio, processed);
- return;
- }
- LINTUSED(sts);
-#if defined(_SD_DEBUG)
- if ((sts != _SD_IO_DONE) && (sts != _SD_IO_FAILED))
- SDALERT(SDF_FLDONE, cd, 0,
- BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent)), 0, sts);
-#endif
-
- if ((cdi->cd_io_head = cc_ent->cc_dirty_link) == NULL)
- cdi->cd_io_tail = NULL;
-
- cc_ent->cc_dirty_link = NULL;
- if (cc_ent->cc_iostatus == _SD_IO_FAILED &&
- _sd_process_failure(cc_ent))
- goto process_loop;
-
- dirty_enq = 0;
- dirty_nxt = &(dirty_hd);
-
- DTRACE_PROBE1(_sd_process_pending_cd, int, cd);
-
- for (; cc_ent; cc_ent = cc_next) {
-
- DTRACE_PROBE1(_sd_process_pending_cc_ent,
- _sd_cctl_t *, cc_ent);
- processed++;
- cc_next = cc_ent->cc_dirty_next;
- cc_ent->cc_dirty_next = NULL;
-
- if (CENTRY_PINNED(cc_ent))
- _sd_process_reflush(cc_ent);
-
- /*
- * Optimize for common case where block not inuse
- * Grabbing cc_inuse is faster than cc_lock.
- */
- if (SET_CENTRY_INUSE(cc_ent))
- goto must_lock;
-
- cc_ent->cc_iostatus = _SD_IO_NONE;
- if (CENTRY_DIRTY_PENDING(cc_ent)) {
- cc_ent->cc_flag &= ~CC_PEND_DIRTY;
-
- CLEAR_CENTRY_INUSE(cc_ent);
- if (dirty_enq)
- dirty_nxt = &((*dirty_nxt)->cc_dirty_link);
- (*dirty_nxt) = cc_ent;
- dirty_enq++;
- continue;
- }
- cc_ent->cc_dirty = 0;
- wctl = cc_ent->cc_write;
- cc_ent->cc_write = NULL;
- cc_ent->cc_flag &= ~(CC_PINNABLE);
-
-
- wctl->sc_dirty = 0;
- SSOP_SETCENTRY(sdbc_safestore, wctl);
- SSOP_DEALLOCRESOURCE(sdbc_safestore, wctl->sc_res);
-
- /*
- * if this was a QHEAD cache block, then
- * _sd_centry_release() did not requeue it as
- * it was dirty. Requeue it now.
- */
-
- if (CENTRY_QHEAD(cc_ent))
- if (sdbc_use_dmchain) {
-
- /* attempt to que head */
- if (cc_ent->cc_alloc_size_dm) {
-
- sdbc_requeue_head_dm_try(cc_ent);
- }
- } else
- _sd_requeue_head(cc_ent);
-
- CLEAR_CENTRY_INUSE(cc_ent);
- continue;
-
- /*
- * Block is inuse, must take cc_lock
- * if DIRTY_PENDING, must re-issue
- */
- must_lock:
- /* was FAST */
- mutex_enter(&cc_ent->cc_lock);
- cc_ent->cc_iostatus = _SD_IO_NONE;
- if (CENTRY_DIRTY_PENDING(cc_ent)) {
- cc_ent->cc_flag &= ~CC_PEND_DIRTY;
- /* was FAST */
- mutex_exit(&cc_ent->cc_lock);
- if (dirty_enq)
- dirty_nxt = &((*dirty_nxt)->cc_dirty_link);
- (*dirty_nxt) = cc_ent;
- dirty_enq++;
- continue;
- }
- /*
- * clear dirty bits, if block no longer inuse release cc_write
- */
- cc_ent->cc_dirty = 0;
- if (SET_CENTRY_INUSE(cc_ent) == 0) {
-
- wctl = cc_ent->cc_write;
- cc_ent->cc_write = NULL;
- cc_ent->cc_flag &= ~(CC_PINNABLE);
- /* was FAST */
- mutex_exit(&cc_ent->cc_lock);
-
-
- wctl->sc_dirty = 0;
- SSOP_SETCENTRY(sdbc_safestore, wctl);
- SSOP_DEALLOCRESOURCE(sdbc_safestore, wctl->sc_res);
-
- /*
- * if this was a QHEAD cache block, then
- * _sd_centry_release() did not requeue it as
- * it was dirty. Requeue it now.
- */
-
- if (CENTRY_QHEAD(cc_ent))
- if (sdbc_use_dmchain) {
-
- /* attempt to que head */
- if (cc_ent->cc_alloc_size_dm) {
- sdbc_requeue_head_dm_try
- (cc_ent);
- }
- } else
- _sd_requeue_head(cc_ent);
- CLEAR_CENTRY_INUSE(cc_ent);
- } else {
- /* was FAST */
- mutex_exit(&cc_ent->cc_lock);
- }
- }
-
- if (dirty_enq)
- _sd_enqueue_dirty_chain(cd, dirty_hd, (*dirty_nxt), dirty_enq);
-
- goto process_loop;
-}
-
-
-static void
-_sd_flcent_ea(blind_t xcc_ent, nsc_off_t fba_pos, nsc_size_t fba_len, int error)
-{
- _sd_cctl_t *cc_ent = (_sd_cctl_t *)xcc_ent;
- int cd;
- nsc_off_t dblk;
-
- _sd_cd_info_t *cdi;
-
- cd = CENTRY_CD(cc_ent);
- dblk = BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent));
- cdi = &(_sd_cache_files[cd]);
-
- SDTRACE(ST_ENTER|SDF_FLCENT_EA, cd, 0, dblk, 2, (unsigned long)cc_ent);
-
- if (error) {
- if (cdi->cd_info->sh_failed == 0) {
- cdi->cd_info->sh_failed = 1;
- cmn_err(CE_WARN, "!sdbc(_sd_flcent_ea) "
- "Disk write failed cd %d (%s): err %d",
- cd, cdi->cd_info->sh_filename, error);
- }
- }
-
- /* was FAST */
- mutex_enter(&cc_ent->cc_lock);
- if (--(cc_ent->cc_iocount) != 0) {
- /* more io's to complete before the cc_ent is done. */
-
- if (cc_ent->cc_iocount < 0) {
- /* was FAST */
- mutex_exit(&cc_ent->cc_lock);
- SDALERT(SDF_FLCENT_EA, cd, 0,
- dblk, cc_ent->cc_iocount, 0);
- } else {
- /* was FAST */
- mutex_exit(&cc_ent->cc_lock);
- }
- SDTRACE(ST_EXIT|SDF_FLCENT_EA, cd, 0, dblk, 2,
- (unsigned long)cc_ent);
-
- DTRACE_PROBE(_sd_flcent_ea_end);
- return;
- }
- /* was FAST */
- mutex_exit(&cc_ent->cc_lock);
-
- DATA_LOG(SDF_FLEA, cc_ent, BLK_FBA_OFF(fba_pos), fba_len);
-
- DTRACE_PROBE4(_sd_flcent_ea_data, uint64_t, ((uint64_t)
- BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent) + BLK_FBA_OFF(fba_pos))),
- uint64_t, (uint64_t)fba_len, char *,
- *(int64_t *)(cc_ent->cc_data + FBA_SIZE(BLK_FBA_OFF(fba_pos))),
- char *, *(int64_t *)(cc_ent->cc_data +
- FBA_SIZE(BLK_FBA_OFF(fba_pos) + fba_len) - 8));
-
- /*
- * All io's are done for this cc_ent.
- * Clear the pagelist io flag.
- */
- CLEAR_CENTRY_PAGEIO(cc_ent);
-
- if (error)
- cc_ent->cc_iostatus = _SD_IO_FAILED;
- else
- cc_ent->cc_iostatus = _SD_IO_DONE;
-
- SDTRACE(ST_EXIT|SDF_FLCENT_EA, cd, 0, dblk, 2, (unsigned long)cc_ent);
-
-}
-
-
-
-static void
-_sd_flclist_ea(blind_t xcc_ent, nsc_off_t fba_pos, nsc_size_t fba_len,
- int error)
-{
- _sd_cctl_t *cc_ent = (_sd_cctl_t *)xcc_ent;
- _sd_cctl_t *first_cc = cc_ent;
- _sd_cd_info_t *cdi;
- int cd;
- nsc_off_t dblk;
-
- cd = CENTRY_CD(cc_ent);
- dblk = BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent));
- cdi = &(_sd_cache_files[cd]);
-
- SDTRACE(ST_ENTER|SDF_FLCLIST_EA, cd, 0, dblk, 1, (unsigned long)cc_ent);
-
- if (error) {
- if (cdi->cd_info->sh_failed == 0) {
- cdi->cd_info->sh_failed = 1;
- cmn_err(CE_WARN, "!sdbc(_sd_flclist_ea) "
- "Disk write failed cd %d (%s): err %d",
- cd, cdi->cd_info->sh_filename, error);
- }
- }
- /*
- * Important: skip the first cc_ent in the list. Marking this will
- * make the writer think the io is done, though the rest of the
- * chain have not been processed here. so mark the first cc_ent
- * last. Optimization, so as not to use locks
- */
-
- cc_ent = cc_ent->cc_dirty_next;
- while (cc_ent) {
- DTRACE_PROBE2(_sd_flclist_ea, _sd_cctl_t *, cc_ent,
- int, CENTRY_CD(cc_ent));
-
- if (cc_ent->cc_iocount != 1)
- SDALERT(SDF_FLCLIST_EA, cd, 0,
- BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent)),
- cc_ent->cc_iocount, 0);
- cc_ent->cc_iocount = 0;
-
- /*
- * Clear the pagelist io flag.
- */
- CLEAR_CENTRY_PAGEIO(cc_ent);
-
- if (error)
- cc_ent->cc_iostatus = _SD_IO_FAILED;
- else
- cc_ent->cc_iostatus = _SD_IO_DONE;
- if (cc_ent->cc_dirty_next) {
- DATA_LOG(SDF_FLSTEA, cc_ent, 0, BLK_FBAS);
-
- DTRACE_PROBE4(_sd_flclist_ea_data1, uint64_t,
- BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent)),
- int, BLK_FBAS, char *,
- *(int64_t *)(cc_ent->cc_data),
- char *, *(int64_t *)(cc_ent->cc_data +
- FBA_SIZE(BLK_FBAS) - 8));
- } else {
- DATA_LOG(SDF_FLSTEA, cc_ent, 0,
- BLK_FBA_OFF(fba_pos + fba_len));
-
- DTRACE_PROBE4(_sd_flclist_ea_data2, uint64_t,
- (uint64_t)BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent)),
- uint64_t, (uint64_t)BLK_FBA_OFF(fba_pos + fba_len),
- char *, *(int64_t *)(cc_ent->cc_data),
- char *, *(int64_t *)(cc_ent->cc_data +
- FBA_SIZE(BLK_FBA_OFF(fba_pos + fba_len)) - 8));
- }
-
- cc_ent = cc_ent->cc_dirty_next;
- }
-
- /*
- * Now process the first cc_ent in the list.
- */
- cc_ent = first_cc;
- DATA_LOG(SDF_FLSTEA, cc_ent, BLK_FBA_OFF(fba_pos),
- BLK_FBAS - BLK_FBA_OFF(fba_pos));
-
- DTRACE_PROBE4(_sd_flclist_ea_data3, uint64_t,
- (uint64_t)fba_pos, int, BLK_FBAS - BLK_FBA_OFF(fba_pos),
- char *, *(int64_t *)(cc_ent->cc_data +
- FBA_SIZE(BLK_FBA_OFF(fba_pos))), char *,
- *(int64_t *)(cc_ent->cc_data + FBA_SIZE(BLK_FBA_OFF(fba_pos) +
- BLK_FBAS - BLK_FBA_OFF(fba_pos)) - 8));
-
- cc_ent->cc_iocount = 0;
-
- if (cc_ent->cc_anon_addr.sa_virt) {
- kmem_free(cc_ent->cc_anon_addr.sa_virt, cc_ent->cc_anon_len);
- cc_ent->cc_anon_addr.sa_virt = NULL;
- cc_ent->cc_anon_len = 0;
- }
-
- /*
- * Clear the pagelist io flag.
- */
- CLEAR_CENTRY_PAGEIO(cc_ent);
-
- if (error)
- cc_ent->cc_iostatus = _SD_IO_FAILED;
- else
- cc_ent->cc_iostatus = _SD_IO_DONE;
-
- SDTRACE(ST_EXIT|SDF_FLCLIST_EA, cd, 0, dblk, 1, (unsigned long)cc_ent);
-}
-
-
-static void
-_sd_mark_failed(_sd_cctl_t *cclist)
-{
- _sd_cctl_t *cc_ent;
- int cd;
-
- cd = CENTRY_CD(cclist);
- cc_ent = cclist;
- while (cc_ent) {
- cc_ent->cc_iostatus = _SD_IO_FAILED;
- cc_ent = cc_ent->cc_dirty_next;
- }
- _sd_enqueue_io_pending(cd, cclist);
-}
-
-
-
-/*
- * Fail single chain of cache blocks, updating numfail/numio counts.
- * For dual-copy, log & clear PINNED, fall thru to regular processing.
- */
-int
-_sd_process_failure(_sd_cctl_t *cc_ent)
-{
- int cd, num;
- _sd_cctl_t *cc_chain;
- _sd_cd_info_t *cdi;
-
- cd = CENTRY_CD(cc_ent);
- cdi = &(_sd_cache_files[cd]);
-
- cc_chain = cc_ent;
-
- if (!cdi->cd_global->sv_pinned) {
- cdi->cd_global->sv_pinned = _SD_SELF_HOST;
- SSOP_SETVOL(sdbc_safestore, cdi->cd_global);
- }
-
- for (num = 0; cc_ent; cc_ent = cc_ent->cc_dirty_next) {
- num++;
- /* was FAST */
- mutex_enter(&cc_ent->cc_lock);
- cc_ent->cc_flag |= (CC_PEND_DIRTY |
- (CENTRY_PINNABLE(cc_ent) ? CC_PINNED : 0));
- if (cc_ent->cc_write) {
- cc_ent->cc_write->sc_flag = cc_ent->cc_flag;
- SSOP_SETCENTRY(sdbc_safestore, cc_ent->cc_write);
- }
- mutex_exit(&cc_ent->cc_lock);
- if (CENTRY_PINNED(cc_ent))
- nsc_pinned_data(cdi->cd_iodev,
- BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent)), BLK_FBAS);
- }
-
- /*
- * In normal processing we wouldn't need a lock here as all i/o
- * is single threaded by cd. However during failover blocks can
- * be failing from real i/o and as soon as the disk is marked bad
- * the failover code which is furiously cloning safe-store into
- * more blocks will short circuit to here (see _sd_ft_clone)
- * and two threads can be executing in here simultaneously.
- */
- mutex_enter(&cdi->cd_lock);
- cc_chain->cc_dirty_link = cdi->cd_fail_head;
- cdi->cd_fail_head = cc_chain;
- cdi->cd_info->sh_numfail += num;
- cdi->cd_info->sh_numio -= num;
- mutex_exit(&cdi->cd_lock);
- return (1); /* blocks are failed */
-}
-
-
-static void
-_sd_process_reflush(_sd_cctl_t *cc_ent)
-{
- int cd;
-
- if (CENTRY_PINNABLE(cc_ent)) {
- cd = CENTRY_CD(cc_ent);
- nsc_unpinned_data(_sd_cache_files[cd].cd_iodev,
- BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent)), BLK_FBAS);
- }
-
- /* was FAST */
- mutex_enter(&cc_ent->cc_lock);
- cc_ent->cc_flag &= ~CC_PINNED;
- /* was FAST */
- mutex_exit(&cc_ent->cc_lock);
-}
-
-
-
-/*
- * cd_write_thread -- flush dirty buffers.
- *
- * ARGUMENTS:
- *
- * cd - cache descriptor
- *
- * USAGE:
- * called by cd's writer thread, returns when no more entries
- *
- * NOTE: if sdbc is being shutdown (for powerfail) then we will
- * process pending i/o's but issue no more new ones.
- */
-static int SD_LOOP_DELAY = 32;
-#if !defined(m88k) && !defined(sun)
-static int SD_WRITE_HIGH = 255; /* cache blocks */
-#endif
-
-static void
-cd_write_thread(int cd)
-{
- _sd_cctl_t *cc_list, *dirty_head, *last_chain;
- _sd_cd_info_t *cdi;
-
- cdi = &(_sd_cache_files[cd]);
- if (!FILE_OPENED(cd)) {
- cdi->cd_writer = _SD_WRITER_NONE;
- return;
- }
- cdi->cd_writer = _SD_WRITER_RUNNING;
-
- _sd_process_pending(cd);
-
- if (_sdbc_shutdown_in_progress) {
- cdi->cd_write_inprogress = 0;
- cdi->cd_writer = _SD_WRITER_NONE;
- return;
- }
-#if !defined(m88k) && !defined(sun)
- if (cdi->cd_info->sh_numio > SD_WRITE_HIGH) {
- /* let I/Os complete before issuing more */
- cdi->cd_writer = _SD_WRITER_NONE;
- return;
- }
-#endif
-
-#ifdef DEBUG
- if (!_sdbc_flush_flag) { /* hang the flusher for testing */
- cdi->cd_write_inprogress = 0;
- cdi->cd_writer = _SD_WRITER_NONE;
- return;
- }
-#endif
-
- dirty_head = cdi->cd_dirty_head;
- if (dirty_head && (dirty_head != cdi->cd_lastchain_ptr ||
- ++cdi->cd_info->sh_flushloop > SD_LOOP_DELAY)) {
- cdi->cd_info->sh_flushloop = 0;
- /* was FAST */
- mutex_enter(&cdi->cd_lock);
- if (SD_LOOP_DELAY == 0 ||
- dirty_head == cdi->cd_lastchain_ptr) {
- last_chain = NULL;
- cdi->cd_dirty_head = NULL;
- cdi->cd_dirty_tail = NULL;
- cdi->cd_info->sh_numio += cdi->cd_info->sh_numdirty;
- cdi->cd_info->sh_numdirty = 0;
- } else
-#if !defined(m88k) && !defined(sun)
- if (cdi->cd_info->sh_numdirty > SD_WRITE_HIGH) {
- int count = 0;
- for (last_chain = dirty_head; last_chain;
- last_chain = last_chain->cc_dirty_next)
- count++;
- last_chain = dirty_head->cc_dirty_link;
- cdi->cd_dirty_head = last_chain;
- /* cdi->cd_dirty_tail is unchanged */
- cdi->cd_info->sh_numio += count;
- cdi->cd_info->sh_numdirty -= count;
- } else
-#endif
- {
- last_chain = cdi->cd_lastchain_ptr;
- cdi->cd_dirty_head = last_chain;
- cdi->cd_dirty_tail = last_chain;
- cdi->cd_info->sh_numio += cdi->cd_info->sh_numdirty -
- cdi->cd_lastchain;
- cdi->cd_info->sh_numdirty = cdi->cd_lastchain;
- }
- /* was FAST */
- mutex_exit(&cdi->cd_lock);
-
- while (((cc_list = dirty_head) != NULL) &&
- cc_list != last_chain) {
- dirty_head = cc_list->cc_dirty_link;
- cc_list->cc_dirty_link = NULL;
- if (cdi->cd_info->sh_failed)
- _sd_mark_failed(cc_list);
- else if (cc_list->cc_dirty_next == NULL)
- _sd_async_flcent(cc_list, cdi->cd_crdev);
- else
- _sd_async_flclist(cc_list, cdi->cd_crdev);
- cdi->cd_write_inprogress++;
- }
- }
- cdi->cd_write_inprogress = 0;
- cdi->cd_writer = _SD_WRITER_NONE;
-}
-
-/*
- * cd_writer -- spawn new writer if not running already
- * called after enqueing the dirty blocks
- */
-int
-cd_writer(int cd)
-{
- _sd_cd_info_t *cdi;
- nstset_t *tset = NULL;
- nsthread_t *t;
-
-#if defined(_SD_USE_THREADS)
- tset = _sd_ioset;
-#endif /* _SD_USE_THREADS */
-
- cdi = &(_sd_cache_files[cd]);
-
- if (cdi->cd_writer)
- return (0);
-
- if (tset == NULL) {
- _sd_unblock(&_sd_flush_cv);
- return (0);
- }
-
- if (cdi->cd_writer || xmem_bu(_SD_WRITER_CREATE, &cdi->cd_writer))
- return (0);
-
- t = nst_create(tset, cd_write_thread, (blind_t)(unsigned long)cd, 0);
- if (t)
- return (1);
-
- cmn_err(CE_WARN, "!sdbc(cd_writer) cd %d nst_create error", cd);
- cdi->cd_writer = _SD_WRITER_NONE;
- return (-1);
-}
-
-/*
- * _sd_ccent_rd - add appropriate parts of cc_ent to struct buf.
- * optimized not to read dirty FBAs from disk.
- *
- * ARGUMENTS:
- *
- * cc_ent - single cache block
- * wanted - bitlist of FBAs that need to be read
- * bp - struct buf to extend
- *
- * USAGE:
- * Called for each dirty in a read I/O.
- * The bp must be sized to allow for one entry per FBA that needs
- * to be read (see _sd_doread()).
- */
-
-void
-_sd_ccent_rd(_sd_cctl_t *cc_ent, uint_t wanted, struct buf *bp)
-{
- int index, offset = 0, size = 0;
- int state, state1 = -3; /* state1 is previous state */
- sd_addr_t *addr = NULL;
- uint_t dirty;
-
- dirty = CENTRY_DIRTY(cc_ent);
- for (index = 0; index < BLK_FBAS; index++) {
- if (!_SD_BIT_ISSET(wanted, index))
- continue;
- state = _SD_BIT_ISSET(dirty, index);
- if (state == state1) /* same state, expand size */
- size++;
- else {
- if (state1 != -3) /* not first FBA */
- sd_add_fba(bp, addr, offset, size);
- state1 = state; /* new previous state */
- offset = index;
- size = 1;
- if (state) { /* dirty, don't overwrite */
- addr = NULL;
- } else {
- addr = &cc_ent->cc_addr;
- }
- }
- }
- if (state1 != -3)
- sd_add_fba(bp, addr, offset, size);
-}
-
-
-
-int _SD_WR_THRESHOLD = 1000;
-static void
-_sd_flush_thread(void)
-{
- int cd;
- _sd_cd_info_t *cdi;
- _sd_shared_t *shi;
- int cnt;
- int short_sleep = 0;
- long tics;
- int waiting_for_idle = 0;
- int check_count = 0;
- int pending, last_pending;
- int SD_LONG_SLEEP_TICS, SD_SHORT_SLEEP_TICS;
- nstset_t *tset = NULL;
- nsthread_t *t;
-
-#if defined(_SD_USE_THREADS)
- tset = _sd_ioset;
-#endif /* _SD_USE_THREADS */
-
- mutex_enter(&_sd_cache_lock);
- _sd_cache_dem_cnt++;
- mutex_exit(&_sd_cache_lock);
-
- /* .2 seconds */
- SD_LONG_SLEEP_TICS = drv_usectohz(200000);
- /* .02 seconds */
- SD_SHORT_SLEEP_TICS = drv_usectohz(20000);
-
- /* CONSTCOND */
- while (1) {
- if (_sd_flush_exit == 0) {
- /*
- * wait until no i/o's pending (on two successive
- * iterations) or we see no progress after
- * GIVE_UP_WAITING total sleeps.
- */
-/* at most 5*128 ticks about 6 seconds of no progress */
-#define GIVE_UP_WAITING 128
- if (waiting_for_idle) {
- pending = _sd_pending_iobuf();
- /*LINTED*/
- if (pending == last_pending) {
- if (pending != 0)
- check_count++;
- } else
- check_count = 0;
- if ((last_pending == 0 && (pending == 0)) ||
- (check_count == GIVE_UP_WAITING)) {
- mutex_enter(&_sd_cache_lock);
- _sd_cache_dem_cnt--;
- mutex_exit(&_sd_cache_lock);
- if (check_count == GIVE_UP_WAITING)
- cmn_err(CE_WARN,
- "!_sd_flush_thread "
- "exiting with %d IOs "
- "pending", pending);
- return;
- }
- last_pending = pending;
- } else {
- waiting_for_idle = 1;
- last_pending = _sd_pending_iobuf();
- }
- }
-
- /*
- * Normally wakeup every SD_LONG_SLEEP_TICS to flush.
- */
-
- if (!short_sleep) {
- ssioc_stats_t ss_stats;
- int rc;
-
- if ((rc = SSOP_CTL(sdbc_safestore, SSIOC_STATS,
- (uintptr_t)&ss_stats)) == 0) {
-
- if (ss_stats.wq_inq < _SD_WR_THRESHOLD)
- short_sleep = 1;
- } else {
- if (rc == SS_ERR)
- cmn_err(CE_WARN,
- "!sdbc(_sd_flush_thread)"
- "cannot get safestore inq");
- }
- }
-
- if (short_sleep)
- tics = SD_SHORT_SLEEP_TICS;
- else
- tics = SD_LONG_SLEEP_TICS;
-
- _sd_timed_block(tics, &_sd_flush_cv);
- cd = 0;
- cnt = short_sleep = 0;
- for (; (cnt < _sd_cache_stats->st_loc_count) &&
- (cd < sdbc_max_devs); cd++) {
- cdi = &_sd_cache_files[cd];
- shi = cdi->cd_info;
-
- if (shi == NULL || (shi->sh_failed == 2))
- continue;
-
- if (!(shi->sh_alloc & CD_ALLOCATED) ||
- !(shi->sh_flag & CD_ATTACHED))
- continue;
- cnt++;
- if (cdi->cd_writer)
- continue;
- if (!_SD_CD_WBLK_USED(cd)) {
- if (cdi->cd_failover == 2) {
- nsc_release(cdi->cd_rawfd);
- cdi->cd_failover = 0;
- }
- continue;
- }
- if (cdi->cd_writer ||
- xmem_bu(_SD_WRITER_CREATE, &cdi->cd_writer))
- continue;
-
- t = NULL;
- if (tset) {
- t = nst_create(tset,
- cd_write_thread, (blind_t)(unsigned long)cd,
- 0);
- }
- if (!t)
- cd_write_thread(cd);
- }
- }
-}
-
-
-#if defined(_SD_DEBUG_PATTERN)
-check_write_consistency(cc_entry)
- _sd_cctl_t *cc_entry;
-{
- int *data;
- nsc_off_t fba_pos;
- int i, dirty_bl;
-
- while (cc_entry) {
- dirty_bl = CENTRY_DIRTY(cc_entry);
- if (dirty_bl == 0) {
- cmn_err(CE_WARN, "!check: no dirty");
- }
- data = (int *)cc_entry->cc_data;
- fba_pos = BLK_TO_FBA_NUM(CENTRY_BLK(cc_entry));
-
- for (i = 0; i < 8; i++, data += 128, fba_pos++) {
- if (dirty_bl & 1) {
- if (*((int *)(data + 2)) != fba_pos) {
- cmn_err(CE_WARN, "!wr exp %" NSC_SZFMT
- " got %x", fba_pos, *(data + 2));
- }
- }
- dirty_bl >>= 1;
- }
- cc_entry = cc_entry->cc_dirty_next;
- }
-}
-
-check_buf_consistency(handle, rw)
- _sd_buf_handle_t *handle;
- char *rw;
-{
- _sd_bufvec_t *bvec1;
- int *data;
- nsc_off_t fpos;
- nsc_size_t fba_len, i;
- nsc_size_t len = 0;
-
- bvec1 = handle->bh_bufvec;
- fpos = handle->bh_fba_pos;
-
- while (bvec1->bufaddr) {
- fba_len = FBA_NUM(bvec1->buflen);
- data = (int *)bvec1->bufaddr;
- for (i = 0; i < fba_len; i++, data += 128, fpos++) {
- len++;
- if (*(data+2) != fpos) {
- cmn_err(CE_WARN, "!%s exp%" NSC_SZFMT " got%x",
- rw, fpos, *(data + 2));
- }
- }
- bvec1++;
- }
- if (handle->bh_fba_len != len) {
- cmn_err(CE_WARN, "!len %" NSC_SZFMT " real %" NSC_SZFMT, len,
- handle->bh_fba_len);
- }
-}
-#endif
-
-int
-_sdbc_wait_pending(void)
-{
- int tries, pend, last;
-
- tries = 0;
- last = _sd_pending_iobuf();
- while ((pend = _sd_pending_iobuf()) > 0) {
- if (pend == last) {
- if (++tries > 60) {
- return (pend);
- }
- } else {
- pend = last;
- tries = 0;
- }
- delay(HZ);
- }
- return (0);
-}
diff --git a/usr/src/uts/common/avs/ns/sdbc/sd_io.h b/usr/src/uts/common/avs/ns/sdbc/sd_io.h
deleted file mode 100644
index f28ca06f28..0000000000
--- a/usr/src/uts/common/avs/ns/sdbc/sd_io.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SD_IO_H
-#define _SD_IO_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define SGIO_MAX 254
-
-#define _SD_IO_NONE 0
-#define _SD_IO_INITIATE 1
-#define _SD_IO_DONE 2
-#define _SD_IO_FAILED 3
-#define _SD_IO_DISCARDED 4
-
-#define _SD_WRITER_NONE 0
-#define _SD_WRITER_CREATE 1
-#define _SD_WRITER_RUNNING 2
-
-#ifdef _KERNEL
-
-extern kcondvar_t _sd_flush_cv;
-/* secret flush toggle flag for testing */
-extern int _sdbc_flush_flag; /* 0 ==> noflushing, 1 ==> flush */
-
-
-extern int _sdbc_flush_configure(void);
-extern void _sdbc_flush_deconfigure(void);
-extern void _sd_async_flclist(_sd_cctl_t *cclist, dev_t rdev);
-extern void _sd_enqueue_io_pending(int cd, _sd_cctl_t *cclist);
-extern void _sd_async_flcent(_sd_cctl_t *cc_ent, dev_t rdev);
-extern int _sd_process_failure(_sd_cctl_t *cc_ent);
-extern int cd_writer(int cd);
-extern void _sd_ccent_rd(_sd_cctl_t *cc_ent, uint_t wanted, buf_t *bp);
-extern int _sdbc_wait_pending(void);
-
-#endif /* _KERNEL */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SD_IO_H */
diff --git a/usr/src/uts/common/avs/ns/sdbc/sd_iob.h b/usr/src/uts/common/avs/ns/sdbc/sd_iob.h
deleted file mode 100644
index f875c6aef8..0000000000
--- a/usr/src/uts/common/avs/ns/sdbc/sd_iob.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-
-#ifndef _SD_IOB_H
-#define _SD_IOB_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define MAX_HOOK_LOCKS 32
-typedef int (*dcb_t)(struct buf *); /* driver callback type */
-
-/*
- * order of end action calls:
- * driver callback (iob_drv_iodone) is stuffed in b_iodone and called by
- * the device driver when i/o completes. It calls the hook end action
- * (iob_hook_iodone) which maintains the completion count (iob_hook.count)
- * and calls the clients end action (iob_hook.func) when the chain is complete.
- */
-typedef struct iob_hook {
- struct iob_hook *next_hook;
- struct buf *chain; /* all the buffers for this iob */
- struct buf *tail; /* tail of buffer chain */
- int count; /* number of bufs on the chain */
- nsc_off_t start_fba; /* initial disk block for the xfer */
- nsc_off_t last_fba; /* last disk block for the xfer */
- nsc_size_t size; /* # bytes for entire transfer */
- unsigned char *last_vaddr; /* ending addr of last i/o request */
- sdbc_ea_fn_t func; /* clients end action routine */
- int (* iob_hook_iodone)(struct buf *, struct iob_hook *);
- dcb_t iob_drv_iodone; /* driver call back */
- blind_t param; /* param for clnt end action routine */
- int flags; /* flags for each buffer */
- int error; /* any error */
- int skipped; /* this iob used sd_add_mem */
- kmutex_t *lockp; /* mutex for releasing buffers */
- kcondvar_t wait; /* sync for sleeping on synch i/o */
-#ifdef _SD_BIO_STATS
- int PAGE_IO, NORM_IO, SKIP_IO;
- int PAGE_COMBINED;
- nsc_size_t NORM_IO_SIZE;
-#endif /* _SD_BIO_STATS */
- } iob_hook_t;
-
-typedef struct _sd_buf_list {
- iob_hook_t *hooks; /* all of the iob hooks */
- iob_hook_t *hook_head; /* free iob hook */
- int bl_init_count; /* total count */
- int bl_hooks_avail; /* monitor available hook count */
- int bl_hook_lowmark; /* record if ever run out of hooks */
- int hook_waiters; /* count of waiters */
- int max_hook_waiters; /* record max ever waiters */
- kcondvar_t hook_wait; /* sync for sleeping on synch i/o */
- kmutex_t hook_locks[MAX_HOOK_LOCKS];
-} _sd_buf_list_t;
-
-/*
- * NOTE: if you change this, then also make changes to the generation
- * of sd_iob_impl*.c in src/uts/common/Makefile.files and Makefile.rules!
- */
-#define _SD_DEFAULT_IOBUFS 4096
-
-/* define driver callback and driver callback function table */
-
-#define IOB_DCBP(i) (sd_iob_dcb ## i)
-
-#define IOB_DCB(i) \
- int \
- IOB_DCBP(i)(struct buf *bp) \
- { \
- return ((*_sd_buflist.hooks[i].iob_hook_iodone) \
- (bp, &_sd_buflist.hooks[i])); \
- }
-
-extern _sd_buf_list_t _sd_buflist;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SD_IOB_H */
diff --git a/usr/src/uts/common/avs/ns/sdbc/sd_misc.c b/usr/src/uts/common/avs/ns/sdbc/sd_misc.c
deleted file mode 100644
index e63bf9dd4d..0000000000
--- a/usr/src/uts/common/avs/ns/sdbc/sd_misc.c
+++ /dev/null
@@ -1,1437 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#define _SCM_
-
-#include <sys/types.h>
-#include <sys/ksynch.h>
-#include <sys/cmn_err.h>
-#include <sys/modctl.h>
-#include <sys/conf.h>
-#include <sys/errno.h>
-#include <sys/file.h>
-#include <sys/kmem.h>
-#include <sys/cred.h>
-#include <sys/ddi.h>
-#include <sys/nsc_thread.h>
-
-#include "sd_bcache.h"
-#include "sd_misc.h"
-#include "sd_trace.h"
-#include "sd_ft.h"
-#include "sd_io.h"
-#include "sd_bio.h"
-#include "sd_pcu.h"
-#include "sd_tdaemon.h"
-#include "sdbc_ioctl.h"
-#include <sys/ncall/ncall.h>
-#include <sys/nsctl/nsctl.h>
-#include <sys/nsctl/nsvers.h>
-
-#include <sys/sdt.h> /* dtrace is S10 or later */
-
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_k.h>
-#include <sys/unistat/spcs_errors.h>
-static dev_info_t *dev_dip;
-dev_info_t *sdbc_get_dip();
-
-
-/*
- * A global variable to set the threshold for large writes to
- * be in write through mode when NVRAM is present. This should
- * solve the NVRAM bandwidth problem.
- */
-
-int sdbc_wrthru_len;
-nsc_size_t sdbc_max_fbas = _SD_MAX_FBAS;
-int sdbc_max_devs = 0;
-
-krwlock_t sdbc_queue_lock;
-
-static int _sd_debug_level = 0;
-
-static kmutex_t _sd_block_lk;
-
-#define REGISTER_SVC(X, Y) (ncall_register_svc(X, Y))
-#define UNREGISTER_SVC(X) (ncall_unregister_svc(X))
-
-const int sdbc_major_rev = ISS_VERSION_MAJ;
-const int sdbc_minor_rev = ISS_VERSION_MIN;
-const int sdbc_micro_rev = ISS_VERSION_MIC;
-const int sdbc_baseline_rev = ISS_VERSION_NUM;
-static char sdbc_version[16];
-
-static int _sdbc_attached = 0;
-
-static int _sdbc_print(dev_t dev, char *s);
-static int sdbcunload(void);
-static int sdbcload(void);
-static int sdbcopen(dev_t *devp, int flag, int otyp, cred_t *crp);
-static int sdbcclose(dev_t dev, int flag, int otyp, cred_t *crp);
-static int sdbcioctl(dev_t dev, int cmd, void *arg, int mode, cred_t *crp,
- int *rvp);
-static int _sdbc_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
-static int _sdbc_probe(dev_info_t *dip);
-static int _sdbc_attach(dev_info_t *, ddi_attach_cmd_t);
-static int _sdbc_detach(dev_info_t *, ddi_detach_cmd_t);
-static int _sdbc_reset(dev_info_t *, ddi_reset_cmd_t);
-
-#ifdef sun
-/*
- * Solaris specific driver module interface code.
- */
-
-#ifdef USES_SOFT_STATE
-struct sdbc_state {
- dev_info_t *dip; /* everyone would need a devinfo */
-};
-
-static void *sdbc_statep; /* for soft state routines */
-#endif /* USES_SOFT_STATE */
-
-static struct cb_ops sdbc_cb_ops = {
- sdbcopen, /* open */
- sdbcclose, /* close */
- nodev, /* not a block driver, strategy not an entry point */
- _sdbc_print, /* no print routine */
- nodev, /* no dump routine */
- nodev, /* read */
- nodev, /* write */
- (int (*) ()) sdbcioctl, /* ioctl */
- nodev, /* no devmap routine */
- nodev, /* no mmap routine */
- nodev, /* no segmap routine */
- nochpoll, /* no chpoll routine */
- ddi_prop_op,
- 0, /* not a STREAMS driver, no cb_str routine */
- D_NEW | D_MP, /* safe for multi-thread/multi-processor */
-};
-
-
-static struct dev_ops sdbc_ops = {
- DEVO_REV, /* Driver build version */
- 0, /* device reference count */
- _sdbc_getinfo,
- nulldev,
- _sdbc_probe,
- _sdbc_attach,
- _sdbc_detach,
- _sdbc_reset,
- &sdbc_cb_ops,
- (struct bus_ops *)NULL
-};
-
-static struct modldrv sdbc_ldrv = {
- &mod_driverops,
- "nws:Storage Cache:" ISS_VERSION_STR,
- &sdbc_ops
-};
-
-static struct modlinkage sdbc_modlinkage = {
- MODREV_1,
- &sdbc_ldrv,
- NULL
-};
-
-/*
- * dynmem interface
- */
-static int mutex_and_condvar_flag;
-
-/*
- * Solaris module load time code
- */
-int
-_init(void)
-{
-
- int err;
-
- mutex_and_condvar_flag = 0;
-
-#ifdef USES_SOFT_STATE
- ddi_soft_state_init(&sdbc_statep, sizeof (struct sdbc_state),
- MAX_INSTANCES);
-#endif /* USES_SOFT_STATE */
-
- /*
- * It is "load" time, call the unixware equivalent.
- */
- err = sdbcload();
- if (!err)
- err = mod_install(&sdbc_modlinkage);
-
- if (err) {
- (void) sdbcunload();
-#ifdef USES_SOFT_STATE
- ddi_soft_state_fini(&sdbc_statep);
-#endif /* USES_SOFT_STATE */
- }
-
- if (!err) {
- mutex_and_condvar_flag = 1;
- mutex_init(&dynmem_processing_dm.thread_dm_lock, "dynmem",
- MUTEX_DRIVER, NULL);
- cv_init(&dynmem_processing_dm.thread_dm_cv, "dynmem",
- CV_DRIVER, NULL);
- }
-
- return (err);
-
-}
-/*
- * Solaris module unload time code
- */
-
-int
-_fini(void)
-{
- int err;
-
- if (_sd_cache_initialized) {
- return (EBUSY);
- } else if (_sd_ioset &&
- (_sd_ioset->set_nlive || _sd_ioset->set_nthread)) {
- cmn_err(CE_WARN, "!sdbc:_fini() %d threads still "
- "active; %d threads in set\n", _sd_ioset->set_nlive,
- _sd_ioset->set_nthread);
- return (EBUSY);
- }
- if ((err = mod_remove(&sdbc_modlinkage)) == 0) {
- DTRACE_PROBE2(_sdbc_fini_mod_remove_succeeded,
- int, err,
- struct modlinkage *, &sdbc_modlinkage);
- err = sdbcunload();
-#ifdef USES_SOFT_STATE
- ddi_soft_state_fini(&sdbc_statep);
-#endif /* USES_SOFT_STATE */
-
- if (mutex_and_condvar_flag) {
- cv_destroy(&dynmem_processing_dm.thread_dm_cv);
- mutex_destroy(&dynmem_processing_dm.thread_dm_lock);
- mutex_and_condvar_flag = 0;
- }
- }
-
- return (err);
-}
-
-/*
- * Solaris module info code
- */
-int
-_info(struct modinfo *modinfop)
-{
- return (mod_info(&sdbc_modlinkage, modinfop));
-}
-
-/*ARGSUSED*/
-static int
-_sdbc_probe(dev_info_t *dip)
-{
- return (DDI_PROBE_SUCCESS);
-}
-
-/*
- * Attach an instance of the device. This happens before an open
- * can succeed.
- */
-static int
-_sdbc_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
-{
- _dm_process_vars_t local_dm_process_vars;
- struct buf bp;
-
- if (cmd != DDI_ATTACH)
- return (DDI_FAILURE);
-
- /*
- * Get the threshold value for setting large writes in
- * write through mode(when NVRAM is present)
- */
-
- sdbc_wrthru_len = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "sdbc_wrthru_thresh", 64);
-
- /* Get sdbc_max_fbas from sdbc.conf */
- sdbc_max_fbas = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "sdbc_max_fbas",
- _SD_MAX_FBAS);
-
- bp.b_bcount = (size_t)FBA_SIZE(sdbc_max_fbas);
- minphys(&bp); /* clamps value to maxphys */
-
- sdbc_max_fbas = FBA_NUM(bp.b_bcount);
-
- if (sdbc_max_fbas > _SD_MAX_FBAS) {
- cmn_err(CE_WARN,
- "!_sdbc_attach: sdbc_max_fbas set to %d", _SD_MAX_FBAS);
- sdbc_max_fbas = _SD_MAX_FBAS;
- }
-
- /*
- * -get the maximum list length for multipage dynmem
- * -time between aging
- * -number of agings before dealloc
- * -what to report D0=shutdown, D1=thread variables
- */
- dynmem_processing_dm.max_dyn_list = MAX_DYN_LIST_DEFAULT;
- dynmem_processing_dm.monitor_dynmem_process =
- MONITOR_DYNMEM_PROCESS_DEFAULT;
- dynmem_processing_dm.cache_aging_ct1 = CACHE_AGING_CT_DEFAULT;
- dynmem_processing_dm.cache_aging_ct2 = CACHE_AGING_CT_DEFAULT;
- dynmem_processing_dm.cache_aging_ct3 = CACHE_AGING_CT_DEFAULT;
- dynmem_processing_dm.cache_aging_sec1 = CACHE_AGING_SEC1_DEFAULT;
- dynmem_processing_dm.cache_aging_sec2 = CACHE_AGING_SEC2_DEFAULT;
- dynmem_processing_dm.cache_aging_sec3 = CACHE_AGING_SEC3_DEFAULT;
- dynmem_processing_dm.cache_aging_pcnt1 = CACHE_AGING_PCNT1_DEFAULT;
- dynmem_processing_dm.cache_aging_pcnt2 = CACHE_AGING_PCNT2_DEFAULT;
- dynmem_processing_dm.max_holds_pcnt = MAX_HOLDS_PCNT_DEFAULT;
- dynmem_processing_dm.process_directive = PROCESS_DIRECTIVE_DEFAULT;
-
- local_dm_process_vars.max_dyn_list = ddi_prop_get_int(DDI_DEV_T_ANY,
- dip, DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "sdbc_max_dyn_list",
- MAX_DYN_LIST_DEFAULT);
-
- local_dm_process_vars.monitor_dynmem_process =
- ddi_prop_get_int(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "sdbc_monitor_dynmem",
- MONITOR_DYNMEM_PROCESS_DEFAULT);
-
- local_dm_process_vars.cache_aging_ct1 = ddi_prop_get_int(DDI_DEV_T_ANY,
- dip, DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "sdbc_cache_aging_ct1",
- CACHE_AGING_CT_DEFAULT);
-
- local_dm_process_vars.cache_aging_ct2 = ddi_prop_get_int(DDI_DEV_T_ANY,
- dip, DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "sdbc_cache_aging_ct2",
- CACHE_AGING_CT_DEFAULT);
-
- local_dm_process_vars.cache_aging_ct3 = ddi_prop_get_int(DDI_DEV_T_ANY,
- dip, DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "sdbc_cache_aging_ct3",
- CACHE_AGING_CT_DEFAULT);
-
- local_dm_process_vars.cache_aging_sec1 = ddi_prop_get_int(DDI_DEV_T_ANY,
- dip, DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "sdbc_cache_aging_sec1",
- CACHE_AGING_SEC1_DEFAULT);
-
- local_dm_process_vars.cache_aging_sec2 = ddi_prop_get_int(DDI_DEV_T_ANY,
- dip, DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "sdbc_cache_aging_sec2",
- CACHE_AGING_SEC2_DEFAULT);
-
- local_dm_process_vars.cache_aging_sec3 = ddi_prop_get_int(DDI_DEV_T_ANY,
- dip, DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "sdbc_cache_aging_sec3",
- CACHE_AGING_SEC3_DEFAULT);
-
- local_dm_process_vars.cache_aging_pcnt1 =
- ddi_prop_get_int(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "sdbc_cache_aging_pcnt1",
- CACHE_AGING_PCNT1_DEFAULT);
-
- local_dm_process_vars.cache_aging_pcnt2 =
- ddi_prop_get_int(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "sdbc_cache_aging_pcnt2",
- CACHE_AGING_PCNT2_DEFAULT);
-
- local_dm_process_vars.process_directive =
- ddi_prop_get_int(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "sdbc_process_directive",
- PROCESS_DIRECTIVE_DEFAULT);
-
- local_dm_process_vars.max_holds_pcnt = ddi_prop_get_int(DDI_DEV_T_ANY,
- dip, DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "sdbc_max_holds_pcnt",
- MAX_HOLDS_PCNT_DEFAULT);
-
- (void) sdbc_edit_xfer_process_vars_dm(&local_dm_process_vars);
-
-#define MINOR_NAME "c,sdbc" /* character device */
-#define MINOR_NUMBER 0
-#ifdef MINOR_NAME
- if (ddi_create_minor_node(dip, MINOR_NAME, S_IFCHR,
- MINOR_NUMBER, DDI_PSEUDO, 0) != DDI_SUCCESS) {
- /* free anything we allocated here */
- return (DDI_FAILURE);
- }
-#endif /* MINOR_NAME */
-
- /* Announce presence of the device */
- ddi_report_dev(dip);
- dev_dip = dip;
- /* mark the device as attached, opens may proceed */
- _sdbc_attached = 1;
-
- rw_init(&sdbc_queue_lock, NULL, RW_DRIVER, NULL);
-
- return (DDI_SUCCESS);
-}
-
-/*ARGSUSED*/
-static int
-_sdbc_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
-{
- if (cmd == DDI_DETACH) {
- /*
- * Check first if the cache is still in use
- * and if it is, prevent the detach.
- */
- if (_sd_cache_initialized)
- return (EBUSY);
-
- _sdbc_attached = 0;
-
- rw_destroy(&sdbc_queue_lock);
- dev_dip = NULL;
-
- return (DDI_SUCCESS);
- } else
- return (DDI_FAILURE);
-}
-
-/*ARGSUSED*/
-static int
-_sdbc_reset(dev_info_t *dip, ddi_reset_cmd_t cmd)
-{
- return (DDI_SUCCESS);
-}
-
-/*ARGSUSED*/
-static int
-_sdbc_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
-{
- dev_t dev;
-#ifdef USES_SOFT_STATE
- struct sdbc_state *xsp;
- int instance;
-#endif /* USES_SOFT_STATE */
- int rc;
-
- switch (cmd) {
- case DDI_INFO_DEVT2INSTANCE:
- dev = (dev_t)arg;
- /* The "instance" number is the minor number */
- *result = (void *)(unsigned long)getminor(dev);
- rc = DDI_SUCCESS;
- break;
-
- case DDI_INFO_DEVT2DEVINFO:
- dev = (dev_t)arg;
-#ifdef USES_SOFT_STATE
- /* the instance number is the minor number */
- instance = getminor(dev);
- xsp = ddi_get_soft_state(sdbc_statep, instance);
- if (xsp == NULL)
- return (DDI_FAILURE);
- *result = (void *) xsp->dip;
-#else
- *result = (void *) NULL;
-#endif /* USES_SOFT_STATE */
- rc = DDI_SUCCESS;
- break;
-
- default:
- rc = DDI_FAILURE;
- break;
- }
- return (rc);
-}
-
-/*ARGSUSED*/
-int
-_sdbc_print(dev_t dev, char *s)
-{
- cmn_err(CE_WARN, "!sdbc(_sdbc_print) %s", s);
- return (0);
-}
-#else
-MOD_DRV_WRAPPER(sdbc, sdbcload, sdbcunload, NULL, "Storage Device Block Cache");
-#endif /* sun */
-
-static int sdbc_inited;
-
-static int
-sdbcinit(void)
-{
- int rc;
-
- sdbc_inited = 0;
-
- (void) strncpy(sdbc_version, _VERSION_, sizeof (sdbc_version));
-
- mutex_init(&_sd_cache_lock, NULL, MUTEX_DRIVER, NULL);
- mutex_init(&_sdbc_config_lock, NULL, MUTEX_DRIVER, NULL);
-
-#ifdef m88k
- REGISTER_SVC(SD_DUAL_WRITE, r_sd_ifs_write);
- REGISTER_SVC(SD_DUAL_READ, r_sd_ifs_read);
- REGISTER_SVC(SD_SET_CD, r_sd_set_cd);
- REGISTER_SVC(SD_GETSIZE, r_sd_getsize);
- REGISTER_SVC(SD_DUAL_OPEN, r_sd_ifs_open);
- REGISTER_SVC(SD_REMOTE_FLUSH, r_sd_remote_flush);
- REGISTER_SVC(SD_SGREMOTE_FLUSH, r_sd_sgremote_flush);
- REGISTER_SVC(SD_DISK_IO, r_sd_disk_io);
- REGISTER_SVC(SD_GET_BMAP, r_rem_get_bmap);
-
- if ((rc = hpf_register_module("SDBC", _sd_hpf_stats)) != 0)
- return (rc);
-#endif
- REGISTER_SVC(SD_ENABLE, r_sd_ifs_cache_enable);
- REGISTER_SVC(SD_DISABLE, r_sd_ifs_cache_disable);
- REGISTER_SVC(SD_CD_DISCARD, r_cd_discard);
-
- cv_init(&_sd_flush_cv, NULL, CV_DRIVER, NULL);
-
- mutex_init(&_sd_block_lk, NULL, MUTEX_DRIVER, NULL);
-
- sdbc_max_devs = nsc_max_devices();
-
- /*
- * Initialize the bitmap array that would be useful in determining
- * if the mask is not fragmented, instead of determinig this
- * at run time. Also initialize a lookup array for each mask, with
- * the starting position, the length, and the mask subset
- */
- _sd_init_contig_bmap();
- _sd_init_lookup_map();
-
- if ((rc = _sdbc_iobuf_load()) != 0)
- return (rc);
- if ((rc = _sdbc_handles_load()) != 0)
- return (rc);
- if ((rc = _sdbc_tr_load()) != 0)
- return (rc);
- if ((rc = _sdbc_ft_load()) != 0)
- return (rc);
- if ((rc = _sdbc_tdaemon_load()) != 0)
- return (rc);
- if ((rc = _sdbc_hash_load()) != 0)
- return (rc);
-#ifdef DEBUG
- _sdbc_ioj_load();
-#endif
- sdbc_inited = 1;
-
- return (0);
-}
-
-static int
-sdbcunload(void)
-{
- if (_sd_cache_initialized) {
- cmn_err(CE_WARN,
- "!sdbc(sdbcunload) cannot unload module - cache in use!");
- return (EEXIST);
- }
-#ifdef m88k
- UNREGISTER_SVC(SD_DUAL_WRITE);
- UNREGISTER_SVC(SD_DUAL_READ);
- UNREGISTER_SVC(SD_SET_CD);
- UNREGISTER_SVC(SD_GETSIZE);
- UNREGISTER_SVC(SD_DUAL_OPEN);
- UNREGISTER_SVC(SD_REMOTE_FLUSH);
- UNREGISTER_SVC(SD_SGREMOTE_FLUSH);
- UNREGISTER_SVC(SD_DISK_IO);
- UNREGISTER_SVC(SD_GET_BMAP);
-
- (void) hpf_unregister_module("SDBC");
-#endif
- UNREGISTER_SVC(SD_ENABLE);
- UNREGISTER_SVC(SD_DISABLE);
- UNREGISTER_SVC(SD_CD_DISCARD);
-
- cv_destroy(&_sd_flush_cv);
- mutex_destroy(&_sd_block_lk);
-
- _sdbc_hash_unload();
- _sdbc_ft_unload();
- _sdbc_tr_unload();
- _sdbc_tdaemon_unload();
- _sdbc_handles_unload();
- _sdbc_iobuf_unload();
-#ifdef DEBUG
- _sdbc_ioj_unload();
-#endif
-
- mutex_destroy(&_sd_cache_lock);
- mutex_destroy(&_sdbc_config_lock);
-
- /*
- * Normally we would unregister memory at deconfig time.
- * However when chasing things like memory leaks it is
- * useful to defer until unload time.
- */
- if (_sdbc_memtype_deconfigure_delayed)
- _sdbc_memtype_deconfigure();
-
- return (0);
-}
-
-
-static int
-sdbcload(void)
-{
- int err;
-
- if ((err = sdbcinit()) != 0) {
- (void) sdbcunload();
- return (err);
- }
- return (0);
-}
-
-
-/* ARGSUSED */
-
-static int
-sdbcopen(dev_t *devp, int flag, int otyp, cred_t *crp)
-{
- int nd = nsc_node_id();
-
- /*
- * If we were statically linked in then returning an error out
- * of sdbcinit won't prevent someone from coming thru here.
- * We must prevent them from getting any further.
- */
- if (!sdbc_inited)
- return (EINVAL);
-
- if (nd < nsc_min_nodeid) {
- cmn_err(CE_WARN,
- "!sdbc(sdbcopen) open failed, systemid (%d) must be >= %d",
- nd, nsc_min_nodeid);
- return (EINVAL);
- }
- if (!_sdbc_attached)
- return (ENXIO);
-
- return (0);
-}
-
-
-/* ARGSUSED */
-
-static int
-sdbcclose(dev_t dev, int flag, int otyp, cred_t *crp)
-{
- return (0);
-}
-
-#ifdef _MULTI_DATAMODEL
-static int
-convert_ioctl_args(int cmd, void *arg, int mode, _sdbc_ioctl_t *args)
-/*
- * convert_ioctl-args - Do a case by case conversion of a ILP32 ioctl
- * structure to an LP64 structure.
- * The main concern here is whether to sign-extend or not. The rule
- * is that pointers are not sign extended, the rest are obvious.
- * Since most everything is sign-extended the definition of
- * _sdbc_ioctl32_t uses signed fields.
- *
- */
-{
- _sdbc_ioctl32_t args32;
-
- if (ddi_copyin(arg, &args32, sizeof (_sdbc_ioctl32_t), mode))
- return (EFAULT);
-
- bzero((void *) args, sizeof (_sdbc_ioctl_t));
-
- switch (cmd) {
-
- case SDBC_UNUSED_1:
- case SDBC_UNUSED_2:
- case SDBC_UNUSED_3:
- args->sdbc_ustatus = (spcs_s_info_t)args32.sdbc_ustatus;
- cmn_err(CE_WARN,
- "!sdbc(convert_ioctl_args) obsolete sdbc ioctl used");
- return (EINVAL);
-
- case SDBC_ADUMP:
- args->arg0 = args32.arg0; /* cd */
- args->arg1 = (uint32_t)args32.arg1; /* &tt */
- args->arg2 = (uint32_t)args32.arg2; /* NULL (buf) */
- args->arg3 = args32.arg3; /* size of buf */
- args->arg4 = args32.arg4; /* flag */
- args->sdbc_ustatus = (spcs_s_info_t)args32.sdbc_ustatus;
- break;
-
- case SDBC_TEST_INIT:
- args->arg0 = (uint32_t)args32.arg0; /* fname (char *) */
- args->arg1 = args32.arg1; /* index */
- args->arg2 = args32.arg2; /* len */
- args->arg3 = args32.arg3; /* track size */
- args->arg4 = args32.arg4; /* flag */
- break;
-
- case SDBC_TEST_START:
- args->arg0 = args32.arg0; /* num */
- args->arg1 = args32.arg1; /* type */
- args->arg2 = args32.arg2; /* loops */
- args->arg3 = args32.arg3; /* from */
- args->arg4 = args32.arg4; /* seed */
- break;
-
- case SDBC_TEST_END:
- break;
-
- case SDBC_ENABLE:
- case SDBC_VERSION:
- args->arg0 = (uint32_t)args32.arg0; /* pointer */
- args->sdbc_ustatus = (spcs_s_info_t)args32.sdbc_ustatus;
- break;
-
- case SDBC_DISABLE:
- args->sdbc_ustatus = (spcs_s_info_t)args32.sdbc_ustatus;
- break;
-
- case SDBC_GET_CLUSTER_SIZE:
- args->arg0 = (uint32_t)args32.arg0; /* (int * ) */
- args->sdbc_ustatus = (spcs_s_info_t)args32.sdbc_ustatus;
- break;
-
- /* get the gl_file data */
- case SDBC_GET_CLUSTER_DATA:
- /* pointer to array[2*cluster_size] */
- args->arg0 = (uint32_t)args32.arg0;
- args->sdbc_ustatus = (spcs_s_info_t)args32.sdbc_ustatus;
- break;
-
- /* get the size of the global info pages for each board */
- case SDBC_GET_GLMUL_SIZES:
- args->arg0 = (uint32_t)args32.arg0; /* int[CACHE_MEM_PAD] * */
- args->sdbc_ustatus = (spcs_s_info_t)args32.sdbc_ustatus;
- break;
-
- /* get the global info about write blocks */
- case SDBC_GET_GLMUL_INFO:
- /* pointer to array[2*(sum of GLMUL_SIZES)] */
- args->arg0 = (uint32_t)args32.arg0;
- args->sdbc_ustatus = (spcs_s_info_t)args32.sdbc_ustatus;
- break;
-
- case SDBC_SET_CD_HINT:
- args->arg0 = args32.arg0; /* cd */
- args->arg1 = args32.arg1; /* hint */
- args->arg2 = args32.arg2; /* flag */
- args->sdbc_ustatus = (spcs_s_info_t)args32.sdbc_ustatus;
- break;
-
- case SDBC_GET_CD_HINT:
- args->arg0 = args32.arg0;
- args->sdbc_ustatus = (spcs_s_info_t)args32.sdbc_ustatus;
- break;
-
- case SDBC_SET_NODE_HINT:
- args->arg0 = args32.arg0; /* hint */
- args->arg1 = args32.arg1; /* flag */
- args->sdbc_ustatus = (spcs_s_info_t)args32.sdbc_ustatus;
- break;
-
- case SDBC_GET_NODE_HINT:
- args->sdbc_ustatus = (spcs_s_info_t)args32.sdbc_ustatus;
- break;
-
- case SDBC_STATS:
- args->arg0 = (uint32_t)args32.arg0; /* (_sd_stats_t *) */
- args->sdbc_ustatus = (spcs_s_info_t)args32.sdbc_ustatus;
- break;
-
- case SDBC_ZAP_STATS:
- args->sdbc_ustatus = (spcs_s_info_t)args32.sdbc_ustatus;
- break;
-
- case SDBC_GET_CD_BLK:
- args->arg0 = args32.arg0; /* cd */
- args->arg1 = (uint32_t)args32.arg1; /* blk */
- args->arg2 = (uint32_t)args32.arg2; /* (addr[5] *) */
- break;
-
- case SDBC_GET_CONFIG:
- args->arg0 = (uint32_t)args32.arg0; /* (_sdbc_config_t *) */
- args->sdbc_ustatus = (spcs_s_info_t)args32.sdbc_ustatus;
- break;
-
- case SDBC_SET_CONFIG:
- args->arg0 = (uint32_t)args32.arg0; /* (_sdbc_config_t *) */
- args->sdbc_ustatus = (spcs_s_info_t)args32.sdbc_ustatus;
- break;
-
- case SDBC_MAXFILES:
- args->arg0 = (uint32_t)args32.arg0; /* (int * ) */
- args->sdbc_ustatus = (spcs_s_info_t)args32.sdbc_ustatus;
- break;
-
-#ifdef DEBUG
- /* toggle flusher flag for testing */
- case SDBC_TOGGLE_FLUSH:
- args->sdbc_ustatus = (spcs_s_info_t)args32.sdbc_ustatus;
- break;
-
- case SDBC_INJ_IOERR: /* cd, errnum */
- args->arg0 = args32.arg0; /* cd */
- args->arg1 = args32.arg1; /* i/o error number */
- args->arg2 = args32.arg2; /* countdown to issuing error */
- break;
-
- /* clear injected i/o errors */
- case SDBC_CLR_IOERR: /* cd */
- args->arg0 = args32.arg0; /* cd */
- break;
-#endif /* DEBUG */
- default:
- return (EINVAL);
- }
-
- return (0);
-}
-#endif /* _MULTI_DATAMODEL */
-
-static int
-sdbc_get_cd_blk(_sdbc_ioctl_t *args, int mode)
-{
-
- _sd_cctl_t *cc_ent;
- caddr_t data;
- char *taddr;
- intptr_t addr[5];
-#ifdef _MULTI_DATAMODEL
- uint32_t addr_32[5];
-#endif /* _MULTI_DATAMODEL */
- char *lookup_file = NULL;
- int rc;
- sdbc_info_t info;
- nsc_off_t fba_pos; /* disk block number */
-
- if (_sd_cache_initialized == 0) {
- return (EINVAL);
- }
-
- /* copyin the block number */
- if (ddi_copyin((void *)args->arg1, &fba_pos, sizeof (nsc_off_t),
- mode)) {
- return (EFAULT);
- }
-
-#ifdef _MULTI_DATAMODEL
- if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
- if (ddi_copyin((void *)args->arg2, addr_32, sizeof (addr_32),
- mode)) {
- return (EFAULT);
- }
- addr[0] = addr_32[0]; /* (sdbc_info_t *) */
- addr[1] = addr_32[1]; /* (char *) cdata */
- addr[2] = addr_32[2]; /* ( int * ) cblk_size */
- addr[3] = addr_32[3]; /* ( char * ) filename */
- addr[4] = addr_32[4]; /* ( char *) wdata */
- } else {
- if (ddi_copyin((void *)args->arg2, addr, sizeof (addr), mode)) {
- return (EFAULT);
- }
- }
-#else /* _MULTI_DATAMODEL */
- if (ddi_copyin((void *)args->arg2, addr, sizeof (addr), mode)) {
- return (EFAULT);
- }
-#endif /* _MULTI_DATAMODEL */
-
- (void) copyout(&CACHE_BLOCK_SIZE, (void *)addr[2], sizeof (int));
-
- if (_sd_get_cd_blk((int)args->arg0, FBA_TO_BLK_NUM(fba_pos),
- &cc_ent, &data, &lookup_file)) {
- if (lookup_file != NULL)
- (void) copyout(lookup_file, (void *)addr[3],
- NSC_MAXPATH);
- return (ENOENT);
- }
- rc = 0;
- taddr = NULL;
-
- info.ci_write = cc_ent->cc_write ? 1 : 0;
- info.ci_dirty = cc_ent->cc_dirty;
- info.ci_valid = cc_ent->cc_valid;
- info.ci_cd = CENTRY_CD(cc_ent);
- info.ci_dblk = BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent));
- (void) copyout(lookup_file, (void *)addr[3], NSC_MAXPATH);
- (void) copyout(&info, (void *)addr[0], sizeof (sdbc_info_t));
-
- (void) copyout(data, (void *)addr[1], CACHE_BLOCK_SIZE);
-
- /* get the write data if any */
- if (cc_ent->cc_write) {
-
- if (sdbc_safestore) {
- cmn_err(CE_WARN,
- "!sdbc(sdbc_get_cd_blk) cc_write 0x%p sc-res 0x%p",
- (void *)cc_ent->cc_write,
- (void *)cc_ent->cc_write->sc_res);
-
- if ((taddr = kmem_alloc(CACHE_BLOCK_SIZE,
- KM_NOSLEEP)) == NULL) {
- cmn_err(CE_WARN,
- "!sdbc(sdbc_get_cd_blk) kmem_alloc failed."
- " cannot get write data");
- info.ci_write = NULL;
- rc = EFAULT;
- } else if (SSOP_READ_CBLOCK(sdbc_safestore,
- cc_ent->cc_write->sc_res, taddr,
- CACHE_BLOCK_SIZE, 0) == SS_ERR) {
-
- cmn_err(CE_WARN, "sdbc(sdbc_get_cd_blk) "
- "!safestore read failed");
- rc = EFAULT;
-
- } else if (copyout(taddr, (void *)addr[4],
- CACHE_BLOCK_SIZE)) {
- cmn_err(CE_WARN,
- "!sdbc(sdbc_get_cd_blk) copyout failed."
- " cannot get write data");
- rc = EFAULT;
- }
- }
-
- }
-
- if (taddr)
- kmem_free(taddr, CACHE_BLOCK_SIZE);
-
- return (rc);
-}
-
-/* ARGSUSED */
-static int
-sdbcioctl(dev_t dev, int cmd, void *arg, int mode, cred_t *crp, int *rvp)
-{
- int rc = 0;
- _sdbc_ioctl_t args;
- int convert_32 = 0;
- spcs_s_info_t kstatus;
-
- *rvp = 0;
-
-#ifdef _MULTI_DATAMODEL
- if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
- int rc;
- convert_32 = 1;
- if ((rc = convert_ioctl_args(cmd, arg, mode, &args)) != 0)
- return (rc);
- } else {
- if (ddi_copyin(arg, &args, sizeof (_sdbc_ioctl_t), mode)) {
- return (EFAULT);
- }
- }
-#else /* _MULTI_DATAMODEL */
- if (ddi_copyin(arg, &args, sizeof (_sdbc_ioctl_t), mode)) {
- return (EFAULT);
- }
-#endif /* _MULTI_DATAMODEL */
-
- kstatus = spcs_s_kcreate();
- if (!kstatus)
- return (ENOMEM);
-
- switch (cmd) {
-
- case SDBC_UNUSED_1:
- case SDBC_UNUSED_2:
- case SDBC_UNUSED_3:
-
- return (spcs_s_ocopyoutf(&kstatus, args.sdbc_ustatus,
- SDBC_EOBSOLETE));
-
- case SDBC_ADUMP:
- rc = _sd_adump(&args, rvp);
- break;
-
- case SDBC_TEST_INIT:
- rc = _sd_test_init(&args);
- break;
-
- case SDBC_TEST_START:
- rc = _sd_test_start(&args, rvp);
- break;
-
- case SDBC_TEST_END:
- rc = _sd_test_end();
- break;
-
- case SDBC_ENABLE:
- mutex_enter(&_sdbc_config_lock);
- rc = _sdbc_configure((_sd_cache_param_t *)args.arg0,
- NULL, kstatus);
- if (rc && rc != EALREADY && rc != SDBC_ENONETMEM) {
- (void) _sdbc_deconfigure(kstatus);
- mutex_exit(&_sdbc_config_lock);
- return (spcs_s_ocopyoutf
- (&kstatus, args.sdbc_ustatus, rc));
- }
- mutex_exit(&_sdbc_config_lock);
- return (spcs_s_ocopyoutf(&kstatus, args.sdbc_ustatus, rc));
-
- case SDBC_DISABLE:
- mutex_enter(&_sdbc_config_lock);
- if (_sd_cache_initialized == 0) {
-
- mutex_exit(&_sdbc_config_lock);
- return (spcs_s_ocopyoutf(&kstatus, args.sdbc_ustatus,
- SDBC_EDISABLE));
- }
- rc = _sdbc_deconfigure(kstatus);
- mutex_exit(&_sdbc_config_lock);
- return (spcs_s_ocopyoutf(&kstatus, args.sdbc_ustatus, rc));
-
- case SDBC_GET_CLUSTER_SIZE:
- if (_sd_cache_initialized == 0) {
-
- return (spcs_s_ocopyoutf(&kstatus, args.sdbc_ustatus,
- SDBC_ECLUSTER_SIZE));
- }
-
- rc = sd_get_file_info_size((void *)args.arg0);
- break;
-
- /* get the gl_file data */
- case SDBC_GET_CLUSTER_DATA:
- if (_sd_cache_initialized == 0) {
-
- return (spcs_s_ocopyoutf(&kstatus, args.sdbc_ustatus,
- SDBC_ECLUSTER_DATA));
- }
- rc = sd_get_file_info_data((void *)args.arg0);
- break;
-
- /* get the size of the global info pages for each board */
- case SDBC_GET_GLMUL_SIZES:
- if (_sd_cache_initialized == 0) {
- return (spcs_s_ocopyoutf(&kstatus, args.sdbc_ustatus,
- SDBC_EGLMUL_SIZE));
- }
- rc = sd_get_glmul_sizes((void *)args.arg0);
- break;
-
- /* get the global info about write blocks */
- case SDBC_GET_GLMUL_INFO:
- if (_sd_cache_initialized == 0) {
-
- return (spcs_s_ocopyoutf(&kstatus, args.sdbc_ustatus,
- SDBC_EGLMUL_INFO));
-
- }
- rc = sd_get_glmul_info((void *)args.arg0);
- break;
-
- case SDBC_SET_CD_HINT:
- if (_sd_cache_initialized == 0)
- return (spcs_s_ocopyoutf(&kstatus,
- args.sdbc_ustatus, EINVAL));
- rc = ((args.arg2) ?
- _sd_set_hint((int)args.arg0, (uint_t)args.arg1) :
- _sd_clear_hint((int)args.arg0, (uint_t)args.arg1));
- return (spcs_s_ocopyoutf(&kstatus, args.sdbc_ustatus, rc));
-
- case SDBC_GET_CD_HINT:
- {
- uint_t hint;
-
- if (_sd_cache_initialized == 0)
- return (spcs_s_ocopyoutf(&kstatus,
- args.sdbc_ustatus, EINVAL));
- if ((rc = _sd_get_cd_hint((int)args.arg0, &hint)) == 0)
- *rvp = hint;
- return (spcs_s_ocopyoutf(&kstatus, args.sdbc_ustatus,
- rc));
- }
-
- case SDBC_SET_NODE_HINT:
- rc = ((args.arg1) ? _sd_set_node_hint((uint_t)args.arg0) :
- _sd_clear_node_hint((uint_t)args.arg0));
- if (rc)
- return (spcs_s_ocopyoutf(&kstatus, args.sdbc_ustatus,
- rc));
- /* FALLTHRU */
- case SDBC_GET_NODE_HINT:
- {
- uint_t hint;
- if ((rc = _sd_get_node_hint(&hint)) == 0)
- *rvp = hint;
- return (spcs_s_ocopyoutf(&kstatus, args.sdbc_ustatus,
- rc));
- }
-
- case SDBC_STATS:
- rc = _sd_get_stats((void *)args.arg0, convert_32);
- return (spcs_s_ocopyoutf(&kstatus, args.sdbc_ustatus, rc));
-
- case SDBC_ZAP_STATS:
- _sd_zap_stats();
- return (spcs_s_ocopyoutf(&kstatus, args.sdbc_ustatus, 0));
-
- case SDBC_GET_CD_BLK:
- if (_sd_cache_initialized == 0)
- return (spcs_s_ocopyoutf(&kstatus,
- args.sdbc_ustatus, EINVAL));
- rc = sdbc_get_cd_blk(&args, mode);
- break;
-
- case SDBC_GET_CONFIG:
- {
- _sdbc_config_t sdbc_config_info;
-
- if (ddi_copyin((void *)args.arg0,
- &sdbc_config_info,
- sizeof (_sdbc_config_t),
- mode)) {
- spcs_s_kfree(kstatus);
- return (EFAULT);
- }
- rc = _sdbc_get_config(&sdbc_config_info);
- (void) ddi_copyout(&sdbc_config_info,
- (void *)args.arg0,
- sizeof (_sdbc_config_t),
- mode);
- return (spcs_s_ocopyoutf(&kstatus, args.sdbc_ustatus, rc));
- }
-
- case SDBC_SET_CONFIG:
- {
- _sdbc_config_t mgmt_config_info;
-
- if (ddi_copyin((void *)args.arg0,
- &mgmt_config_info,
- sizeof (_sdbc_config_t),
- mode)) {
- spcs_s_kfree(kstatus);
- return (EFAULT);
- }
-
- rc = _sdbc_configure(NULL, &mgmt_config_info, kstatus);
- if (rc && rc != EALREADY) {
- (void) _sdbc_deconfigure(kstatus);
- return (spcs_s_ocopyoutf
- (&kstatus, args.sdbc_ustatus, rc));
- }
-
- return (spcs_s_ocopyoutf(&kstatus, args.sdbc_ustatus, rc));
- }
-
- case SDBC_MAXFILES:
- if (copyout(&sdbc_max_devs, (void *)args.arg0,
- sizeof (sdbc_max_devs)))
- rc = EFAULT;
- else
- rc = 0;
-
- break;
-
- case SDBC_VERSION:
- {
- cache_version_t cache_version;
-
- cache_version.major = sdbc_major_rev;
- cache_version.minor = sdbc_minor_rev;
- cache_version.micro = sdbc_micro_rev;
- cache_version.baseline = sdbc_baseline_rev;
-
- if (ddi_copyout(&cache_version, (void *)args.arg0,
- sizeof (cache_version_t), mode)) {
- rc = EFAULT;
- break;
- }
-
- break;
- }
-
-
-#ifdef DEBUG
- /* toggle flusher flag for testing */
- case SDBC_TOGGLE_FLUSH:
- _sdbc_flush_flag ^= 1;
- *rvp = _sdbc_flush_flag;
- rc = 0;
-
- return (spcs_s_ocopyoutf(&kstatus, args.sdbc_ustatus,
- SDBC_ETOGGLE_FLUSH, _sdbc_flush_flag ? "on" : "off"));
-
-
- /* inject i/o errors */
- case SDBC_INJ_IOERR: /* cd, errnum */
- if (_sd_cache_initialized == 0)
- return (spcs_s_ocopyoutf(&kstatus,
- args.sdbc_ustatus, EINVAL));
- rc = _sdbc_inject_ioerr(args.arg0, args.arg1, args.arg2);
- break;
-
- /* clear injected i/o errors */
- case SDBC_CLR_IOERR: /* cd */
- if (_sd_cache_initialized == 0)
- return (spcs_s_ocopyoutf(&kstatus,
- args.sdbc_ustatus, EINVAL));
- rc = _sdbc_clear_ioerr(args.arg0);
- break;
-
-#endif /* DEBUG */
- default:
- _sd_print(3, "!SDBC unknown ioctl: 0x%x unsupported", cmd);
- rc = EINVAL;
- break;
- }
-
- spcs_s_kfree(kstatus);
- return (rc);
-}
-
-
-/*
- * _sd_timed_block - sleep waiting for ticks time delay.
- * ticks - # of ticks to sleep
- * cvp - pointer to the cv we wait on while we delay.
- *
- * NO spin locks can be held at entry!
- *
- */
-void
-_sd_timed_block(clock_t ticks, kcondvar_t *cvp)
-{
- mutex_enter(&_sd_block_lk);
- (void) cv_reltimedwait(cvp, &_sd_block_lk, ticks, TR_CLOCK_TICK);
- mutex_exit(&_sd_block_lk);
-}
-
-
-/*
- * _sd_unblock - awake a sleeper waiting on cv pointed to by cvp.
- *
- * NO spin locks can be held at entry as we may sleep.
- *
- */
-void
-_sd_unblock(kcondvar_t *cvp)
-{
-
- mutex_enter(&_sd_block_lk);
- cv_broadcast(cvp);
- mutex_exit(&_sd_block_lk);
-}
-
-/* ARGSUSED */
-void
-_sd_data_log(int num, _sd_cctl_t *centry, nsc_off_t st, nsc_size_t len)
-{
-#if defined(_SD_FBA_DATA_LOG)
- nsc_size_t i;
- nsc_off_t blk;
-
- blk = BLK_TO_FBA_NUM(CENTRY_BLK(centry));
- for (i = st; i < (st + len); i++)
- SDTRACE(num, CENTRY_CD(centry), 1, blk + i,
- *(int *)(centry->cc_data + FBA_SIZE(i)),
- *(int *)(centry->cc_data + FBA_SIZE(i) + 4));
-#endif /* _SD_FBA_DATA_LOG */
-}
-
-/* ARGSUSED */
-void
-_sd_data_log_chain(int num, _sd_cctl_t *centry, nsc_off_t fba_pos,
- nsc_size_t fba_len)
-{
-#if defined(_SD_FBA_DATA_LOG)
- sdbc_cblk_fba_t st_cblk_len; /* FBA len of starting cache block */
- sdbc_cblk_fba_t end_cblk_len; /* FBA len of ending cache block */
- sdbc_cblk_fba_t st_cblk_off; /* FBA offset into starting cblock */
-
- while (CENTRY_BLK(centry) != FBA_TO_BLK_NUM(fba_pos))
- centry = centry->cc_chain;
-
- st_cblk_off = BLK_FBA_OFF(fba_pos);
- st_cblk_len = BLK_FBAS - st_cblk_off;
- if (st_cblk_len >= fba_len) {
- end_cblk_len = 0;
- st_cblk_len = fba_len;
- } else {
- end_cblk_len = BLK_FBA_OFF(fba_pos + fba_len);
- }
-
- DATA_LOG(num, centry, st_cblk_off, st_cblk_len);
-
- fba_len -= st_cblk_len;
- centry = centry->cc_chain;
-
- while (fba_len > end_cblk_len) {
- DATA_LOG(num, centry, 0, BLK_FBAS);
- fba_len -= BLK_FBAS;
- centry = centry->cc_chain;
- }
- if (end_cblk_len) DATA_LOG(num, centry, 0, end_cblk_len);
-#endif /* _SD_FBA_DATA_LOG */
-}
-
-
-void
-_sd_zap_stats(void)
-{
- int i;
-
- if (_sd_cache_stats == NULL)
- return;
-
- _sd_cache_stats->st_rdhits = 0;
- _sd_cache_stats->st_rdmiss = 0;
- _sd_cache_stats->st_wrhits = 0;
- _sd_cache_stats->st_wrmiss = 0;
- _sd_lru_q.sq_noreq_stat = 0;
- _sd_lru_q.sq_req_stat = 0;
-
- for (i = 0; i < sdbc_max_devs; i++) {
- _sd_cache_stats->st_shared[i].sh_cache_read = 0;
- _sd_cache_stats->st_shared[i].sh_cache_write = 0;
- _sd_cache_stats->st_shared[i].sh_disk_read = 0;
- _sd_cache_stats->st_shared[i].sh_disk_write = 0;
- }
-}
-
-
-/*
- * Return the cache sizes used by the Sense Subsystem Status CCW
- */
-int
-_sd_cache_sizes(int *asize, int *wsize)
-{
- int psize;
-
- *asize = 0;
- *wsize = 0;
-
- /*
- * add in the total cache size and the
- * non-volatile (battery-backed) cache size.
- */
- if (_sd_net_config.sn_configured) {
- psize = _sd_net_config.sn_psize;
- *asize += (_sd_net_config.sn_cpages * psize);
- *wsize += (safestore_config.ssc_wsize);
- }
-
- return (0);
-}
-
-
-/*PRINTFLIKE2*/
-void
-_sd_print(int level, char *fmt, ...)
-{
- va_list adx;
- if (level <= _sd_debug_level) {
- va_start(adx, fmt);
- vcmn_err(CE_NOTE, fmt, adx);
- va_end(adx);
-
- }
-}
-
-
-int
-_sd_get_cd_blk(int cd, nsc_off_t cblk, _sd_cctl_t **cc, caddr_t *data,
- char **filename)
-{
- _sd_cctl_t *cc_ent;
-
- if (FILE_OPENED(cd) != 0) {
- *filename = _sd_cache_files[cd].cd_info->sh_filename;
- if (cc_ent = (_sd_cctl_t *)
- _sd_hash_search(cd, cblk, _sd_htable)) {
- *cc = cc_ent;
- *data = (caddr_t)cc_ent->cc_data;
- return (0);
- }
- }
- return (-1);
-}
-
-/*
- * central dyn mem processing vars edit rtn.
- * input a local copy and xfer to global
- *
- * sec0,sec1,sec2
- * range check 1 to 255 (arbitrary but in any case must be <= 2000 due to
- * 32bit signed int limits in later calc)
- * aging_ct
- * range check 1 to 255 (only 8 bits reserved for aging ctr)
- *
- */
-int
-sdbc_edit_xfer_process_vars_dm(_dm_process_vars_t *process_vars)
-{
- if (process_vars->max_dyn_list > 0)
- dynmem_processing_dm.max_dyn_list = process_vars->max_dyn_list;
-
- /* no edit on monitor_dynmem_process */
- dynmem_processing_dm.monitor_dynmem_process =
- process_vars->monitor_dynmem_process;
- /* no edit on process_directive */
- dynmem_processing_dm.process_directive =
- process_vars->process_directive;
-
- if (process_vars->cache_aging_ct1 > 0 &&
- process_vars->cache_aging_ct1 <= CACHE_AGING_CT_MAX)
- dynmem_processing_dm.cache_aging_ct1 =
- process_vars->cache_aging_ct1;
- if (process_vars->cache_aging_ct2 > 0 &&
- process_vars->cache_aging_ct2 <= CACHE_AGING_CT_MAX)
- dynmem_processing_dm.cache_aging_ct2 =
- process_vars->cache_aging_ct2;
- if (process_vars->cache_aging_ct3 > 0 &&
- process_vars->cache_aging_ct3 <= CACHE_AGING_CT_MAX)
- dynmem_processing_dm.cache_aging_ct3 =
- process_vars->cache_aging_ct3;
- if (process_vars->cache_aging_sec1 > 0 &&
- process_vars->cache_aging_sec1 <= CACHE_AGING_SEC1_MAX)
- dynmem_processing_dm.cache_aging_sec1 =
- process_vars->cache_aging_sec1;
- if (process_vars->cache_aging_sec2 > 0 &&
- process_vars->cache_aging_sec2 <= CACHE_AGING_SEC2_MAX)
- dynmem_processing_dm.cache_aging_sec2 =
- process_vars->cache_aging_sec2;
- if (process_vars->cache_aging_sec3 > 0 &&
- process_vars->cache_aging_sec3 <= CACHE_AGING_SEC3_MAX)
- dynmem_processing_dm.cache_aging_sec3 =
- process_vars->cache_aging_sec3;
- if (process_vars->cache_aging_pcnt1 >= 0 &&
- process_vars->cache_aging_pcnt1 <= CACHE_AGING_PCNT1_MAX)
- dynmem_processing_dm.cache_aging_pcnt1 =
- process_vars->cache_aging_pcnt1;
- if (process_vars->cache_aging_pcnt2 >= 0 &&
- process_vars->cache_aging_pcnt2 <= CACHE_AGING_PCNT2_MAX)
- dynmem_processing_dm.cache_aging_pcnt2 =
- process_vars->cache_aging_pcnt2;
- if (process_vars->max_holds_pcnt >= 0 &&
- process_vars->max_holds_pcnt <= MAX_HOLDS_PCNT_MAX)
- dynmem_processing_dm.max_holds_pcnt =
- process_vars->max_holds_pcnt;
- return (0);
-}
-
-dev_info_t *
-sdbc_get_dip()
-{
- return (dev_dip);
-}
diff --git a/usr/src/uts/common/avs/ns/sdbc/sd_misc.h b/usr/src/uts/common/avs/ns/sdbc/sd_misc.h
deleted file mode 100644
index aed864d82d..0000000000
--- a/usr/src/uts/common/avs/ns/sdbc/sd_misc.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SD_MISC_H
-#define _SD_MISC_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define _SD_FIFO_WAIT 1000
-#define _SD_FIFO_WSPIN 100
-#ifdef _KERNEL
-
-extern _dm_process_vars_t dynmem_processing_dm;
-
-extern int sdbc_wrthru_len;
-extern nsc_size_t sdbc_max_fbas;
-extern int sdbc_max_devs;
-
-
-extern int _init(void);
-extern void _sd_data_log(int num, _sd_cctl_t *centry, nsc_off_t st,
- nsc_size_t len);
-extern void _sd_data_log_chain(int num, _sd_cctl_t *centry, nsc_off_t fba_pos,
- nsc_size_t fba_len);
-extern int _sd_reflect_ignore(ucaddr_t from, ucaddr_t to, int size);
-extern int _sd_reflect(ucaddr_t from, ucaddr_t to, int size, int flag);
-extern void _sd_timed_block(clock_t ticks, kcondvar_t *cvp);
-extern void _sd_unblock(kcondvar_t *cvp);
-extern void _sd_zap_stats(void);
-extern int _sd_cache_sizes(int *asize, int *wsize);
-extern void _sd_print(int level, char *fmt, ...);
-extern int _sd_get_cd_blk(int cd, nsc_off_t blk, _sd_cctl_t **cc, caddr_t *data,
- char **filename);
-
-#endif /* _KERNEL */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SD_MISC_H */
diff --git a/usr/src/uts/common/avs/ns/sdbc/sd_mkiob.sh b/usr/src/uts/common/avs/ns/sdbc/sd_mkiob.sh
deleted file mode 100644
index 276261b03b..0000000000
--- a/usr/src/uts/common/avs/ns/sdbc/sd_mkiob.sh
+++ /dev/null
@@ -1,77 +0,0 @@
-#!/usr/bin/sh
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# Build-time script to generate the sd_iob_implX.c files.
-#
-START="$1"
-END="$2"
-FILE="$3"
-
-awk '
-/#define.*_SD_DEFAULT_IOBUFS/ {
- num = $3;
-printf("/* start = %d, end = %d, num %d */\n", start, end, num);
- if (num > end) {
- num = end;
- }
-printf("/* start = %d, end = %d, num %d */\n", start, end, num);
-}
-
-END {
- printf("/* start = %d, end = %d, num %d */\n", start, end, num);
- printf("#include <sys/types.h>\n");
- printf("#include <sys/param.h>\n");
- printf("#include <sys/ksynch.h>\n");
- printf("#include <sys/kmem.h>\n");
- printf("#include <sys/stat.h>\n");
- printf("#include <sys/buf.h>\n");
- printf("#include <sys/open.h>\n");
- printf("#include <sys/conf.h>\n");
- printf("#include <sys/file.h>\n");
- printf("#include <sys/cmn_err.h>\n");
- printf("#include <sys/errno.h>\n");
- printf("#include <sys/debug.h>\n");
- printf("#include <sys/ddi.h>\n");
- printf("#include <sys/nsc_thread.h>\n");
- printf("#include <sys/nsctl/sd_bcache.h>\n");
- printf("#include <sys/nsctl/sd_trace.h>\n");
- printf("#include <ns/sdbc/sd_io.h>\n");
- printf("#include <ns/sdbc/sd_iob.h>\n");
-
- n = start;
- while (n < num) {
- printf("IOB_DCB(%d)", n);
- n = n + 1;
-
- if (n % 4) {
- printf(" ");
- } else {
- printf("\n");
- if (!((n - start) % 2048) && (n < num))
- printf("static int _cscope_brkline%d;\n", n);
- }
- }
-}' start=$START end=$END incdir=`dirname $FILE` $FILE
-
-exit 0
diff --git a/usr/src/uts/common/avs/ns/sdbc/sd_pcu.c b/usr/src/uts/common/avs/ns/sdbc/sd_pcu.c
deleted file mode 100644
index 556a0659c9..0000000000
--- a/usr/src/uts/common/avs/ns/sdbc/sd_pcu.c
+++ /dev/null
@@ -1,874 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/ksynch.h>
-#include <sys/cmn_err.h>
-#include <sys/errno.h>
-#include <sys/kmem.h>
-#include <sys/cred.h>
-#include <sys/buf.h>
-#include <sys/ddi.h>
-#include <sys/nsc_thread.h>
-
-
-#include "sd_bcache.h"
-#include "sd_trace.h"
-#include "sd_io.h"
-#include "sd_bio.h"
-#include "sd_ft.h"
-#include "sd_misc.h"
-#include "sd_pcu.h"
-
-/*
- * PCU (aka UPS) handling -
- */
-#define bitmap_next cc_dirty_link
-#define bitmap_tail cc_dirty_next
-
-#define anon_next cc_dirty_link
-#define anon_tail cc_dirty_next
-#define anon_data cc_data
-
-struct bitmap {
- _sd_cctl_t *bmps;
- int bmaps_per_block;
- int inuse; /* In use in the _last_ block */
-};
-
-#define SDBC_PCU_MAXSWAPIL 3 /* Watch for 5 fields in ioctl arg. */
-
-struct swapfiles {
- int nswpf; /* Number of filenames */
- int colsize; /* In cache blocks */
- char *names[SDBC_PCU_MAXSWAPIL];
-};
-
-static void _sdbc_pcu_cleanup(struct swapfiles *);
-
-/*
- * Forward declare functions containing 64-bit argument types to enforce
- * type-checking.
- */
-static int add_bitmap_entry(struct bitmap *bmp, _sd_bitmap_t bits, int any_fail,
- nsc_off_t fba_num);
-static int flush_bitmap_list(struct bitmap *bmp, dev_t dev, nsc_off_t *blkno);
-static int flush_centry_list(_sd_cd_info_t *cdi, _sd_cctl_t *dirty, dev_t dev,
- nsc_off_t *blkno, int failed, struct bitmap *bmaps);
-static int flush_hdr(_sd_cctl_t *hdr, dev_t dev, nsc_off_t blkno);
-static int flush_anon_list(_sd_cctl_t *anon_list, dev_t dev, nsc_off_t *blkno);
-static void sdbc_anon_copy(caddr_t src, nsc_size_t len, _sd_cctl_t *dest,
- nsc_off_t dest_off);
-static void sdbc_anon_get(_sd_cctl_t *src, nsc_off_t src_off, caddr_t dest,
- nsc_size_t len);
-static _sd_cctl_t *sdbc_get_anon_list(nsc_size_t bytes);
-
-static int got_hint; /* did we capture hint at power_lost */
-static unsigned int wrthru_hint; /* saved hint at power_lost */
-static int saw_power_lost;
-
-char _sdbc_shutdown_in_progress;
-static struct swapfiles swfs;
-
-/*
- * sdbc_get_anon_list - allocate a set of anonymous cache block
- * entries that can pretend to be a single blocks of data holding
- * a virtual character array holding "bytes" entries.
- *
- * returns - the cache block heading the chain.
- */
-static _sd_cctl_t *
-sdbc_get_anon_list(nsc_size_t bytes)
-{
- _sd_cctl_t *list, *prev;
- nsc_size_t i, blks;
-
- prev = NULL;
- blks = (bytes + CACHE_BLOCK_SIZE - 1) / CACHE_BLOCK_SIZE;
- for (i = 0; i < blks; i++) {
-
- list = sdbc_centry_alloc_blks(_CD_NOHASH, 0, 1, 0);
- bzero(list->cc_data, CACHE_BLOCK_SIZE);
- list->anon_next = prev;
- prev = list;
- };
-
- return (list);
-}
-
-/*
- * sdbc_anon_get - gets "len" bytes of data virtual character array represented
- * by "src" begining at index "dest_off" and copy to buffer "dest".
- *
- * dest - pointer to our virtual array (chain of cache blocks).
- * dest_off - first location to copy data to.
- * src - pointer to data to copy
- * len - the number of bytes of data to copy
- *
- */
-static void
-sdbc_anon_get(_sd_cctl_t *src, nsc_off_t src_off, caddr_t dest, nsc_size_t len)
-{
- nsc_size_t i;
- nsc_size_t nlen;
- nsc_off_t blk_start, blk_end;
-
- if (len == 0)
- return;
-
- blk_start = src_off / CACHE_BLOCK_SIZE;
- blk_end = (src_off + len) / CACHE_BLOCK_SIZE;
-
- for (i = 0; i < blk_start; i++) {
- src = src->anon_next;
- src_off -= CACHE_BLOCK_SIZE;
- }
-
- nlen = min(len, CACHE_BLOCK_SIZE - src_off);
- bcopy(&src->anon_data[src_off], dest, (size_t)nlen);
-
- for (i = 1; i < blk_end - blk_start; i++) {
- bcopy(src->anon_data, &dest[nlen], (size_t)CACHE_BLOCK_SIZE);
- nlen += CACHE_BLOCK_SIZE;
- src = src->anon_next;
- }
- if (nlen != len) {
- bcopy(src->anon_data, &dest[nlen], (size_t)(len - nlen));
- }
-}
-
-/*
- * sdbc_anon_copy - copies "len" bytes of data from "src" to the
- * virtual character array represented by "dest" begining at index
- * "dest_off".
- *
- * src - pointer to data to copy
- * len - the number of bytes of data to copy
- * dest - pointer to our virtual array (chain of cache blocks).
- * dest_off - first location to copy data to.
- *
- */
-static void
-sdbc_anon_copy(caddr_t src, nsc_size_t len, _sd_cctl_t *dest,
- nsc_off_t dest_off)
-{
- nsc_size_t i;
- nsc_size_t nlen;
- nsc_off_t blk_start, blk_end;
-
- if (len == 0)
- return;
-
- blk_start = dest_off / CACHE_BLOCK_SIZE;
- blk_end = (dest_off + len) / CACHE_BLOCK_SIZE;
-
- for (i = 0; i < blk_start; i++) {
- dest = dest->anon_next;
- dest_off -= CACHE_BLOCK_SIZE;
- }
-
- nlen = min(len, CACHE_BLOCK_SIZE - dest_off);
- bcopy(src, &dest->anon_data[dest_off], (size_t)nlen);
-
- for (i = 1; i < blk_end - blk_start; i++) {
- bcopy(&src[nlen], dest->anon_data, (size_t)CACHE_BLOCK_SIZE);
- nlen += CACHE_BLOCK_SIZE;
- dest = dest->anon_next;
- }
- if (nlen != len) {
- bcopy(&src[nlen], dest->anon_data, (size_t)(len - nlen));
- }
-}
-
-/*
- * flush_anon_list - flush a chain of anonymous cache blocks
- * to the state file. Anonymous chains of cache blocks represent
- * virtual arrays for the state flushing code and can contain
- * various types of data.
- *
- * anon_list - chain of cache blocks to flush.
- *
- * dev - the state file device
- *
- * blkno - on input the cache block number to begin writing at.
- * On exit the next cache block number following the data
- * just written.
- *
- * returns - 0 on success, error number on failure.
- */
-static int
-flush_anon_list(_sd_cctl_t *anon_list,
- dev_t dev,
- nsc_off_t *blkno)
-{
- struct buf *bp;
- int rc;
- _sd_cctl_t *prev;
- nsc_size_t bcnt;
-
- if (anon_list == NULL)
- return (0);
-
- bcnt = 0;
- do {
- bp = sd_alloc_iob(dev, BLK_TO_FBA_NUM(*blkno),
- BLK_TO_FBA_NUM(1), 0);
- sd_add_fba(bp, &anon_list->cc_addr, 0, BLK_FBAS);
- rc = sd_start_io(bp, NULL, NULL, 0);
- (*blkno)++;
-
- /*
- * A failure here is death. This is harsh but not sure
- * what else to do
- */
-
- if (rc != NSC_DONE)
- return (rc);
- bcnt++;
-
- prev = anon_list;
- anon_list = anon_list->anon_next;
- _sd_centry_release(prev);
-
- } while (anon_list);
-
- cmn_err(CE_CONT, "sdbc(flush_anon_list) %" NSC_SZFMT "\n", bcnt);
- return (0);
-
-}
-
-/*
- * start_bitmap_list - allocate an anonymous cache block entry
- * to anchor a chain of cache blocks representing a virtual
- * array of bitmap entries.
- *
- * returns - the cache block heading the chain.
- */
-static void
-start_bitmap_list(struct bitmap *bmp, int bpb)
-{
- _sd_cctl_t *list;
-
- list = sdbc_centry_alloc_blks(_CD_NOHASH, 0, 1, 0);
- bzero(list->cc_data, CACHE_BLOCK_SIZE);
- list->bitmap_next = NULL;
- list->bitmap_tail = list;
-
- bmp->bmps = list;
- bmp->inuse = 0;
- bmp->bmaps_per_block = bpb;
-}
-
-/*
- * add_bitmap_entry - Add a bitmap entry to the chain of bitmap
- * entries we are creating for cd's entry in the state file.
- *
- * Bitmaps are stored in a chain of anonymous cache blocks. Each
- * cache block can hold bmaps_per_block in it. As each block is
- * filled a new block is added to the tail of the chain.
- *
- * list - the chain of cache blocks containing the bitmaps.
- * bits - the bitmap entry to add.
- * any_fail - flag saying whether the data corresponding to this
- * bitmap entry had previously failed going to disk.
- * fba_num - FBA number corresponding to the entry.
- *
- * returns - 0 on success, error number on failure.
- */
-static int
-add_bitmap_entry(struct bitmap *bmp,
- _sd_bitmap_t bits, int any_fail, nsc_off_t fba_num)
-{
- sdbc_pwf_bitmap_t *bmap;
- _sd_cctl_t *list = bmp->bmps;
- int i;
-
- bmap = (sdbc_pwf_bitmap_t *)list->bitmap_tail->cc_data;
- if (bmp->inuse == bmp->bmaps_per_block) {
- _sd_cctl_t *nlist;
-
- nlist = sdbc_centry_alloc_blks(_CD_NOHASH, 0, 1, 0);
- bzero(nlist->cc_data, CACHE_BLOCK_SIZE);
- nlist->bitmap_next = NULL;
- nlist->bitmap_tail = NULL;
- list->bitmap_tail->bitmap_next = nlist;
- list->bitmap_tail = nlist;
- bmp->inuse = 0;
- }
- i = bmp->inuse++;
- bmap->bitmaps[i].fba_num = fba_num;
- bmap->bitmaps[i].dirty = bits;
- bmap->bitmaps[i].errs = (char)any_fail;
-
- return (0);
-}
-
-/*
- * flush_bitmap_list - flush a chain of anonymous cache blocks
- * containing the dirty/valid bitmaps for a set of cache blocks.
- *
- * b_list - the chain of bitmap data.
- * dev - the state file device.
- * blkno - on input the cache block number to begin writing at.
- * On exit the next cache block number following the data
- * just written.
- *
- * returns - 0 on success, error number on failure.
- */
-static int
-flush_bitmap_list(struct bitmap *bmp, dev_t dev, nsc_off_t *blkno)
-{
- _sd_cctl_t *b_list;
- struct buf *bp;
- int rc;
- _sd_cctl_t *prev;
- int bcnt = 0; /* P3 temp */
-
- if ((b_list = bmp->bmps) == NULL)
- return (0);
-
- do {
- bp = sd_alloc_iob(dev, BLK_TO_FBA_NUM(*blkno),
- BLK_TO_FBA_NUM(1), 0);
- sd_add_fba(bp, &b_list->cc_addr, 0, BLK_FBAS);
- rc = sd_start_io(bp, NULL, NULL, 0);
- (*blkno)++;
-
- /*
- * A failure here is death. This is harsh but not sure
- * what else to do
- */
-
- if (rc != NSC_DONE)
- return (rc);
- bcnt++;
-
- prev = b_list;
- b_list = b_list->bitmap_next;
- _sd_centry_release(prev);
-
- } while (b_list);
- cmn_err(CE_CONT, "sdbc(flush_bitmap_list) %d\n", bcnt); /* P3 */
-
- return (0);
-
-}
-
-/*
- * flush_centry_list - flush a chain of cache blocks for the
- * cache descriptor described by "cdi" to the state file.
- * In addition the bitmaps describing the validity and dirty
- * state of each entry are captured to the bitmap chain.
- *
- * cdi - pointer to description of the cd we are writing.
- * dirty - chain of dirty cache blocks to flush (linked
- * by dirty_next (sequential) and dirty_link (disjoint).
- *
- * dev - the state file device.
- *
- * blkno - on input the cache block number to begin writing at.
- * On exit the next cache block number following the data
- * just written.
- *
- * failed - a flag noting whether these blocks had already
- * been attempted to write to their true destination and
- * failed. (i.e. is the chain from fail_head).
- *
- * bmaps - a chain of anonymous cache blocks containing all
- * the dirty/valid bitmaps for the cache blocks we write.
- *
- * returns - 0 on success, error number on failure.
- */
-static int
-flush_centry_list(_sd_cd_info_t *cdi,
- _sd_cctl_t *dirty,
- dev_t dev,
- nsc_off_t *blkno,
- int failed,
- struct bitmap *bmaps)
-{
- _sd_cctl_t *cc_ent;
- nsc_size_t count; /* count of cache blocks in a sequential chain */
- struct buf *bp;
- int rc;
- int bcnt = 0;
-
- if (dirty == NULL)
- return (0);
-
- mutex_enter(&cdi->cd_lock);
-
- do {
- /*
- * each cache block is written to the disk regardless of its
- * valid/dirty masks.
- */
- count = 0;
- cc_ent = dirty;
- do {
- count++;
- cc_ent = cc_ent->cc_dirty_next;
- } while (cc_ent);
-
- bp = sd_alloc_iob(dev, BLK_TO_FBA_NUM(*blkno),
- BLK_TO_FBA_NUM(count), 0);
-
- cc_ent = dirty;
- do {
- sd_add_fba(bp, &cc_ent->cc_addr, 0, BLK_FBAS);
- rc = add_bitmap_entry(bmaps,
- cc_ent->cc_dirty | cc_ent->cc_toflush, failed,
- BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent)));
- if (rc)
- return (rc);
- cc_ent = cc_ent->cc_dirty_next;
- } while (cc_ent);
-
- *blkno += count;
- rc = sd_start_io(bp, NULL, NULL, 0);
-
- /*
- * A failure here is death. This is harsh but not sure
- * what else to do
- */
-
- if (rc != NSC_DONE)
- return (rc);
- bcnt += count;
-
- dirty = dirty->cc_dirty_link;
- } while (dirty);
- cmn_err(CE_CONT, "sdbc(flush_centry_list) %d\n", bcnt); /* P3 */
-
- mutex_exit(&cdi->cd_lock);
- return (0);
-}
-
-/*
- * flush_hdr - Flush the state file header to the disk partition
- * "dev" at FBA "blkno". Return the result of the i/o operation.
- * hdr - a cache block containing the header.
- * dev - the state file device.
- * blkno - cache block position to write the header.
- *
- * returns - 0 on success, error number on failure.
- */
-static int
-flush_hdr(_sd_cctl_t *hdr, dev_t dev, nsc_off_t blkno)
-{
- struct buf *bp;
- int rc;
-
- bp = sd_alloc_iob(dev, BLK_TO_FBA_NUM(blkno), BLK_TO_FBA_NUM(1), 0);
- sd_add_fba(bp, &hdr->cc_addr, 0, BLK_FBAS);
- rc = sd_start_io(bp, NULL, NULL, 0);
- _sd_centry_release(hdr);
- return (rc);
-
-}
-
-/*
- * _sdbc_power_flush - flushd the state of sdbc to the state "file"
- * on the system disk. All dirty blocks (in progress, unscheduled,
- * failed) are written along with the bitmap for each block. The
- * data is written using normal sdbc i/o via anonymous cache blocks.
- * This is done to simplify the job here (and to limit memory
- * requests) at the expense of making the recovery programs more
- * complex. Since recovery is done at user level this seems to be
- * a good trade off.
- *
- * Returns: 0 on success, error number on failure.
- */
-static int
-_sdbc_power_flush(void)
-{
- _sd_cctl_t *name_pool;
- int string_size;
-
- sdbc_pwf_hdr_t *hdr;
- _sd_cctl_t *hdrblk;
-
- struct bitmap bmap;
-
- _sd_cd_info_t *cdi;
- int open_files;
- _sd_cctl_t *file_pool;
- sdbc_pwf_desc_t current;
-
- nsc_fd_t *state_fd;
- dev_t state_rdev;
- int devmaj, devmin;
- nsc_off_t blkno;
- long len;
- long total_len;
- int pending;
- int rc = 0;
-
- /*
- * Force wrthru just in case SLM software didn't really send us a
- * warning. (Also makes for easier testing)
- */
- (void) _sd_set_node_hint(NSC_FORCED_WRTHRU);
- /* disable all (dangerous) cache entry points */
-
- cmn_err(CE_CONT, "sdbc(sdbc_power_flush) hint set..\n"); /* P3 */
-
- _sdbc_shutdown_in_progress = 1;
-
-#if 0
- if (sdbc_io && (rc = nsc_unregister_io(sdbc_io, NSC_PCATCH)) != 0) {
- /*
- * this is bad, in theory we could just busy-out all our
- * interfaces and continue.
- */
- cmn_err(CE_WARN,
- "sdbc(_sdbc_power_flush) couldn't unregister i/o %d", rc);
- return (rc);
- }
-
- sdbc_io = NULL;
-#endif
-
- /* wait for all i/o to finish/timeout ? */
-
- if ((pending = _sdbc_wait_pending()) != 0)
- cmn_err(CE_NOTE, "sdbc(_sdbc_power_flush) %d I/Os were"
- " pending at power shutdown", pending);
-
- cmn_err(CE_CONT, "sdbc(sdbc_power_flush) over pending\n"); /* P3 */
-
- /* prevent any further async flushing */
-
- _sdbc_flush_deconfigure();
-
- /*
- * At this point no higher level clients should be able to get thru.
- * Failover i/o from the other node is our only other concern as
- * far as disturbing the state of sdbc.
- */
-
- /* figure out the names for the string pool */
-
- string_size = 0;
- open_files = 0;
- cdi = _sd_cache_files;
- do {
-
- if (cdi->cd_info == NULL)
- continue;
- if (cdi->cd_info->sh_alloc == 0)
- continue;
- open_files++;
- string_size += strlen(cdi->cd_info->sh_filename) + 1;
- } while (++cdi != &_sd_cache_files[sdbc_max_devs]);
-
- if (open_files == 0) {
- return (0);
- }
-
- hdrblk = sdbc_centry_alloc_blks(_CD_NOHASH, 0, 1, 0);
- bzero(hdrblk->cc_data, CACHE_BLOCK_SIZE);
- hdr = (sdbc_pwf_hdr_t *)hdrblk->cc_data;
- hdr->magic = SDBC_PWF_MAGIC;
- hdr->alignment = CACHE_BLOCK_SIZE;
- hdr->cd_count = open_files;
- /* XXX bmap_size is redundant */
- hdr->bmap_size = CACHE_BLOCK_SIZE / sizeof (sdbc_pwf_bitmap_t);
-
- name_pool = sdbc_get_anon_list(string_size);
- file_pool = sdbc_get_anon_list(sizeof (sdbc_pwf_desc_t) * open_files);
-
- open_files = 0;
- cdi = _sd_cache_files;
- total_len = 0;
- do {
-
- if (cdi->cd_info == NULL)
- continue;
- if (cdi->cd_info->sh_alloc == 0)
- continue;
-
- len = strlen(cdi->cd_info->sh_filename) + 1;
-
- /* copy the name to string pool */
- sdbc_anon_copy(cdi->cd_info->sh_filename,
- len, name_pool, total_len);
-
- bzero(&current, sizeof (current));
- current.name = total_len;
- sdbc_anon_copy((caddr_t)&current, sizeof (current), file_pool,
- open_files * sizeof (sdbc_pwf_desc_t));
-
- open_files++;
- total_len += len;
-
- } while (++cdi != &_sd_cache_files[sdbc_max_devs]);
-
- /* flush dirty data */
-
- if (swfs.nswpf == 0 || swfs.names[0] == NULL) {
- cmn_err(CE_WARN, "sdbc(_sdbc_power_flush): State file"
- " is not configured");
- rc = ENODEV;
- goto cleanup;
- }
-
- if (!(state_fd =
- nsc_open(swfs.names[0], NSC_DEVICE, NULL, NULL, &rc)) ||
- !nsc_getval(state_fd, "DevMaj", (int *)&devmaj) ||
- !nsc_getval(state_fd, "DevMin", (int *)&devmin)) {
- if (state_fd) {
- (void) nsc_close(state_fd);
- }
- /*
- * We are hosed big time. We can't get device to write the
- * state file opened.
- */
- cmn_err(CE_WARN, "sdbc(_sdbc_power_flush): Couldn't "
- "open %s for saved state file", swfs.names[0]);
- rc = EIO;
- goto cleanup;
- }
-
- state_rdev = makedevice(devmaj, devmin);
-
- blkno = 1;
-
- hdr->string_pool = blkno;
- rc = flush_anon_list(name_pool, state_rdev, &blkno);
-
- hdr->descriptor_pool = blkno;
- rc = flush_anon_list(file_pool, state_rdev, &blkno);
-
- /*
- * iterate across all devices, flushing the data and collecting bitmaps
- */
-
- open_files = 0;
- for (cdi = _sd_cache_files;
- cdi != &_sd_cache_files[sdbc_max_devs]; cdi++) {
- nsc_off_t blk2;
- nsc_off_t fp_off;
-
- if (cdi->cd_info == NULL)
- continue;
- if (cdi->cd_info->sh_alloc == 0)
- continue;
-
- /* retrieve the file description so we can update it */
- fp_off = (open_files++) * sizeof (sdbc_pwf_desc_t);
- sdbc_anon_get(file_pool, fp_off,
- (caddr_t)&current, sizeof (current));
-
- current.blocks = blkno;
-
- if (cdi->cd_io_head) {
- /*
- * Need to wait for this to timeout?
- * Seems like worst case we just write the data twice
- * so we should be ok.
- */
- /*EMPTY*/
- ;
- }
-
- start_bitmap_list(&bmap, hdr->bmap_size);
-
- /* Flush the enqueued dirty data blocks */
-
- (void) flush_centry_list(cdi, cdi->cd_dirty_head, state_rdev,
- &blkno, 0, &bmap);
- cdi->cd_dirty_head = NULL;
- cdi->cd_dirty_tail = NULL;
-
- /* Flush the failed dirty data blocks */
-
- (void) flush_centry_list(cdi, cdi->cd_fail_head, state_rdev,
- &blkno, 1, &bmap);
- cdi->cd_fail_head = NULL;
-
- /*
- * Flush the in progress dirty data blocks. These really should
- * really be null by now. Worst case we write the data again
- * on recovery as we know the dirty masks won't change since
- * flusher is stopped.
- */
-
- (void) flush_centry_list(cdi, cdi->cd_io_head, state_rdev,
- &blkno, 0, &bmap);
- cdi->cd_io_head = NULL;
- cdi->cd_io_tail = NULL;
-
- current.bitmaps = blkno;
- current.nblocks = blkno - current.blocks;
-
- (void) flush_bitmap_list(&bmap, state_rdev, &blkno);
-
- /* update the current cd's file description */
- sdbc_anon_copy((caddr_t)&current, sizeof (current), file_pool,
- fp_off);
-
- blk2 = hdr->descriptor_pool;
- rc = flush_anon_list(file_pool, state_rdev, &blk2);
- }
-
-#if !defined(_SunOS_5_6)
- hdr->dump_time = ddi_get_time();
-#else
- hdr->dump_time = hrestime.tv_sec;
-#endif
- /* write the header at front and back */
- (void) flush_hdr(hdrblk, state_rdev, blkno);
- (void) flush_hdr(hdrblk, state_rdev, 0L);
-
- /* P3 */
- cmn_err(CE_CONT, "sdbc(sdbc_power_flush) %" NSC_SZFMT " total\n",
- blkno);
-
-cleanup:
- ;
- return (rc);
-
-}
-
-/*
- * _sdbc_power_lost - System is running on UPS power we have "rideout"
- * minutes of power left prior to shutdown. Get into a state where we
- * will be ready should we need to shutdown.
- *
- * ARGUMENTS:
- * rideout - minutes of power left prior to shutdown.
- */
-void
-_sdbc_power_lost(int rideout)
-{
- cmn_err(CE_WARN, "sdbc(_sdbc_power_lost) battery time "
- "remaining %d minute(s)", rideout);
-
- got_hint = 1;
- if (_sd_get_node_hint(&wrthru_hint))
- got_hint = 0;
-
- cmn_err(CE_WARN, "sdbc(_sdbc_power_lost) got hint %d "
- "hint 0x%x", got_hint, wrthru_hint);
-
- (void) _sd_set_node_hint(NSC_FORCED_WRTHRU);
- saw_power_lost = 1;
-}
-
-/*
- * _sdbc_power_ok - System is back running on mains power after
- * seeing a power fail. Return to normal power up operation.
- *
- */
-void
-_sdbc_power_ok(void)
-{
- cmn_err(CE_WARN, "sdbc(_sdbc_power_ok) power ok");
- if (saw_power_lost && got_hint) {
- /*
- * In theory we have a race here between _sdbc_power_lost
- * and here. However it is expected that power ioctls that
- * cause these to be generated are sequential in nature
- * so there is no race.
- */
- saw_power_lost = 0;
- if (wrthru_hint & _SD_WRTHRU_MASK)
- (void) _sd_set_node_hint(wrthru_hint & _SD_WRTHRU_MASK);
- else
- (void) _sd_clear_node_hint(_SD_WRTHRU_MASK);
- }
-}
-
-/*
- * _sdbc_power_down - System is running on UPS power and we must stop
- * operation as the machine is now going down. Schedule a shutdown
- * thread.
- *
- * When we return all cache activity will be blocked.
- */
-void
-_sdbc_power_down(void)
-{
- cmn_err(CE_WARN, "sdbc(_sdbc_power_down) powering down...");
- (void) _sdbc_power_flush();
-}
-
-/*
- * Configure safe store from the general cache configuration ioctl.
- */
-int
-_sdbc_pcu_config(int namec, char **namev)
-{
- int i;
-
- if (swfs.nswpf != 0) {
- /*
- * This should not happen because cache protects itself
- * from double configuration in sd_conf.c.
- */
- cmn_err(CE_CONT, "sdbc(_sdbc_pcu_config) double "
- "configuration of Safe Store\n");
- return (EINVAL);
- }
- swfs.colsize = 32; /* No way to configure in the general ioctl */
-
- for (i = 0; i < namec; i++) {
- if ((swfs.names[i] = kmem_alloc(strlen(namev[i])+1,
- KM_NOSLEEP)) == NULL) {
- _sdbc_pcu_cleanup(&swfs);
- return (ENOMEM);
- }
- swfs.nswpf++;
- (void) strcpy(swfs.names[i], namev[i]);
- }
-
- return (0);
-}
-
-/*
- */
-void
-_sdbc_pcu_unload()
-{
- _sdbc_pcu_cleanup(&swfs);
-}
-
-/*
- * Destructor for struct swapfiles.
- */
-static void
-_sdbc_pcu_cleanup(struct swapfiles *swp)
-{
- int i;
- char *s;
-
- for (i = 0; i < swp->nswpf; i++) {
- if ((s = swp->names[i]) != NULL)
- kmem_free(s, strlen(s)+1);
- swp->names[i] = NULL;
- }
- swp->nswpf = 0;
-}
diff --git a/usr/src/uts/common/avs/ns/sdbc/sd_pcu.h b/usr/src/uts/common/avs/ns/sdbc/sd_pcu.h
deleted file mode 100644
index 4545aab0f4..0000000000
--- a/usr/src/uts/common/avs/ns/sdbc/sd_pcu.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SD_PCU_H
-#define _SD_PCU_H
-
-/*
- * All structures here are on-disk, unless specified otherwise.
- * In-core stuff is hidden inside implementation modules.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Header.
- */
-#define SDBC_PWF_MAGIC 0xbcbcbc01
-
-typedef struct sdbc_pwf_hdr_s {
- int32_t magic; /* magic number to distinguish file revs */
- int32_t alignment; /* all sections are multiples of this */
- /* a cache block is this identical size */
- int32_t bmap_size; /* number of entries in each bitmap entry */
- int32_t cd_count; /* number of devices we have data for */
- nsc_off_t string_pool; /* offset in file to pool of filenames */
- nsc_off_t descriptor_pool; /* offset in file to dbc_pwf_desc_t vector */
- int64_t dump_time; /* Timestamp == longest time_t */
-} sdbc_pwf_hdr_t;
-
-/*
- * File description
- */
-typedef struct sdbc_pwf_desc_s {
- int32_t pad0;
- uint32_t name; /* name + stringpool == offset of filename */
- /* the name given to nsc_open */
- nsc_off_t blocks; /* offset into swap for this device's data */
- nsc_off_t bitmaps; /* offset into swap for data bitmaps */
- /* (i.e. nothing to do with rdc bitmaps */
- uint64_t nblocks; /* number of data blocks == bitmap dimension */
- /* long rdc_data; */ /* offset to rdc data (NYI) */
-} sdbc_pwf_desc_t;
-
-/*
- * record status section - describes the state of each cache block in the file
- *
- * zaitcev - XXX errs is per block, not per fba?
- */
-typedef struct sdbc_pwf_rec_s {
- uint32_t dirty; /* Bitmap of dirty fba'a (_sd_bitmap_t) */
- int32_t errs; /* error status per fba, needed to recover */
- /* from errors to a raidset where we must recover */
- /* from a stripe write error */
- /* (i.e. parity is bad or suspect ) */
- nsc_off_t fba_num; /* the block on the disk */
-} sdbc_pwf_rec_t;
-
-typedef struct sdbc_pwf_bitmap_s {
- sdbc_pwf_rec_t bitmaps[1]; /* dynamic array based on cache block size */
-} sdbc_pwf_bitmap_t;
-
-/*
- * Prototypes
- */
-#ifdef _KERNEL /* XXX Split into sd_pcu_ondisk.h, sd_pcu_iface.h */
-extern char _sdbc_shutdown_in_progress;
-
-extern int _sdbc_pcu_config(int c, char **v);
-extern void _sdbc_pcu_unload(void);
-extern void _sdbc_power_lost(int rideout);
-extern void _sdbc_power_ok(void);
-extern void _sdbc_power_down(void);
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SD_PCU_H */
diff --git a/usr/src/uts/common/avs/ns/sdbc/sd_tdaemon.c b/usr/src/uts/common/avs/ns/sdbc/sd_tdaemon.c
deleted file mode 100644
index 1a7069ce33..0000000000
--- a/usr/src/uts/common/avs/ns/sdbc/sd_tdaemon.c
+++ /dev/null
@@ -1,1157 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * Routines for the Infinity Storage Device daemon
- */
-
-#include <sys/types.h>
-#include <sys/ksynch.h>
-#include <sys/cmn_err.h>
-#include <sys/errno.h>
-#include <sys/buf.h>
-#include <sys/kmem.h>
-#include <sys/cred.h>
-#include <sys/ddi.h>
-#include <sys/nsc_thread.h>
-
-#include "sd_bcache.h"
-#include "sd_io.h"
-#include "sd_bio.h"
-#include "sd_ft.h"
-#include "sd_misc.h"
-
-#define _INFSD_LOCAL_MEM
-
-#define _CD_VTRK_SIZE(cd) (dev_tsize[GET_CD_STATE(cd)] * 1024)
-#define _CD_VTRK_NUM(cd, len) ((len)/_CD_VTRK_SIZE(cd))
-#define _CD_VTRK_OFF(cd, len) ((len)%(_CD_VTRK_SIZE(cd)))
-
-#define FILESIZE (1 << 27) /* 128 MB */
-
-#define SIZEMASK 0x0000FFFF
-#define _INFSD_RECORD_SIZE(ndx) REC_SIZE
-#define GET_SEED(ndx) (gld[ndx] . seed & SIZEMASK)
-#define MAX_CD_STS 600
-#define MAX_TDAEMONS 128
-
-static char devarray[MAX_TDAEMONS][MAX_TDAEMONS*2];
-static int dev_tsize[MAX_TDAEMONS*2];
-static int dev_flag[MAX_TDAEMONS*2];
-
-
-/*
- * sd_test options
- */
-#define SD_TEST_CACHE_HIT 0x00000001
-#define SD_TEST_CACHE_MISS 0x00000002
-#define SD_TEST_CHECK_DATA 0x00000004
-#define SD_TEST_READ_ONLY 0x00000008
-#define SD_TEST_WRITE_ONLY 0x00000010
-#define SD_TEST_SEQUENTIAL 0x00000020
-
-static struct cd_sts {
- volatile short cd_state;
- volatile char waiting;
- volatile char inited;
- kcondvar_t cd_blk;
- volatile caddr_t asy_key;
-} cd_test_sts[MAX_CD_STS];
-
-#define SET_CD_STATE(cd, i) (cd_test_sts[(cd)].cd_state = (short)(i))
-#define GET_CD_STATE(cd) (cd_test_sts[(cd)].cd_state)
-
-static kmutex_t tdaemon_lock;
-static kcondvar_t _wait_daemons;
-dev_t _test_async_fail; /* fail async writes to cache dev_t */
-static volatile int test_stop;
-
-static int daemon_awake(int i);
-static void wakeup_all_tdaemons(void);
-static void _sd_idle_daemon(void);
-static void _td_detach_cd(int cd);
-static int _fork_test_daemon(int num_disks, int test_typ, int loop_cnt,
- int from, int seed);
-static void _sd_test_rwloop_seq(int i, int loops, int seed, int forw);
-static int _sd_copy_pattern_to_handle(_sd_buf_handle_t *handle,
- nsc_off_t fba_pos, nsc_size_t fba_len);
-static int _sd_copy_handle(_sd_buf_handle_t *handle1, _sd_buf_handle_t *handle2,
- nsc_off_t fba_pos1, nsc_off_t fba_pos2, nsc_size_t fba_len, int skew);
-static int _sd_compare_handle(_sd_buf_handle_t *handle1,
- _sd_buf_handle_t *handle2, nsc_off_t fba_pos1, nsc_off_t fba_pos2,
- nsc_size_t fba_len, int skew);
-static void _sd_direct_test(int c, int loop, int seed, int type);
-static void set_parameters(void);
-static void test_dma_loop(int net, int seg);
-static int _sd_hwrite(_sd_buf_handle_t *buf, nsc_off_t fba_pos,
- nsc_size_t fba_len, int flag);
-static void myend(blind_t arg, nsc_off_t fba_pos, nsc_size_t fba_len,
- int error);
-static int test_control(int typ, int cd, nsc_off_t fba_pos, nsc_size_t fba_len);
-
-int
-_sim_write(_sd_buf_handle_t *buf, int x)
-{
- int rval;
-
- if (test_stop)
- return (EINVAL);
- rval = _sd_write(buf, buf->bh_fba_pos, buf->bh_fba_len, x);
- return (rval == NSC_HIT ? NSC_DONE : rval);
-}
-
-static int
-_sd_hwrite(_sd_buf_handle_t *buf, nsc_off_t fba_pos, nsc_size_t fba_len,
- int flag)
-{
- int rval;
-
- rval = _sd_write(buf, fba_pos, fba_len, flag);
- return (rval == NSC_HIT ? NSC_DONE : rval);
-}
-
-#define _sd_allocate_buf _trk_allocate_buf
-#define _sd_write _sim_write
-
-/*
- * INF SD daemon global data
- */
-
-volatile int test_created;
-static int _sd_daemon_created;
-static int _sd_num_daemons;
-
-static struct gld {
- volatile int type;
- volatile int loop;
- volatile int seed;
- volatile int asleep;
- kcondvar_t blk;
-} gld[MAX_TDAEMONS];
-
-/*
- * _sdbc_tdaemon_load: cache is being loaded, initialize any global state that
- * isn't configurable (lock/sv's).
- */
-int
-_sdbc_tdaemon_load(void)
-{
- int i;
-
- for (i = 0; i < MAX_TDAEMONS; i++)
- cv_init(&gld[i].blk, NULL, CV_DRIVER, NULL);
-
- mutex_init(&tdaemon_lock, NULL, MUTEX_DRIVER, NULL);
- cv_init(&_wait_daemons, NULL, CV_DRIVER, NULL);
-
- return (0);
-}
-/*
- * _sdbc_tdaemon_unload: cache is being unloaded.
- */
-void
-_sdbc_tdaemon_unload(void)
-{
- int i;
-
- for (i = 0; i < MAX_TDAEMONS; i++) {
- cv_destroy(&gld[i].blk);
- }
-
- mutex_destroy(&tdaemon_lock);
- cv_destroy(&_wait_daemons);
-
-}
-
-/*
- * _sdbc_tdaemon_configure: configure the desired number of test daemons.
- */
-int
-_sdbc_tdaemon_configure(int num)
-{
- int i;
-
- if (num >= MAX_TDAEMONS)
- return (-1);
-
- for (i = 0; i < num; i++) {
- cv_init(&gld[i].blk, NULL, CV_DRIVER, NULL);
- }
- mutex_enter(&tdaemon_lock);
- test_created = 1;
- test_stop = 0;
- _sd_num_daemons = 0;
- mutex_exit(&tdaemon_lock);
-
- mutex_enter(&_sd_cache_lock);
- if (_sd_daemon_created == 1) {
- mutex_exit(&_sd_cache_lock);
- return (-1);
- }
- _sd_daemon_created = 1;
- mutex_exit(&_sd_cache_lock);
-
- for (i = 0; i < num; i++) {
- (void) nsc_create_process(
- (void (*)(void *))_sd_idle_daemon, 0, FALSE);
- }
-
-#ifdef DEBUG
- if (num)
- cmn_err(CE_NOTE, "!Starting %d SDBC test daemon(s).", num);
-#endif
- return (0);
-}
-
-void
-_sdbc_tdaemon_deconfigure(void)
-{
- int i, running, retry = 30;
-
- if (_sd_num_daemons) {
- _sd_daemon_created = 0;
-
- mutex_enter(&tdaemon_lock);
- test_created = 0;
- test_stop = 1;
- mutex_exit(&tdaemon_lock);
-
- wakeup_all_tdaemons();
- while (retry--) {
- delay(HZ);
- running = 0;
- for (i = 0; i < _sd_num_daemons; i++)
- if (daemon_awake(i))
- running++;
- if (running == 0) break;
- }
- }
- for (i = 0; i < MAX_CD_STS; i++) {
- cv_destroy(&cd_test_sts[i].cd_blk);
- cd_test_sts[i].inited = 0;
- }
- _sd_num_daemons = 0;
-}
-
-
-int sind = 0;
-
-/*
- * Globals to change test parameters - Initially added for tests written
- * by Ajay
- */
-#ifdef SD_TDAEMON_DEBUG
-struct statis {
- int cd;
- nsc_size_t len;
- nsc_off_t offset;
- int type;
-} statis[4000];
-
-#define add_statis(c, l, o, t) (statis[sind].cd = (c), \
- statis[sind].len = (l), \
- statis[sind].offset = (o), \
- statis[sind].type = (t), sind++)
-int
-statis_upd(caddr_t adr)
-{
- (void) copyout(statis, adr, sizeof (struct statis) * sind);
- return (sind);
-}
-#endif /* SD_TDAEMON_DEBUG */
-
-static int
-daemon_awake(int i)
-{
- if (gld[i].asleep == 2)
- return (1);
- return (0);
-}
-
-static int
-daemon_nexist(int i)
-{
- if (gld[i].asleep == 0)
- return (1);
- return (0);
-}
-
-static void
-daemon_wakeup(int i)
-{
-#ifdef _SD_DEBUG
- cmn_err(CE_NOTE, "!unblocking %d %x", i, gld[i].blk);
-#endif
- mutex_enter(&tdaemon_lock);
- cv_broadcast(&gld[i].blk);
- mutex_exit(&tdaemon_lock);
-}
-
-
-static void
-wakeup_all_tdaemons(void)
-{
- int i;
-
- for (i = 0; i < _sd_num_daemons; i++)
- daemon_wakeup(i);
-}
-
-
-static void
-_sd_idle_daemon(void)
-{
- int who; /* id of this daemon */
-
- mutex_enter(&_sd_cache_lock);
- _sd_cache_dem_cnt++;
- who = _sd_num_daemons++;
- mutex_exit(&_sd_cache_lock);
-
- /* CONSTCOND */
- while (1) {
- mutex_enter(&tdaemon_lock);
- gld[who].asleep = 1;
-#ifdef DEBUG
- cmn_err(CE_NOTE, "!%d daemon: sleeping %p", who,
- (void *)&gld[who].blk);
-#endif
-
- cv_signal(&_wait_daemons);
- if (test_created == 0) {
- gld[who].asleep = 0;
- mutex_exit(&tdaemon_lock);
- mutex_enter(&_sd_cache_lock);
- _sd_cache_dem_cnt--;
- mutex_exit(&_sd_cache_lock);
- return;
- } else {
- cv_wait(&gld[who].blk, &tdaemon_lock);
- mutex_exit(&tdaemon_lock);
- }
-
- _sd_print(0, "%d daemon awake type %d loop %d seed %d",
- who, gld[who].type, gld[who].loop, GET_SEED(who));
-
- if (test_created == 0) {
- gld[who].asleep = 0;
- mutex_enter(&_sd_cache_lock);
- _sd_cache_dem_cnt--;
- mutex_exit(&_sd_cache_lock);
- return;
- }
- gld[who].asleep = 2;
-
- switch (gld[who].type) {
-
- case 210:
- test_dma_loop(gld[who].loop, gld[who].seed);
- break;
- case 323:
- _sd_direct_test(who, gld[who].loop, GET_SEED(who), 0);
- break;
-
- case 350:
- _sd_test_rwloop_seq(who, gld[who].loop, GET_SEED(who),
- 1);
- break;
- case 351:
- _sd_test_rwloop_seq(who, gld[who].loop, GET_SEED(who),
- 0);
- break;
-
-#if 0
- case 400:
- if (gld[who].loop >= 6)
- numdevs = gld[who].loop;
- break;
-#endif
- default:
- cmn_err(CE_WARN, "!%d daemon %d type inval\n", who,
- gld[who].type);
- break;
- }
- if (test_created == 0) {
- gld[who].asleep = 0;
- mutex_enter(&_sd_cache_lock);
- _sd_cache_dem_cnt--;
- mutex_exit(&_sd_cache_lock);
- return;
- }
- }
-}
-
-
-static void
-_td_attach_cd(int cd)
-{
- (void) nsc_reserve(_sd_cache_files[cd].cd_rawfd, NSC_MULTI);
-}
-
-
-static void
-_td_detach_cd(int cd)
-{
- nsc_release(_sd_cache_files[cd].cd_rawfd);
-}
-
-
-int
-_sd_test_start(void *args, int *rvp)
-{
-
- register struct a {
- long num;
- long type;
- long loop;
- long from;
- long seed;
- } *uap = (struct a *)args;
-
- *rvp = _fork_test_daemon(uap->num, uap->type, uap->loop,
- uap->from, uap->seed);
-
- return (0);
-}
-
-static int
-test_control(int typ, int cd, nsc_off_t fba_pos, nsc_size_t fba_len)
-/*
- * test_control - perform control operations outside of the range
- * of a test. This is typically called before/after a series of
- * tests to either check a result or to setup/free a device.
- */
-{
- int rc = 0;
-
- if ((cd < 0) || (cd >= sdbc_max_devs))
- return (-1);
- switch (typ) {
- case 1:
- rc = _sdbc_io_attach_cd((blind_t)(unsigned long)cd);
- cmn_err(CE_NOTE, "!_sdbc_io_attach_cd(%d): %d", cd, rc);
- break;
- case 2:
- rc = _sdbc_io_detach_cd((blind_t)(unsigned long)cd);
- cmn_err(CE_NOTE, "!_sdbc_io_detach_cd(%d): %d", cd, rc);
- break;
- case 3:
- _test_async_fail = _sd_cache_files[cd].cd_crdev;
- cmn_err(CE_NOTE, "!async fail dev %lu (cd=%d)",
- _test_async_fail, cd);
- break;
- case 4:
- _test_async_fail = 0;
- cmn_err(CE_NOTE, "!async fail cleared");
- break;
-#if 0
- case 5:
- _trk_alloc_flag = NSC_PINNABLE;
- break;
- case 6:
- _trk_alloc_flag = 0;
- break;
-#endif
- case 7:
- rc = _sd_get_pinned((blind_t)(unsigned long)cd);
- cmn_err(CE_NOTE, "!get_pinned(%d): %d", cd, rc);
- break;
- case 8:
- rc = _sd_discard_pinned((blind_t)(unsigned long)cd, fba_pos,
- fba_len);
- cmn_err(CE_NOTE, "!discard_pinned(%d,%" NSC_SZFMT ",%" NSC_SZFMT
- "): %d", cd, fba_pos, fba_len, rc);
- break;
- default:
- cmn_err(CE_WARN, "!cache device command %d invalid\n", typ);
- }
- return (rc);
-}
-
-
-/*
- * _fork_sd_daemon(): Fork an nunix process that periodically flushes the
- * raw device buffer cache
- */
-
-static int
-_fork_test_daemon(int num_disks, int test_typ, int loop_cnt, int from, int seed)
-{
- int i;
- int type;
- int dowait = 0, verify = 0;
-
- if (num_disks == -1) {
- return (test_control(test_typ, loop_cnt, from, seed));
- }
-
- type = test_typ;
- cmn_err(CE_NOTE,
- "!sd_test %d %d %d %d %d", num_disks, type, loop_cnt, from, seed);
- if (type == 100) {
- test_stop = 1;
- return (0);
- }
-
- if (type == 99) {
- /* Set some parameters for other tests */
- switch (num_disks) {
- /* Params set for this test */
-#if 0
- case 302 :
- _sd_write_len = loop_cnt;
- break;
- case 303 :
- _sd_write_len = loop_cnt;
- break;
- case 304 :
- _sd_trk_zero = loop_cnt;
- _sd_trk_size = from;
- break;
- case 305 :
- _sd_min_blks = loop_cnt;
- _sd_max_blks = from;
- break;
-#endif
- default :
- cmn_err(CE_WARN,
- "!Usage : sd_test <test_num> 99"
- " <param1> <param2> <param3>");
- break;
- }
- return (0);
- } /* type == 99 */
-
- if (type > 1000) {
- dowait = 1;
- type -= 1000;
- }
- if (type > 1000) {
- verify = 1;
- type -= 1000;
- }
-
-again:
- set_parameters();
-
- for (i = from; i < (from+num_disks); i++) {
- if (daemon_awake(i)) {
- cmn_err(CE_WARN, "!Daemon %d awake!?", i);
- return (-1);
- }
- if (daemon_nexist(i)) {
- cmn_err(CE_WARN, "!Daemon %d nexist!?", i);
- return (-1);
- }
-
- gld[i].type = type;
- gld[i].loop = loop_cnt;
- gld[i].seed = seed;
- daemon_wakeup(i);
- }
- cmn_err(CE_CONT, "!%d daemons woken (test %d)\n", num_disks, type);
- if (num_disks <= 0)
- return (0);
-
- if (dowait) {
- wait:
- mutex_enter(&tdaemon_lock);
- if (!cv_wait_sig(&_wait_daemons, &tdaemon_lock)) {
- mutex_exit(&tdaemon_lock);
- test_stop = 1;
- cmn_err(CE_WARN, "!Interrupt: stopping tests");
- return (-1); /* interrupt */
- }
- mutex_exit(&tdaemon_lock);
-
- /* wait for all to stop */
- if (test_stop)
- return (-1);
- for (i = from; i < (from+num_disks); i++) {
- if (daemon_awake(i))
- goto wait;
- }
- }
- if (verify) {
- verify = 0;
- type++; /* next test */
- goto again;
- }
- return (0);
-}
-
-int
-_sd_test_end(void)
-{
- test_created = 0;
- test_stop = 1;
- return (0);
-}
-
-int
-_sd_test_init(void *args)
-{
- register struct a {
- caddr_t addr;
- long ar;
- long len;
- long tsize;
- long flag;
- } *uap = (struct a *)args;
-
- if (copyin(uap->addr, devarray[uap->ar], uap->len)) {
- return (EFAULT);
- }
- dev_tsize[uap->ar] = (uap->tsize < 48) ? 48 : uap->tsize;
- dev_flag[uap->ar] = uap->flag;
- return (0);
-}
-
-
-typedef struct io_type {
- int cd, tsize;
- _sd_buf_handle_t *wbuf, *rbuf;
- int len, len2, rnet, wnet;
- int trk_num, trk_off;
- int offset, boff;
- char test_pattern;
-} infnsc_io_t;
-
-/* static spinlock_t INFSD_iolock = { SLK_IFS_SRVR, 0 }; */
-#define _INFSD_TRK_SIZE() (64*1024)
-#define _INFSD_BUF_ALIGN 512 /* Each read/write should be 512 aligned */
-
-/*
- * _sd_test_rwloop_seq(i,loops, seed, forw):
- *
- * Sequential I/O test. Writes track records sequentially, either forwards
- * or backwards (forw = 1 or forw = 0), writing a fixed pattern with a
- * few unique bytes depending on loop id. Then reads back, checking
- * for data consistency.
- */
-
-/* ARGSUSED */
-static void
-_sd_test_rwloop_seq(int i, int loops, int seed, int forw)
-{
- int cd;
- int j, len;
- nsc_off_t offset;
- nsc_size_t fsize;
- int sts;
- _sd_buf_handle_t *fbuf, *buf;
-
- if (strlen(devarray[i]) == 0) {
- cmn_err(CE_WARN, "!child %d devarray null", i);
- return;
- }
- if ((cd = _sd_open(devarray[i], dev_flag[i])) < 0) {
- cmn_err(CE_WARN, "!Open error %s child %d", devarray[i], i);
- return;
- }
- SET_CD_STATE(cd, i);
- _td_attach_cd(cd);
-
- (void) _sd_get_partsize((blind_t)(unsigned long)cd, &fsize);
- len = 120;
-
- /*
- * Write a base pattern into the first buffer
- */
- fbuf = NULL;
- offset = 0;
- sts = _sd_alloc_buf((blind_t)(unsigned long)cd, 0, len, NSC_WRBUF,
- &fbuf);
- if (sts > 0) {
- cmn_err(CE_WARN, "!Buffer alloc failed %d", sts);
- return;
- }
- (void) _sd_copy_pattern_to_handle(fbuf, 0, len);
- _td_detach_cd(cd);
-
- offset = 0;
- for (j = 0; j < loops; j++) {
- if (test_stop == 1) goto done;
-
- offset += len;
- if (offset + len > fsize)
- break;
-
- buf = NULL;
- _td_attach_cd(cd);
- sts = _sd_alloc_buf((blind_t)(unsigned long)cd, offset, len,
- NSC_WRBUF, &buf);
- if (sts > 0) {
- cmn_err(CE_WARN, "!ch%d getbuf error(WRBUF)%d", i, sts);
- goto done;
- }
- (void) _sd_copy_handle(fbuf, buf, 0, offset, len, j);
-
- sts = len;
- while (sts > 0) {
- if (forw && _sd_hwrite(buf, offset + len - sts,
- 12, 0) > 0) {
- cmn_err(CE_WARN, "!ch %d fwwr err", i);
- test_stop = 1;
- }
- sts -= 12;
- if (!forw && _sd_hwrite(buf, offset + sts, 12, 0) > 0) {
- cmn_err(CE_WARN, "!ch %d rvwr err", i);
- test_stop = 1;
- }
- }
- if (sts = _sd_free_buf(buf)) {
- cmn_err(CE_WARN, "!ch %d freebuf error %d", i, sts);
- goto done;
- }
- _td_detach_cd(cd);
- }
- offset = 0;
- for (j = 0; j < loops; j++) {
- if (test_stop == 1) goto done;
-
- offset += len;
- if (offset + len > fsize)
- break;
-
- buf = NULL;
- _td_attach_cd(cd);
- sts = _sd_alloc_buf((blind_t)(unsigned long)cd, offset, len,
- NSC_RDBUF, &buf);
- if (sts > 0) {
- cmn_err(CE_WARN, "!ch%d getbuf error(WRBUF)%d", i, sts);
- goto done;
- }
- (void) _sd_compare_handle(fbuf, buf, 0, offset, len, j);
-
- if (sts = _sd_free_buf(buf)) {
- cmn_err(CE_WARN, "!ch %d freebuf error %d", i, sts);
- goto done;
- }
- _td_detach_cd(cd);
- }
-done:
- if (sts = _sd_free_buf(fbuf))
- cmn_err(CE_WARN, "!child %d freebuf error %d", i, sts);
- cmn_err(CE_NOTE, "!TEST OVER : rwloop_seq_%s() child %d",
- forw ? "forw" : "rev", i);
-}
-
-static int
-_sd_copy_pattern_to_handle(_sd_buf_handle_t *handle, nsc_off_t fba_pos,
- nsc_size_t fba_len)
-{
- sdbc_cblk_fba_t st_cblk_len; /* FBA len of starting cache block */
- sdbc_cblk_fba_t end_cblk_len; /* FBA len of ending cache block */
- sdbc_cblk_fba_t st_cblk_off; /* FBA offset into starting cblock */
- nsc_size_t cur_fba_len;
- int i;
- _sd_cctl_t *cc_ent;
-
- cc_ent = handle->bh_centry;
- while (CENTRY_BLK(cc_ent) != FBA_TO_BLK_NUM(fba_pos))
- cc_ent = cc_ent->cc_chain;
-
- cur_fba_len = fba_len;
- st_cblk_off = BLK_FBA_OFF(fba_pos);
- st_cblk_len = (BLK_FBAS - st_cblk_off);
- if ((nsc_size_t)st_cblk_len >= fba_len) {
- end_cblk_len = 0;
- st_cblk_len = (sdbc_cblk_fba_t)fba_len;
- } else
- end_cblk_len = BLK_FBA_OFF(fba_pos + fba_len);
-
- for (i = 0; i < (int)FBA_SIZE(st_cblk_len); i += 4)
- *((uint_t *)(void *)(cc_ent->cc_data + FBA_SIZE(st_cblk_off) +
- i)) = nsc_usec();
- cur_fba_len -= st_cblk_len;
- cc_ent = cc_ent->cc_chain;
-
- while (cur_fba_len > (nsc_size_t)end_cblk_len) {
- for (i = 0; i < CACHE_BLOCK_SIZE; i += 4) {
- unsigned int usec = nsc_usec();
- bcopy(&usec, cc_ent->cc_data + i, 4);
- }
- cc_ent = cc_ent->cc_chain;
- cur_fba_len -= BLK_FBAS;
- }
- if (cur_fba_len) {
- for (i = 0; i < (int)FBA_SIZE(end_cblk_len); i += 4) {
- unsigned int usec = nsc_usec();
- bcopy(&usec, cc_ent->cc_data + i, 4);
- }
- }
- return (0);
-}
-
-static int
-_sd_copy_handle(_sd_buf_handle_t *handle1,
- _sd_buf_handle_t *handle2,
- nsc_off_t fba_pos1,
- nsc_off_t fba_pos2,
- nsc_size_t fba_len,
- int skew)
-{
- sdbc_cblk_fba_t st_cblk_len; /* FBA len of starting cache block */
- sdbc_cblk_fba_t end_cblk_len; /* FBA len of ending cache block */
- sdbc_cblk_fba_t st_cblk_off; /* FBA offset into starting cblock */
- nsc_size_t cur_fba_len;
- _sd_cctl_t *cc_ent, *cc_ent1;
- unsigned char *skew_word;
- int skew_count = 0;
-
- ASSERT_HANDLE_LIMITS(handle1, fba_pos1, fba_len);
- ASSERT_HANDLE_LIMITS(handle2, fba_pos2, fba_len);
-
- cc_ent = handle1->bh_centry;
- while (CENTRY_BLK(cc_ent) != FBA_TO_BLK_NUM(fba_pos1))
- cc_ent = cc_ent->cc_chain;
-
- cc_ent1 = handle2->bh_centry;
- while (CENTRY_BLK(cc_ent1) != FBA_TO_BLK_NUM(fba_pos2))
- cc_ent1 = cc_ent1->cc_chain;
-
-
- if (BLK_FBA_OFF(fba_pos1) != BLK_FBA_OFF(fba_pos2)) {
- cmn_err(CE_WARN, "!Cannot copy unaligned handles");
- return (0);
- }
-
- cur_fba_len = fba_len;
- st_cblk_off = BLK_FBA_OFF(fba_pos1);
- st_cblk_len = (BLK_FBAS - st_cblk_off);
- if ((nsc_size_t)st_cblk_len >= fba_len) {
- end_cblk_len = 0;
- st_cblk_len = (sdbc_cblk_fba_t)fba_len;
- } else
- end_cblk_len = BLK_FBA_OFF(fba_pos1 + fba_len);
-
- skew_word = cc_ent->cc_data + FBA_SIZE(st_cblk_off);
- *skew_word = skew | (++skew_count << 24);
- bcopy(cc_ent->cc_data + FBA_SIZE(st_cblk_off), cc_ent1->cc_data +
- FBA_SIZE(st_cblk_off), FBA_SIZE(st_cblk_len));
- cur_fba_len -= st_cblk_len;
- cc_ent = cc_ent->cc_chain;
- cc_ent1 = cc_ent1->cc_chain;
-
- while (cur_fba_len > (nsc_size_t)end_cblk_len) {
- skew_word = cc_ent->cc_data;
- *skew_word = skew | (++skew_count << 24);
- bcopy(cc_ent->cc_data, cc_ent1->cc_data, CACHE_BLOCK_SIZE);
- cc_ent = cc_ent->cc_chain;
- cc_ent1 = cc_ent1->cc_chain;
- cur_fba_len -= BLK_FBAS;
- }
- if (cur_fba_len) {
- skew_word = cc_ent->cc_data;
- *skew_word = skew | (++skew_count << 24);
- bcopy(cc_ent->cc_data, cc_ent1->cc_data,
- FBA_SIZE(end_cblk_len));
- }
- return (0);
-}
-
-static int
-_sd_compare_handle(_sd_buf_handle_t *handle1, _sd_buf_handle_t *handle2,
- nsc_off_t fba_pos1, nsc_off_t fba_pos2, nsc_size_t fba_len, int skew)
-{
- sdbc_cblk_fba_t st_cblk_len; /* FBA len of starting cache block */
- sdbc_cblk_fba_t end_cblk_len; /* FBA len of ending cache block */
- sdbc_cblk_fba_t st_cblk_off; /* FBA offset into starting cblock */
- nsc_size_t cur_fba_len;
- _sd_cctl_t *cc_ent, *cc_ent1;
- unsigned char *skew_word;
- int skew_count = 0;
-
- ASSERT_HANDLE_LIMITS(handle1, fba_pos1, fba_len);
- ASSERT_HANDLE_LIMITS(handle2, fba_pos2, fba_len);
-
- cc_ent = handle1->bh_centry;
- while (CENTRY_BLK(cc_ent) != FBA_TO_BLK_NUM(fba_pos1))
- cc_ent = cc_ent->cc_chain;
-
- cc_ent1 = handle2->bh_centry;
- while (CENTRY_BLK(cc_ent1) != FBA_TO_BLK_NUM(fba_pos2))
- cc_ent1 = cc_ent1->cc_chain;
-
- if (BLK_FBA_OFF(fba_pos1) != BLK_FBA_OFF(fba_pos2)) {
- cmn_err(CE_WARN, "!Cannot compare unaligned handles");
- return (0);
- }
-
- cur_fba_len = fba_len;
- st_cblk_off = BLK_FBA_OFF(fba_pos1);
- st_cblk_len = (BLK_FBAS - st_cblk_off);
- if ((nsc_size_t)st_cblk_len >= fba_len) {
- end_cblk_len = 0;
- st_cblk_len = (sdbc_cblk_fba_t)fba_len;
- } else
- end_cblk_len = BLK_FBA_OFF(fba_pos1 + fba_len);
-
- skew_word = cc_ent->cc_data + FBA_SIZE(st_cblk_off);
- *skew_word = skew | (++skew_count << 24);
- if (bcmp(cc_ent->cc_data + FBA_SIZE(st_cblk_off),
- cc_ent1->cc_data + FBA_SIZE(st_cblk_off),
- FBA_SIZE(st_cblk_len)) != 0)
- cmn_err(CE_WARN, "!Data mismatch fba_pos:%" NSC_SZFMT,
- fba_pos2);
-
- cur_fba_len -= st_cblk_len;
- cc_ent = cc_ent->cc_chain;
- cc_ent1 = cc_ent1->cc_chain;
-
- while (cur_fba_len > (nsc_size_t)end_cblk_len) {
- skew_word = cc_ent->cc_data;
- *skew_word = skew | (++skew_count << 24);
- if (bcmp(cc_ent->cc_data, cc_ent1->cc_data,
- CACHE_BLOCK_SIZE) != 0)
- cmn_err(CE_WARN, "!Data mismatch fba_pos:%" NSC_SZFMT,
- fba_pos2);
-
- cc_ent = cc_ent->cc_chain;
- cc_ent1 = cc_ent1->cc_chain;
- cur_fba_len -= BLK_FBAS;
- }
- if (cur_fba_len) {
- skew_word = cc_ent->cc_data;
- *skew_word = skew | (++skew_count << 24);
- if (bcmp(cc_ent->cc_data, cc_ent1->cc_data,
- FBA_SIZE(end_cblk_len)) != 0)
- cmn_err(CE_WARN, "!Data mismatch fba_pos:%" NSC_SZFMT,
- fba_pos2);
- }
- return (0);
-}
-
-/*
- * Macro definition for waiting for an IO buffer to be allocated or a read
- * to complete. Macro defined so code doesn't have to be typed each time
- */
-#define WAIT_IO(st, cd, buf, l) \
-if ((st != NSC_DONE) && (st != NSC_HIT)) { \
- if (st != NSC_PENDING) \
- cmn_err(CE_WARN, "!alloc sts: %d", st); \
- else { \
- buf = wait_io(cd, &st); \
- if (st) { \
- cmn_err(CE_WARN, "!ch %d getbuf errpr %d\n", l, st); \
- if (buf) \
- (void) _sd_free_buf(buf); \
- return; \
- } \
- } \
-}
-
-
-#undef _sd_write
-
-static int tiodone, iosent, tioerr;
-
-/* ARGSUSED */
-
-static void
-myend(blind_t arg, nsc_off_t fba_pos, nsc_size_t fba_len, int error)
-{
- if (error)
- tioerr++;
- else tiodone++;
-}
-
-static int ckd_sskip = 3;
-
-/* ARGSUSED3 */
-static void
-_sd_direct_test(int c, int loop, int seed, int type)
-{
- nsc_size_t filesize;
- int loops;
-
- int cd;
- int ckd_hd, recs, rec_size, ckd_doz;
- int done_size;
- clock_t st_time;
- int i;
-
- int ckd_hd_sz, rec_bsz;
- int print_stuff;
- int throttle;
- struct buf *bp;
- nsc_off_t curpos;
-
- caddr_t caddr;
- iosent = 0;
-
- print_stuff = 0;
- seed = gld[c].seed;
- rec_size = (seed & 0xff);
- recs = (seed & 0xf00)>>8;
- ckd_hd = (seed & 0xf000)>>12;
- ckd_doz = (seed & 0xf0000)>>16;
- throttle = (seed & 0xff00000)>>20;
- ckd_hd_sz = ckd_hd * 512;
- rec_bsz = rec_size * 512;
-
- done_size = 0;
- tiodone = 0;
- curpos = 0;
- tioerr = 0;
-
- if (strlen(devarray[c]) == 0) {
- cmn_err(CE_WARN, "!child %d devarray null\n", c);
- return;
- }
- if ((cd = _sd_open(devarray[c], dev_flag[c])) < 0) {
- cmn_err(CE_WARN, "!Open error %s child %d\n", devarray[c], c);
- return;
- }
-
- caddr = (caddr_t)nsc_kmem_alloc(20 * 8192, KM_SLEEP, sdbc_local_mem);
-
- (void) _sd_get_partsize((blind_t)(unsigned long)cd, &filesize);
- filesize = FBA_SIZE(filesize);
- loops = ((nsc_size_t)loop > (filesize / (60 * 1024))) ?
- (filesize / (60 * 1024)) : loop;
-
- st_time = nsc_usec();
- cmn_err(CE_CONT, "!Test 100: %s file %d cd %d loops %x seed\n",
- devarray[c], cd, loop, seed);
- cmn_err(CE_CONT,
- "!Test 100: %d recsize %d recs %d throttle %d hd %d doz\n",
- rec_size, recs, throttle, ckd_hd, ckd_doz);
-
- for (i = 0; i < loops; i++) {
- curpos = i * 120;
- if (ckd_doz) {
- bp = sd_alloc_iob(_sd_cache_files[cd].cd_crdev,
- curpos, 20, B_WRITE);
- sd_add_mem(bp, caddr, ckd_hd_sz);
- (void) sd_start_io(bp,
- _sd_cache_files[cd].cd_strategy, myend, NULL);
- iosent++;
- curpos += ckd_sskip;
- }
- if (ckd_doz == 2) {
- bp = sd_alloc_iob(_sd_cache_files[cd].cd_crdev,
- curpos, 20, B_WRITE);
- sd_add_mem(bp, caddr, 4096-ckd_sskip*512);
- (void) sd_start_io(bp,
- _sd_cache_files[cd].cd_strategy, myend, NULL);
- iosent++;
- curpos += 4096-ckd_sskip*512;
- }
- bp = sd_alloc_iob(_sd_cache_files[cd].cd_crdev,
- curpos, 20, B_WRITE);
- sd_add_mem(bp, caddr, recs * rec_bsz);
- (void) sd_start_io(bp,
- _sd_cache_files[cd].cd_strategy, myend, NULL);
- iosent++;
-
- done_size += recs * rec_bsz;
-
- if (tiodone && ((tiodone / 300) > print_stuff)) {
- cmn_err(CE_CONT, "!Done %d ios %d size in %lu time\n",
- tiodone,
- ckd_doz ? ((ckd_doz == 2) ?
- (tiodone * (recs * rec_bsz + 4096)) / 3:
- (tiodone * (recs * rec_bsz + ckd_hd_sz)) / 2) :
- (tiodone * (recs * rec_bsz)),
- (nsc_usec() - st_time) / 1000);
- print_stuff++;
- }
- while ((iosent - (tiodone + tioerr)) > throttle)
- ;
- }
- while ((tiodone + tioerr) < iosent) {
- if (tiodone && ((tiodone / 300) > print_stuff)) {
- cmn_err(CE_CONT, "!Done %d ios %d size in %lu time\n",
- tiodone,
- ckd_doz ? ((ckd_doz == 2) ?
- (tiodone * (recs * rec_bsz + 4096)) / 3:
- (tiodone * (recs * rec_bsz + ckd_hd_sz)) / 2) :
- (tiodone * (recs * rec_bsz)),
- (nsc_usec() - st_time) / 1000);
- print_stuff++;
- }
- }
- cmn_err(CE_CONT, "!Done %d ios %d size in %lu time\n",
- tiodone,
- ckd_doz ? ((ckd_doz == 2) ?
- (tiodone * (recs * rec_bsz + 4096)) / 3:
- (tiodone * (recs * rec_bsz + ckd_hd_sz)) / 2) :
- (tiodone * (recs * rec_bsz)),
- (nsc_usec() - st_time) / 1000);
-
- print_stuff++;
- nsc_kmem_free(caddr, 20 * 8192);
-}
-
-static void
-set_parameters(void)
-{
- test_stop = 0;
-}
-
-static nsc_mem_t *dma_test = NULL;
-static int *dma_mem = NULL;
-
-static int
-init_dmatest(void)
-{
- dma_test = nsc_register_mem("dmatest:mem", NSC_MEM_GLOBAL, 0);
- dma_mem = (int *)nsc_kmem_zalloc(4096, 0, dma_test);
- if (!dma_mem) {
- cmn_err(CE_NOTE, "!could not get rm mem\n");
- return (1);
- }
- cmn_err(CE_NOTE, "!rm = 0x%p\n", (void *)dma_mem);
- return (0);
-}
-
-/*ARGSUSED*/
-static void
-release_dmatest(void)
-{
- nsc_kmem_free(dma_mem, 1);
- nsc_unregister_mem(dma_test);
- dma_test = NULL;
- dma_mem = NULL;
-}
-/*ARGSUSED*/
-static void
-test_dma_loop(int net, int seg)
-{
- delay(3*HZ);
-
- if (!dma_mem && init_dmatest()) {
- cmn_err(CE_WARN, "!test_dma_loop: init failed");
- return;
- }
-
- /*
- * The body of test loop is removed since we don't use any more
- */
-
- release_dmatest();
-}
diff --git a/usr/src/uts/common/avs/ns/sdbc/sd_tdaemon.h b/usr/src/uts/common/avs/ns/sdbc/sd_tdaemon.h
deleted file mode 100644
index 60de75dc5f..0000000000
--- a/usr/src/uts/common/avs/ns/sdbc/sd_tdaemon.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SD_TDAEMON_H
-#define _SD_TDAEMON_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if defined(_SD_DEBUG)
-extern int _test_async_fail;
-#endif
-
-extern int _sdbc_tdaemon_load(void);
-extern void _sdbc_tdaemon_unload(void);
-extern int _sdbc_tdaemon_configure(int num);
-extern void _sdbc_tdaemon_deconfigure(void);
-extern int _sd_test_start(void *args, int *rvp);
-extern int _sd_test_end(void);
-extern int _sd_test_init(void *args);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SD_TDAEMON_H */
diff --git a/usr/src/uts/common/avs/ns/sdbc/sd_trace.c b/usr/src/uts/common/avs/ns/sdbc/sd_trace.c
deleted file mode 100644
index 6a4502cfca..0000000000
--- a/usr/src/uts/common/avs/ns/sdbc/sd_trace.c
+++ /dev/null
@@ -1,620 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/ksynch.h>
-#include <sys/cmn_err.h>
-#include <sys/errno.h>
-#include <sys/kmem.h>
-#include <sys/ddi.h>
-#include <sys/nsc_thread.h>
-
-#include "sd_bcache.h"
-#include "sd_trace.h"
-#include "sd_misc.h"
-
-#ifndef _SD_NOTRACE
-
-#ifndef SM_SDTRSEMA
-#define SM_SDTRSEMA 1
-#define SM_SDTRLCK 1
-#endif
-
-int _sd_trace_mask = 0;
-
-/*
- * _sdbd_trace_t _sd_trace_table[-1, 0 .. sdbc_max_devs - 1]
- * allocate memory, shift pointer up by one.
- */
-static _sdbc_trace_t *_sd_trace_table;
-
-static kcondvar_t _sd_adump_cv;
-static int _sd_trace_configed;
-static kmutex_t _sd_adump_lk;
-
-static int _alert_cd = SDT_ANY_CD;
-static int _last_cd = SDT_ANY_CD;
-#define XMEM(x, y) (void)(x = y, y = (SDT_ANY_CD), x)
-
-/*
- * Forward declare all statics that are used before defined to enforce
- * parameter checking.
- * Some (if not all) of these could be removed if the code were reordered
- */
-
-static int _sd_set_adump(int cd, int flag, _sdtr_table_t *table);
-
-/*
- * _sdbc_tr_unload - cache is being unloaded. Release any memory/lock/sv's
- * created by _sdbc_tr_unload and null the stale pointers.
- *
- */
-void
-_sdbc_tr_unload(void)
-{
- if (_sd_trace_table)
- nsc_kmem_free((_sd_trace_table - 1),
- sizeof (_sdbc_trace_t) * (sdbc_max_devs + 1));
- cv_destroy(&_sd_adump_cv);
- mutex_destroy(&_sd_adump_lk);
-
- _sd_trace_table = NULL;
-}
-
-/*
- * _sdbc_tr_load - cache is being loaded. Allocate the memory/lock/sv's
- * which need to be present regardless of state of cache configuration.
- *
- */
-int
-_sdbc_tr_load(void)
-{
- _sdbc_trace_t *m;
-
- cv_init(&_sd_adump_cv, NULL, CV_DRIVER, NULL);
- mutex_init(&_sd_adump_lk, NULL, MUTEX_DRIVER, NULL);
-
- /*
- * this maybe ought to wait to see if traces are configured, but it
- * is only 4k
- */
-
- m = (_sdbc_trace_t *)nsc_kmem_zalloc(
- sizeof (_sdbc_trace_t) * (sdbc_max_devs + 1),
- KM_NOSLEEP, sdbc_stats_mem);
-
- if (m == NULL) {
- cmn_err(CE_WARN,
- "sdbc(_sdbc_tr_load) cannot allocate trace table");
- return (-1);
- }
- _sd_trace_table = m + 1;
-
- return (0);
-
-}
-
-/*
- * _sdbc_tr_configure - configure a trace area for the descriptor "cd".
- * Unlike other ..._configure routines this routine is called multiple
- * times since there will be an unknown number of open descriptors. At
- * cache config time if tracing is enabled only the slot for SDT_INV_CD
- * is created.
- *
- * Allocate the SD cache trace area (per device)
- */
-
-int
-_sdbc_tr_configure(int cd)
-{
- int size;
- _sdtr_table_t *t;
- kmutex_t *lk;
-
- if (!_sd_cache_config.trace_size)
- return (0);
-
- if (cd == SDT_INV_CD)
- _sd_trace_configed = 1;
-
- if (_sd_trace_table[cd].tbl)
- return (0);
-
- size = sizeof (_sdtr_table_t) +
- _sd_cache_config.trace_size * sizeof (_sdtr_t);
-
- if ((t = (_sdtr_table_t *)nsc_kmem_zalloc(size,
- KM_NOSLEEP, sdbc_stats_mem)) == NULL) {
- cmn_err(CE_WARN, "sdbc(_sdbc_tr_configure) failed to "
- "allocate %d bytes for trace, cd=%d", size, cd);
- return (-1);
- }
-
- lk = nsc_kmem_zalloc(sizeof (kmutex_t), KM_NOSLEEP, sdbc_local_mem);
- if (!lk) {
- nsc_kmem_free(t, size);
- cmn_err(CE_WARN, "sdbc(_sdbc_tr_configure) cannot "
- "alloc trace lock for cd %d", cd);
- return (-1);
- }
- mutex_init(lk, NULL, MUTEX_DRIVER, NULL);
-
- _sd_trace_table[cd].t_lock = lk;
- t->tt_cd = cd;
- t->tt_max = _sd_cache_config.trace_size;
- t->tt_mask = _sd_cache_config.trace_mask;
- t->tt_lbolt = (char)_sd_cache_config.trace_lbolt;
- t->tt_good = (char)_sd_cache_config.trace_good;
- _sd_trace_mask |= t->tt_mask;
- _sd_trace_table[cd].tbl = t;
- return (0);
-}
-
-
-/*
- * _sdbc_tr_deconfigure
- * free all trace memory (regions) when deconfiguring cache
- */
-void
-_sdbc_tr_deconfigure(void)
-{
- int i, size;
- _sdbc_trace_t *tt;
-
- if (!_sd_cache_config.trace_size || !_sd_trace_configed)
- return;
-
- mutex_enter(&_sd_adump_lk);
- _sd_trace_configed = 0;
- cv_broadcast(&_sd_adump_cv);
- mutex_exit(&_sd_adump_lk);
-
- for (i = -1, tt = &_sd_trace_table[-1]; i < sdbc_max_devs; i++, tt++) {
- if (tt->tbl == NULL) continue;
- size = tt->tbl->tt_max * sizeof (_sdtr_t) +
- sizeof (_sdtr_table_t);
- if (tt->t_lock) {
- mutex_destroy(tt->t_lock);
- nsc_kmem_free(tt->t_lock, sizeof (kmutex_t));
- }
- nsc_kmem_free(tt->tbl, size);
- tt->t_lock = NULL;
- tt->tbl = NULL;
- }
- _alert_cd = SDT_ANY_CD;
- _last_cd = SDT_ANY_CD;
-}
-
-static int first_alert = 0;
-/*
- * SDALERT(f,cd,len,fba,flg,ret) \
- * _sd_alert(f,cd,len,fba,flg,ret)
- * Build a ALERT trace entry and place it into the trace table.
- */
-void
-_sd_alert(int f, int cd, int len, nsc_off_t fba, int flg, int ret)
-{
- int tin;
- _sdtr_t *tp;
- _sdtr_table_t *t;
- kmutex_t *lk;
-
- if (!first_alert) {
- first_alert++;
- cmn_err(CE_WARN,
- "sdbc(_sd_alert) cd=%x f=%x len=%x fba=%" NSC_SZFMT
- " flg=%x ret=%x", cd, f, len, fba, flg, ret);
-
- }
-
- /* Watch out for negative error codes or simply bogus cd's */
-
- if (cd < -1 || cd >= sdbc_max_devs) {
- /*
- * no device trace buffer -- use SDT_INV_CD table?
- */
- if ((t = _sd_trace_table[-1].tbl) == NULL)
- return;
- lk = _sd_trace_table[-1].t_lock;
- } else {
- lk = _sd_trace_table[cd].t_lock;
- if ((t = _sd_trace_table[cd].tbl) == NULL) {
- /*
- * no device trace buffer -- use SDT_INV_CD table?
- */
- if ((t = _sd_trace_table[-1].tbl) == NULL)
- return;
- lk = _sd_trace_table[-1].t_lock;
- }
- }
-
- if (!(t->tt_mask & ST_ALERT))
- return; /* check per-device mask */
-
- if (t->tt_good) mutex_enter(lk);
- t->tt_alert++; /* alert on this device */
- t->tt_cnt++; /* overwritten entries if (tt_cnt >= tt_max) */
-
- tin = t->tt_in++;
- if (tin >= t->tt_max) tin = t->tt_in = 0;
- tp = &t->tt_buf[tin];
- tp->t_time = 0; /* not filled in yet */
- if (t->tt_good) mutex_exit(lk);
-
- tp->t_func = (ushort_t)f | ST_ALERT;
- tp->t_len = (ushort_t)len;
- tp->t_fba = fba;
- tp->t_flg = flg;
- tp->t_ret = ret;
- /*
- * On LP64 systems we will only capture the low 32 bits of the
- * time this really should be good enough for our purposes.
- *
- */
- if (t->tt_lbolt)
- tp->t_time = (int)nsc_lbolt();
- else
- tp->t_time = (int)nsc_usec();
-
- /* wakeup trace daemon, with hint */
- _alert_cd = cd;
-
- if (_sd_trace_configed)
- cv_signal(&_sd_adump_cv);
-}
-
-
-/*
- * SDTRACE(f,cd,len,fba,flg,ret) \
- * if (_sd_trace_mask & (f)) _sd_trace(f,cd,len,fba,flg,ret)
- * Build a trace entry and place it into the trace table.
- */
-void
-_sd_trace(int f, int cd, int len, nsc_off_t fba, int flg, int ret)
-{
- int tin;
- _sdtr_t *tp;
- _sdtr_table_t *t;
- kmutex_t *lk;
-
- /* Watch out for negative error codes or simply bogus cd's */
-
- if (cd < -1 || cd >= sdbc_max_devs) {
- /*
- * no device trace buffer -- use SDT_INV_CD table?
- */
- if ((t = _sd_trace_table[-1].tbl) == NULL)
- return;
- lk = _sd_trace_table[-1].t_lock;
- } else {
- lk = _sd_trace_table[cd].t_lock;
- if ((t = _sd_trace_table[cd].tbl) == NULL)
- return;
- }
-
- if (!(t->tt_mask & f))
- return; /* check per-device mask */
-
- /*
- * Don't overwrite if alert signaled (count lost instead)
- * Locking only if 'trace_good' parameter set.
- */
- if (t->tt_good) mutex_enter(lk);
- if (t->tt_alert && (t->tt_cnt >= t->tt_max)) {
- t->tt_lost++; /* lost during alert */
- if (t->tt_good) mutex_exit(lk);
- return;
- }
- t->tt_cnt++; /* overwritten entries if (tt_cnt >= tt_max) */
-
- tin = t->tt_in++;
- if (tin >= t->tt_max) tin = t->tt_in = 0;
- tp = &t->tt_buf[tin];
- tp->t_time = 0; /* not filled in yet */
- if (t->tt_good) mutex_exit(lk);
-
- tp->t_func = (ushort_t)f;
- tp->t_len = (ushort_t)len;
- tp->t_fba = fba;
- tp->t_flg = flg;
- tp->t_ret = ret;
- /*
- * On LP64 systems we will only capture the low 32 bits of the
- * time this really should be good enough for our purposes.
- *
- */
- if (t->tt_lbolt)
- tp->t_time = (int)nsc_lbolt();
- else
- tp->t_time = (int)nsc_usec();
-}
-
-/*
- * _sd_scan_alert -- search for device with trace alert
- */
-static int
-_sd_scan_alert(void)
-{
- int cd;
-
- XMEM(cd, _alert_cd);
- if ((cd != SDT_ANY_CD) && _sd_trace_table[cd].tbl->tt_alert)
- return (cd);
- for (cd = _last_cd + 1; cd < sdbc_max_devs; cd++)
- if (_sd_trace_table[cd].tbl &&
- _sd_trace_table[cd].tbl->tt_alert)
- return (_last_cd = cd);
- for (cd = SDT_INV_CD; cd <= _last_cd; cd++)
- if (_sd_trace_table[cd].tbl &&
- _sd_trace_table[cd].tbl->tt_alert)
- return (_last_cd = cd);
- return (SDT_ANY_CD);
-}
-
-/*
- * _sd_scan_entries -- search for next device with trace entries
- */
-static int
-_sd_scan_entries(void)
-{
- int cd;
-
- for (cd = _last_cd + 1; cd < sdbc_max_devs; cd++)
- if (_sd_trace_table[cd].tbl && _sd_trace_table[cd].tbl->tt_cnt)
- return (_last_cd = cd);
- for (cd = SDT_INV_CD; cd <= _last_cd; cd++)
- if (_sd_trace_table[cd].tbl && _sd_trace_table[cd].tbl->tt_cnt)
- return (_last_cd = cd);
- return (SDT_ANY_CD);
-}
-
-
-/*
- * _sd_adump
- * copy information about new trace records to trace daemon,
- * or modify trace parameters.
- *
- * Some tracing parameters can be modified
- * [Either per-device if cd specified, or the defaults if cd = SDT_ANY_CD]
- * SD_LOGSIZE: table.tt_max (size for future opens)
- * SD_SET_LBOLT: table.tt_lbolt
- * SD_SET_MASK: table.tt_mask
- * SD_SET_GOOD: table.tt_good
- *
- * if (cd >= 0) dump specific device records;
- * if (cd == SDT_INV_CD) dump records which don't apply to any one device.
- * if (cd == SDT_ANY_CD), then choose a device:
- * 1) most recent alert, block if (flag & SD_ALERT_WAIT)
- * 2) "next" device with unprocessed records.
- */
-int
-_sd_adump(void *args, int *rvp)
-{
- struct a {
- long cd;
- _sdtr_table_t *table;
- _sdtr_t *buf;
- long size;
- long flag;
- } *uap = (struct a *)args;
- _sdtr_t *ubuf;
- _sdtr_table_t tt, *t;
- kmutex_t *lk;
- int cd, count, lost, new_cnt;
-
- if (uap->flag & (SD_SET_SIZE|SD_SET_MASK|SD_SET_LBOLT|SD_SET_GOOD)) {
- return (_sd_set_adump(uap->cd, uap->flag, uap->table));
- }
- if (! _sd_trace_configed) {
- return (EINVAL); /* not initialized yet */
- }
- if (uap->cd >= SDT_INV_CD) {
- /* specific device: check if configured. dump current state. */
- if ((uap->cd > (long)sdbc_max_devs) ||
- !(t = _sd_trace_table[uap->cd].tbl)) {
- return (ENOSPC); /* no space configured */
- }
- lk = _sd_trace_table[uap->cd].t_lock;
- cd = uap->cd;
- } else {
- /*
- * SDT_ANY_CD:
- * SD_ALERT_WAIT - wait for alert
- */
- scan:
- if ((cd = _sd_scan_alert()) != SDT_ANY_CD)
- goto dump;
- if ((uap->flag & SD_ALERT_WAIT)) {
- mutex_enter(&_sd_adump_lk);
- if (!_sd_trace_configed) {
- mutex_exit(&_sd_adump_lk);
- return (EINVAL);
- }
-
- if (!cv_wait_sig(&_sd_adump_cv, &_sd_adump_lk)) {
- mutex_exit(&_sd_adump_lk);
- return (EINTR);
- }
- mutex_exit(&_sd_adump_lk);
-
- if (!_sd_trace_configed || !_sd_cache_initialized) {
- return (EIDRM);
- }
- goto scan;
- }
- /* any device with entries */
- if ((cd = _sd_scan_entries()) == SDT_INV_CD)
- return (0); /* no new entries */
-
- dump:
- lk = _sd_trace_table[cd].t_lock;
- if ((t = _sd_trace_table[cd].tbl) == NULL) {
- if (uap->flag & SD_ALERT_WAIT) {
- t = _sd_trace_table[-1].tbl;
- lk = _sd_trace_table[-1].t_lock;
- } else {
- return (ENOSPC); /* no space configured */
- }
- }
- }
-
- /*
- * take a snapshot of the table state
- */
- if (t->tt_good)
- mutex_enter(lk);
- tt = *t;
- if (t->tt_good)
- mutex_exit(lk);
-
- /*
- * copy trace log entries to daemon
- *
- * size: entries in user-level 'buf'
- * count: how many entries to copy [force count <= size]
- * tt_max: size of kernel buffer
- * tt_cnt: written entries [lossage if tt_cnt > tt_max]
- * cnt: for wrap-around calculations
- */
- if ((count = tt.tt_cnt) > tt.tt_max) { /* lost from beginning */
- tt.tt_out = tt.tt_in;
- count = tt.tt_max;
- lost = tt.tt_cnt - tt.tt_max;
- } else
- lost = 0;
- if (count <= 0)
- return (0);
- if ((long)count > uap->size)
- count = uap->size;
- ubuf = uap->buf;
- if ((tt.tt_out + count) > tt.tt_max) {
- int cnt = tt.tt_max - tt.tt_out;
- if (cnt > count)
- cnt = count;
- if (copyout(&(t->tt_buf[tt.tt_out]), ubuf,
- cnt * sizeof (_sdtr_t))) {
- return (EFAULT);
- }
- ubuf += cnt;
- cnt = count - cnt;
- if (copyout(&(t->tt_buf[0]), ubuf, cnt * sizeof (_sdtr_t))) {
- return (EFAULT);
- }
- tt.tt_out = cnt;
- } else {
- if (copyout(&(t->tt_buf[tt.tt_out]), ubuf,
- count * sizeof (_sdtr_t))) {
- return (EFAULT);
- }
- tt.tt_out += count;
- if (tt.tt_out == tt.tt_max)
- tt.tt_out = 0;
- }
-
- /*
- * tt_alert uses fuzzy counting.
- * if multiple alerts signaled, leave it at 1.
- */
- if (t->tt_alert)
- t->tt_alert = (t->tt_alert > 1) ? 1 : 0;
-
- /*
- * tt_cntout is tt_cnt after dump
- * update tt_cnt for copied entries
- */
- if (t->tt_good)
- mutex_enter(lk);
- tt.tt_cntout = t->tt_cnt;
- t->tt_out = tt.tt_out;
- new_cnt = t->tt_cnt;
- if ((new_cnt -= count+lost) < 0)
- new_cnt = 0;
- t->tt_cnt = new_cnt; /* race with new traces if not "tt_good" */
- if (t->tt_good)
- mutex_exit(lk);
-
- if (copyout(&tt, uap->table, sizeof (tt) - sizeof (_sdtr_t))) {
- return (EFAULT);
- }
- *rvp = count;
-
- first_alert = 0;
- return (0);
-}
-
-
-/* set size, mask, lbolt, or good(locks) */
-static int
-_sd_set_adump(int cd, int flag, _sdtr_table_t *table)
-{
- _sdtr_table_t tt, *t;
-
- if (copyin(table, &tt, sizeof (tt) - sizeof (_sdtr_t))) {
- return (EFAULT);
- }
- if (cd == SDT_ANY_CD) { /* modify config parameter */
- if (flag & SD_SET_SIZE)
- _sd_cache_config.trace_size = tt.tt_max;
- if (flag & SD_SET_MASK) {
- _sd_cache_config.trace_mask = tt.tt_mask;
- /* explicitly set global mask, not bitwise or */
- _sd_trace_mask = tt.tt_mask;
- }
- if (flag & SD_SET_LBOLT)
- _sd_cache_config.trace_lbolt = tt.tt_lbolt;
- if (flag & SD_SET_GOOD)
- _sd_cache_config.trace_good = tt.tt_good;
- return (0);
- }
- if (flag & SD_SET_SIZE)
- _sd_cache_config.trace_size = tt.tt_max;
- /* modify particular device parameters */
- if (!_sd_trace_table[cd].tbl)
- (void) _sdbc_tr_configure(cd);
- if ((t = _sd_trace_table[cd].tbl) == NULL)
- return (0);
- if (flag & SD_SET_MASK) {
- t->tt_mask = tt.tt_mask;
- _sd_trace_mask |= tt.tt_mask; /* or-ed with global mask */
- }
- if (flag & SD_SET_LBOLT)
- t->tt_lbolt = tt.tt_lbolt;
- if (flag & SD_SET_GOOD)
- t->tt_good = tt.tt_good;
- if (copyout(t, table, sizeof (*t) - sizeof (_sdtr_t))) {
- return (EFAULT);
- }
- return (0);
-}
-
-#else /* ! _SD_NOTRACE */
-
-int _sd_adump() { return (ENOSYS); }
-int _sdbc_tr_load(void) { return (0); }
-int _sdbc_tr_configure(void) { return (0); }
-void _sdbc_tr_deconfigure(void) { return; }
-void _sdbc_tr_unload(void) { return; }
-
-#endif /* ! _SD_NOTRACE */
diff --git a/usr/src/uts/common/avs/ns/sdbc/sd_trace.h b/usr/src/uts/common/avs/ns/sdbc/sd_trace.h
deleted file mode 100644
index 8dd86528c2..0000000000
--- a/usr/src/uts/common/avs/ns/sdbc/sd_trace.h
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-
-#ifndef _SD_TRACE_H
-#define _SD_TRACE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-#ifdef _SD_NOTRACE
-#define SDALERT(f, cd, len, fba, flg, ret)
-#define SDTRACE(f, cd, len, fba, flg, ret)
-#define DATA_LOG_CHAIN(ttype, c_ent, stp, ln)
-#define DATA_LOG(ttype, c_ent, stp, ln)
-#else
-#define SDALERT(f, cd, len, fba, flg, ret) \
- _sd_alert(f, (int)cd, (int)len, (nsc_off_t)fba, (int)flg, (int)ret)
-#define SDTRACE(f, cd, len, fba, flg, ret) \
- if (_sd_trace_mask & (f)) \
- _sd_trace(f, (int)cd, (int)len, (nsc_off_t)fba,\
- (int)flg, (int)ret)
-#define DATA_LOG_CHAIN(ttype, c_ent, stp, ln) \
- _sd_data_log_chain((int)(ttype), c_ent, (nsc_off_t)(stp), \
- (nsc_size_t)(ln))
-#if defined(_SD_FBA_DATA_LOG) || defined(lint)
-#define DATA_LOG(ttype, c_ent, stp, ln) \
- _sd_data_log((int)(ttype), c_ent, (nsc_off_t)(stp), (nsc_size_t)(ln))
-#else
-#define DATA_LOG(ttype, c_ent, stp, ln) \
- SDTRACE(ttype, CENTRY_CD(c_ent), \
- ln, (nsc_off_t)(BLK_TO_FBA_NUM(CENTRY_BLK(c_ent)) + stp), \
- *(int *)((c_ent)->cc_data+FBA_SIZE(stp)), \
- *(int *)((c_ent)->cc_data+FBA_SIZE(stp+ln)-4))
-#endif /* (_SD_FBA_DATA_LOG) */
-#endif
-
-#define SDT_INV_CD -1
-#define SDT_ANY_CD -2
-#define SDT_INV_BL 0xffffffff
-
-typedef struct _sdtr
-{
- ushort_t t_func; /* function being traced */
- ushort_t t_len; /* allocation type */
- nsc_off_t t_fba; /* fixed block offset */
- int t_flg; /* buffer size requested */
- int t_ret; /* return value */
- int t_time; /* micro_second timer, or lbolt */
- /* low order only on LP64 systems */
-} _sdtr_t;
-
-typedef struct _sdtr_table
-{
- int tt_cd; /* cache device */
- int tt_max; /* entries in table */
- int tt_in; /* entries added */
- int tt_out; /* entries read */
- int tt_cnt; /* unread entries */
- int tt_cntout; /* tt_cnt after dump */
- int tt_mask; /* copy of _sd_trace_mask */
- int tt_lost; /* lost after alert */
- char tt_alert; /* alert signaled */
- char tt_lbolt; /* use 'lbolt' instead of microsec */
- char tt_good; /* use locking (races with end-action) */
- char tt_type; /* memory region 0 or 1 (_SD_MEM_TRACE) */
- _sdtr_t tt_buf[1]; /* per-device trace records [0..tt_max] */
-} _sdtr_table_t;
-
-#if defined(_KERNEL)
-typedef struct _sdbc_trace_s {
- _sdtr_table_t *tbl; /* points to the trace table for a cd */
- kmutex_t *t_lock; /* the lock for this cd */
- } _sdbc_trace_t;
-#endif /* _KERNEL */
-
-/* sd_adump() flags */
-#define SD_SET_SIZE 0x01 /* create log if it doesn't exist */
-#define SD_SET_MASK 0x02
-#define SD_SET_LBOLT 0x04
-#define SD_SET_GOOD 0x08
-#define SD_ADUMP_WAIT 0x10 /* wakeup for buffer full or alert */
-#define SD_ALERT_WAIT 0x20 /* wakeup for alert messages */
-
-/* Trace function, category, mask bits */
-#define ST_FUNC 0x000f /* functions per category */
-#define ST_CATMASK 0x0ff0 /* Category mask */
-
-#define ST_BCACHE 0x0010 /* BCACHE entry points */
-#define ST_BSUB 0x0020 /* BCACHE subroutines */
-#define ST_IO 0x0040 /* IO subsystem */
-#define ST_CCIO 0x0080 /* concurrent (dual) copy */
-#define ST_FT 0x0100 /* Fault-tolerant subsystem */
-#define ST_DL 0x0200 /* Data-logging (debug) */
-#define ST_STATS 0x0400 /* cache statistics */
-#define ST_CKD 0x0800 /* SIMCKD traces */
-
-#define ST_ENTER 0x1000 /* function entry */
-#define ST_EXIT 0x2000 /* function exit */
-#define ST_INFO 0x4000 /* see t_flg */
-#define ST_ALERT 0x8000 /* force write to daemon */
-
-/*
- * dump file pseudo-entries
- */
-#define SDF_LOST 0x0000 /* trace is missing entries */
-#define SDF_CD 0x0001 /* new device (following entries) */
-
-/*
- * ST_BCACHE functions
- */
-#define SDF_OPEN 0x00 | ST_BCACHE
-#define SDF_CLOSE 0x01 | ST_BCACHE
-#define SDF_HALLOC 0x02 | ST_BCACHE
-#define SDF_HFREE 0x03 | ST_BCACHE
-#define SDF_ALLOCBUF 0x04 | ST_BCACHE
-#define SDF_FREEBUF 0x05 | ST_BCACHE
-#define SDF_WRITE 0x06 | ST_BCACHE
-#define SDF_READ 0x07 | ST_BCACHE
-#define SDF_UNCOMMIT 0x08 | ST_BCACHE
-#define SDF_ZERO 0x09 | ST_BCACHE
-#define SDF_HINT 0x0a | ST_BCACHE
-#define SDF_ATTACH 0x0b | ST_BCACHE | ST_FT
-#define SDF_DETACH 0x0c | ST_BCACHE | ST_FT
-#define SDF_NOTIFY 0x0d | ST_BCACHE
-
-/*
- * ST_BSUB - bcache subroutines
- */
-#define SDF_ENT_GET 0x00 | ST_BSUB
-#define SDF_ENT_ALLOC 0x01 | ST_BSUB
-#define SDF_READ_EA 0x02 | ST_BSUB
-#define SDF_ENT_FREE 0x03 | ST_BSUB
-#define SDF_WR_ALLOC 0x04 | ST_BSUB
-#define SDF_WR_FREE 0x05 | ST_BSUB
-#define SDF_WR_ALLOCONE 0x06 | ST_BSUB
-
-
-/*
- * SD_IO - I/O subsustem
- */
-#define SDF_FLCLIST 0x00 | ST_IO
-#define SDF_FLCENT 0x01 | ST_IO
-#define SDF_FLCLIST_EA 0x02 | ST_IO
-#define SDF_FLCENT_EA 0x03 | ST_IO
-#define SDF_FLDONE 0x04 | ST_IO
-#define SDF_IOB_ALLOC 0x05 | ST_IO
-
-/*
- * ST_FT - Fault-tolerant subsystem
- */
-#define SDF_AWAITR 0x00 | ST_FT
-#define SDF_RECOVER 0x01 | ST_FT
-#define SDF_FT_CLONE 0x02 | ST_FT
-#define SDF_REFLECT 0x03 | ST_FT
-#define SDF_ONLINE 0x04 | ST_FT
-
-/*
- * ST_STATS - Statistics points
- */
-#define SDF_REPLACE 0x00 | ST_STATS
-#define SDF_DISCONNECT 0x01 | ST_STATS
-
-/*
- * ST_INFO
- */
-#define SDF_COVERAGE 0x00 | ST_INFO
-
-/*
- * ST_DL
- */
-
-#define SDF_ALLOC 0x00 | ST_DL
-#define SDF_RD 0x01 | ST_DL
-#define SDF_WR 0x02 | ST_DL
-#define SDF_WRSYNC 0x03 | ST_DL
-#define SDF_FLSHLIST 0x04 | ST_DL
-#define SDF_FLSHENT 0x05 | ST_DL
-#define SDF_RDIO 0x06 | ST_DL
-#define SDF_FLEA 0x07 | ST_DL
-#define SDF_FLSTEA 0x08 | ST_DL
-#define SDF_WRSYEA 0x09 | ST_DL
-
-/*
- * More entry points
- */
-
-#ifdef _SD_FNAME
-/*
- * function category names
- * change these when changing functions above
- * compress name to fit in 8 printable characters
- */
-char *_bcache_fname[16] =
-{
- "open",
- "close",
- "al_hndl",
- "fr_hndl",
- "al_buf",
- "fr_buf",
- "write",
- "read",
- "ucommit",
- "zero",
- "hint",
- "attach",
- "detach",
- "notify",
-};
-
-char *_bsub_fname[16] =
-{
- "get_cent",
- "al_cent",
- "read_ea",
- "fr_cent",
- "al_went",
- "fr_went",
- "al_wone",
-};
-
-char *_io_fname[16] =
-{
- "flclist",
- "flcent",
- "eaclist",
- "eacent",
- "fldone",
- "get_iob",
-};
-
-char *_ccio_fname[16] =
-{
- "ccio",
- "dc_albuf",
- "dc_frbuf",
- "dc_write",
- "dc_read",
- "dc_zero",
-};
-
-char *_ft_fname[16] =
-{
- "wait_rec",
- "cache_rc",
- "ft_clone",
- "reflect",
- "online",
-};
-
-char *_stats_fname[16] =
-{
- "LRU-repl",
- "Disconn",
-};
-
-char *_info_fname[16] =
-{
- "Cover",
-};
-
-char *_dlog_fname[16] =
-{
- "alloc",
- "rd",
- "wr",
- "wrsync",
- "flshlist",
- "flshent",
- "rdio",
- "flea",
- "flstea",
- "wrsyea",
-};
-
-#endif /* _ST_NAMES */
-#ifdef _KERNEL
-
-extern int _sd_trace_mask;
-
-extern void _sdbc_tr_unload(void);
-extern int _sdbc_tr_load(void);
-extern int _sdbc_tr_configure(int cd);
-extern void _sdbc_tr_deconfigure(void);
-extern int _sd_adump(void *args, int *rvp);
-extern void _sd_alert(int f, int cd, int len, nsc_off_t fba, int flg, int ret);
-extern void _sd_trace(int f, int cd, int len, nsc_off_t fba, int flg,
- int ret);
-#endif /* _KERNEL */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SD_TRACE_H */
diff --git a/usr/src/uts/common/avs/ns/sdbc/sdbc.conf b/usr/src/uts/common/avs/ns/sdbc/sdbc.conf
deleted file mode 100644
index ce2e87d523..0000000000
--- a/usr/src/uts/common/avs/ns/sdbc/sdbc.conf
+++ /dev/null
@@ -1,35 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#
-# SDBC Solaris configuration properties
-#
-name="sdbc" parent="pseudo" instance=0;
-
-# Threshold for large writes above which sdbc will force write through
-# mode; specified as a number of 512-byte blocks (default 64).
-# This value only takes affect when NVRAM is present.
-sdbc_wrthru_thresh=64;
-
-# Reduce to 256 if IDE disks are to be used, cannot exceed 1024
-sdbc_max_fbas=1024;
diff --git a/usr/src/uts/common/avs/ns/sdbc/sdbc_ioctl.h b/usr/src/uts/common/avs/ns/sdbc/sdbc_ioctl.h
deleted file mode 100644
index 33a512826e..0000000000
--- a/usr/src/uts/common/avs/ns/sdbc/sdbc_ioctl.h
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-
-#ifndef _SDBC_IOCTL_H
-#define _SDBC_IOCTL_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/unistat/spcs_s.h> /* included for unistat */
-
-/*
- * Generic sdbc ioctl arguments structure.
- * Individual ioctl's will use 0-n of these arguments.
- *
- * Each sdbc ioctl is described first by the command number
- * e.g. #define SDBC_ADUMP _SDBC_(4)
- *
- * Followed by a description of each argument (if any).
- * Each argument is on a single line.
- *
- */
-
-typedef struct _sdbc_ioctl_s {
- long arg0;
- long arg1;
- long arg2;
- long arg3;
- long arg4;
- long magic;
- spcs_s_info_t sdbc_ustatus;
- long pad[1];
-} _sdbc_ioctl_t;
-
-typedef struct _sdbc_ioctl32_s {
- int32_t arg0;
- int32_t arg1;
- int32_t arg2;
- int32_t arg3;
- int32_t arg4;
- int32_t magic;
- spcs_s_info32_t sdbc_ustatus;
- int32_t pad[1];
-} _sdbc_ioctl32_t;
-
-/*
- * Ioctl command numbers
- */
-
-#define _SDBC_(x) (('B'<<16)|('C'<<8)|(x))
-
-/*
- * Old ioctl commands prior to ioctl reorg. These could be re-used
- * at a later date
- */
-#define SDBC_UNUSED_1 _SDBC_(1) /* OLD out of date syscall -> ioctl stuff */
-#define SDBC_UNUSED_2 _SDBC_(2) /* OLD INFSD_CONC_WRITE */
-#define SDBC_UNUSED_3 _SDBC_(3) /* OLD muli-subopcode configuration */
-
-#define SDBC_ADUMP _SDBC_(4)
-/*
- * int cd;
- * _sdtr_table * table;
- * _sdtr_t * trace_buffer;
- * int size_of_trace_buffer;
- * int flags;
- */
-
-#define SDBC_TEST_INIT _SDBC_(5) /* TESTING - tdaemon parameters */
-/*
- * char * device_name;
- * int index;
- * int len;
- * int track_size;
- * int flags;
- */
-
-#define SDBC_TEST_START _SDBC_(6) /* TESTING - tdaemon .... */
-/*
- * int num;
- * int type;
- * int loops;
- * int from;
- * int seed;
- */
-
-#define SDBC_TEST_END _SDBC_(7) /* TESTING - tdaemon .... */
-/* NO-ARGS */
-
-#define SDBC_ENABLE _SDBC_(8) /* configure sdbc */
-/*
- * _sd_cache_param_t * user_configuration;
- */
-
-#define SDBC_DISABLE _SDBC_(9) /* deconfigure sdbc */
-/* NO-ARGS */
-
-#define SDBC_SET_CD_HINT _SDBC_(10)
-/*
- * int cd;
- * int hint;
- * int flags;
- */
-
-#define SDBC_GET_CD_HINT _SDBC_(11)
-/*
- * int cd;
- */
-
-#define SDBC_SET_NODE_HINT _SDBC_(12)
-/*
- * int hint;
- * int flags;
- */
-
-#define SDBC_GET_NODE_HINT _SDBC_(13)
-/* NO-ARGS */
-
-#define SDBC_STATS _SDBC_(14)
-/*
- * _sd_stats_t * stats buffer;
- */
-
-#define SDBC_ZAP_STATS _SDBC_(15)
-/* NO-ARGS */
-
-#define SDBC_GET_CD_BLK _SDBC_(16)
-/*
- * int cd;
- * nsc_off_t * block_number;
- * void * addresses[5];
- */
-
-#define SDBC_GET_CLUSTER_SIZE _SDBC_(17)
-/*
- * int * cluster_size;
- */
-
-#define SDBC_GET_CLUSTER_DATA _SDBC_(18)
-/*
- * char * buffer[2*cluster_size];
- */
-
-#define SDBC_GET_GLMUL_SIZES _SDBC_(19)
-/*
- * int * global_sizes;
- */
-
-#define SDBC_GET_GLMUL_INFO _SDBC_(20)
-/*
- * char * buffer[ 2 times sum of global_sizes];
- */
-
-/* Unused _SDBC(21,22) */
-
-#define SDBC_STATE_DEV _SDBC_(23) /* set path to sdbc state file/volume */
-/*
- * char * device_name;
- * int device_name_length;
- */
-#define SDBC_TOGGLE_FLUSH _SDBC_(24) /* TESTING - toggle flusher enable */
- /* NO-ARGS */
-
-#define SDBC_INJ_IOERR _SDBC_(25) /* TESTING - inject i/o error */
-/*
- * int cd
- * int io_error_number;
- */
-
-#define SDBC_CLR_IOERR _SDBC_(26) /* TESTING - clear injected i/o error */
-/*
- * int cd
- */
-
-#define SDBC_GET_CONFIG _SDBC_(27) /* retrieve current configuration */
-/*
- * _sdbc_config_t *current_config;
- */
-
-#define SDBC_SET_CONFIG _SDBC_(28) /* enable cache configuration info */
-/*
- * _sdbc_config_t *mgmt_config_info;
- */
-
-/* Unused _SDBC(29) */
-
-#define SDBC_MAXFILES _SDBC_(30) /* get maxfiles */
-/*
- * int * max_files;
- */
-
-#define SDBC_VERSION _SDBC_(31)
-/*
- * cache_version_t *cache_version;
- */
-
-#define _SD_MAGIC 0xD017
-
-#define MAX_CACHE_NET 4
-#define MAX_REMOTE_MIRRORS 64
-#define MAX_MIR_SEGS MAX_REMOTE_MIRRORS
-#define MAX_CACHE_SIZE 1024
-
-/* unexposed configuration bits */
-#define CFG_USE_DMCHAIN 0x1
-#define CFG_STATIC_CACHE 0x2
-
-#define RESERVED1_DEFAULTS (CFG_STATIC_CACHE)
-
-/* maintain _sd_cache_param struct layout (MAX_CACHE_NET is deprecated) */
-#define CACHE_MEM_PAD 4
-
-typedef struct _sd_cache_param {
- int mirror_host;
- int blk_size;
- int threads;
- int procs;
- int test_demons;
- int write_cache;
- int trace_size;
- int trace_mask;
- int trace_lbolt;
- int trace_good;
- int trace_net; /* not used */
- int iobuf;
- int num_handles;
- int cache_mem[CACHE_MEM_PAD];
- int prot_lru;
- int gen_pattern;
- uint_t fill_pattern;
- short nodes_conf[MAX_REMOTE_MIRRORS]; /* Actual Nodes in conf file */
- short num_nodes; /* Number of nodes in sd.cf */
- short net_type; /* not used */
- ushort_t magic; /* Check for proper sd_cadmin */
- int reserved1; /* unexposed config options */
- int reserved[8];
-} _sd_cache_param_t;
-
-typedef struct _sdbc_config {
- int cache_mem[CACHE_MEM_PAD];
- int threads;
- int enabled;
- ushort_t magic;
-} _sdbc_config_t;
-
-typedef struct cache_version {
- int major; /* Major release number */
- int minor; /* Minor release number */
- int micro; /* Micro release number */
- int baseline; /* Baseline revison number */
-} cache_version_t;
-
-#if !defined(_KERNEL)
-
-
-/* Keep this definition in sync with the one in rdc_ioctl.h. */
-#ifndef SDBC_IOCTL
-#define SDBC_IOCTL(cmd, a0, a1, a2, a3, a4, ustatus) \
- sdbc_ioctl((long)(cmd), (long)(a0), (long)(a1), (long)(a2), \
- (long)(a3), (long)(a4), (spcs_s_info_t *)(ustatus))
-#endif
-
-int sdbc_ioctl(long, long, long, long, long, long, spcs_s_info_t *);
-
-
-#endif /* ! _KERNEL */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SDBC_IOCTL_H */
diff --git a/usr/src/uts/common/avs/ns/solaris/Makefile b/usr/src/uts/common/avs/ns/solaris/Makefile
deleted file mode 100644
index d891bb36b9..0000000000
--- a/usr/src/uts/common/avs/ns/solaris/Makefile
+++ /dev/null
@@ -1,50 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# include global definitions
-include ../../../../../Makefile.master
-
-HDRS= nsc_ddi.h \
- nskernd.h \
- nsc_thread.h
-
-ROOTDIR= $(ROOT)/usr/include/sys
-
-ROOTHDRS= $(HDRS:%=$(ROOTDIR)/%)
-
-# install rules
-$(ROOTDIR)/%: %
- $(INS.file)
-
-CHECKHDRS= $(HDRS:%.h=%.check)
-
-.KEEP_STATE:
-
-.PARALLEL: $(CHECKHDRS)
-
-install_h: $(ROOTDIR) $(ROOTHDRS)
-
-$(ROOTDIR):
- $(INS.dir)
-
-check: $(CHECKHDRS)
diff --git a/usr/src/uts/common/avs/ns/solaris/nsc_ddi.c b/usr/src/uts/common/avs/ns/solaris/nsc_ddi.c
deleted file mode 100644
index d8bc957670..0000000000
--- a/usr/src/uts/common/avs/ns/solaris/nsc_ddi.c
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * This file contains interface code to make the kernel look it has
- * an svr4.2 ddi/ddk. It also adds a little other system dependent
- * functionality that is useful for drivers lower than nsctl.
- */
-
-#include <sys/types.h>
-#ifndef DS_DDICT
-#include <sys/time.h> /* only DDI compliant as of 5.9 */
-#endif
-#include <sys/param.h>
-#include <sys/errno.h>
-#include <sys/kmem.h>
-#include <sys/ksynch.h>
-#include <sys/cmn_err.h>
-#include <sys/uio.h>
-#include <sys/conf.h>
-#include <sys/modctl.h>
-#ifndef DS_DDICT
-#include <sys/vnode.h>
-#endif
-#include <sys/open.h>
-#include <sys/ddi.h>
-
-#include "nsc_thread.h"
-
-#ifdef DS_DDICT
-#include <sys/nsctl/contract.h>
-#endif
-
-#include <sys/nsctl/nsctl.h>
-#include <sys/nsctl/nsvers.h>
-#include "nskernd.h"
-#include "nsc_list.h"
-
-kmutex_t _nskern_lock;
-
-void _nsc_stop_proc(void);
-void _nsc_start_proc(void);
-
-
-/*
- * Solaris specific driver module interface code.
- */
-
-static struct cb_ops nskern_cb_ops = {
- nulldev, /* open */
- nulldev, /* close */
- nodev, /* strategy */
- nodev, /* print */
- nodev, /* dump */
- nodev, /* read */
- nodev, /* write */
- nodev, /* ioctl */
- nodev, /* devmap routine */
- nodev, /* mmap routine */
- nodev, /* segmap */
- nochpoll, /* chpoll */
- ddi_prop_op,
- 0, /* not a STREAMS driver, no cb_str routine */
- D_NEW | D_MP | D_64BIT, /* safe for multi-thread/multi-processor */
- CB_REV,
- nodev, /* aread */
- nodev, /* awrite */
-};
-
-static int _nskern_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
-static int _nskern_attach(dev_info_t *, ddi_attach_cmd_t);
-static int _nskern_detach(dev_info_t *, ddi_detach_cmd_t);
-
-static struct dev_ops nskern_ops = {
- DEVO_REV, /* Driver build version */
- 0, /* device reference count */
- _nskern_getinfo,
- nulldev, /* identify */
- nulldev, /* probe */
- _nskern_attach,
- _nskern_detach,
- nodev, /* reset */
- &nskern_cb_ops,
- (struct bus_ops *)NULL
-};
-
-static struct modldrv nskern_ldrv = {
- &mod_driverops,
- "nws:Kernel Interface:" ISS_VERSION_STR,
- &nskern_ops
-};
-
-static dev_info_t *nskern_dip;
-
-static struct modlinkage nskern_modlinkage = {
- MODREV_1,
- &nskern_ldrv,
- NULL
-};
-
-/*
- * Solaris module load time code
- */
-
-int
-_init(void)
-{
- void nskern_init();
- int err;
-
- mutex_init(&_nskern_lock, NULL, MUTEX_DRIVER, NULL);
-
- err = mod_install(&nskern_modlinkage);
- if (err) {
- mutex_destroy(&_nskern_lock);
- cmn_err(CE_WARN, "nskern_init: mod_install err %d", err);
- return (err);
- }
-
- nskern_init();
-
- return (DDI_SUCCESS);
-}
-
-/*
- * Solaris module unload time code
- */
-
-int
-_fini(void)
-{
- int err;
-
- if ((err = mod_remove(&nskern_modlinkage)) == 0) {
- nskernd_stop();
- _nsc_stop_proc();
- nskernd_deinit();
-
- mutex_destroy(&_nskern_lock);
- }
-
- return (err);
-}
-
-int
-_info(struct modinfo *modinfop)
-{
- return (mod_info(&nskern_modlinkage, modinfop));
-}
-
-/*
- * Attach an instance of the device. This happens before an open
- * can succeed.
- */
-
-static int
-_nskern_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
-{
- if (cmd == DDI_ATTACH) {
- nskern_dip = dip;
- return (DDI_SUCCESS);
- } else {
- return (DDI_FAILURE);
- }
-}
-
-/* ARGSUSED */
-
-static int
-_nskern_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
-{
- if (cmd == DDI_DETACH) {
- nskern_dip = NULL;
- return (DDI_SUCCESS);
- } else {
- return (DDI_FAILURE);
- }
-}
-
-/* ARGSUSED */
-static int
-_nskern_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
-{
- int rc = DDI_FAILURE;
-
- switch (cmd) {
- case DDI_INFO_DEVT2DEVINFO:
- *result = nskern_dip;
- rc = DDI_SUCCESS;
- break;
-
- case DDI_INFO_DEVT2INSTANCE:
- /* single instance */
- *result = 0;
- rc = DDI_SUCCESS;
- break;
- }
-
- return (rc);
-}
-
-/* ARGSUSED */
-
-int
-_nskern_print(dev_t dev, char *s)
-{
- cmn_err(CE_WARN, "nskern:%s", s);
- return (0);
-}
-
-/*
- * nskern_init - initialize the nskern layer at module load time.
- */
-
-void
-nskern_init(void)
-{
- _nsc_start_proc();
- nskernd_init();
-
- (void) nst_startup();
-}
-
-
-#if (defined(DS_DDICT))
-static clock_t
-nskern_lbolt(void)
-{
-#ifdef _SunOS_5_6
- clock_t lbolt;
-
- if (drv_getparm(LBOLT, &lbolt) == 0)
- return (lbolt);
-
- return (0);
-#else
- return (ddi_get_lbolt());
-#endif
-}
-#endif /* ddict */
-
-
-/*
- * nsc_usec()
- * - return the value of the "microsecond timer emulation".
- *
- * Pre-SunOS 5.9:
- * Actually this is a fake free running counter based on the lbolt value.
- *
- * SunOS 5.9+
- * This is based on the gethrtime(9f) DDI facility.
- */
-
-#if (defined(DS_DDICT))
-/* these two #defines need to match! */
-#define USEC_SHIFT 16
-#define INCR_TYPE uint16_t
-#endif /* ! _SunOS_5_9+ */
-
-clock_t
-nsc_usec(void)
-{
- /* avoid divide by zero */
- return (gethrtime() / 1000);
-}
-
-
-/*
- * nsc_yield - yield the cpu.
- */
-void
-nsc_yield(void)
-{
- /* can't call yield() unless there is an lwp context */
- /* do this for now */
-
- delay(2);
-}
-
-
-/*
- * void
- * ls_ins_before(ls_elt_t *, ls_elt_t *)
- * Link new into list before old.
- *
- * Calling/Exit State:
- * None.
- */
-#ifdef lint
-void
-nsc_ddi_ls_ins_before(ls_elt_t *old, ls_elt_t *new)
-#else
-void
-ls_ins_before(ls_elt_t *old, ls_elt_t *new)
-#endif
-{
- new->ls_prev = old->ls_prev;
- new->ls_next = old;
- new->ls_prev->ls_next = new;
- new->ls_next->ls_prev = new;
-}
-
-/*
- * void
- * ls_ins_after(ls_elt_t *, ls_elt_t *)
- * Link new into list after old.
- *
- * Calling/Exit State:
- * None.
- */
-#ifdef lint
-void
-nsc_ddi_ls_ins_after(ls_elt_t *old, ls_elt_t *new)
-#else
-void
-ls_ins_after(ls_elt_t *old, ls_elt_t *new)
-#endif
-{
- new->ls_next = old->ls_next;
- new->ls_prev = old;
- new->ls_next->ls_prev = new;
- new->ls_prev->ls_next = new;
-}
-
-/*
- * ls_elt_t *
- * ls_remque(ls_elt_t *)
- * Unlink first element in the specified list.
- *
- * Calling/Exit State:
- * Returns the element's address or 0 if list is empty.
- * Resets elements pointers to empty list state.
- */
-ls_elt_t *
-ls_remque(ls_elt_t *p)
-{
- ls_elt_t *result = 0;
-
- if (!LS_ISEMPTY(p)) {
- result = p->ls_next;
- result->ls_prev->ls_next = result->ls_next;
- result->ls_next->ls_prev = result->ls_prev;
- LS_INIT(result);
- }
- return (result);
-}
-
-/*
- * void
- * ls_remove(ls_elt_t *)
- * Unlink donated element for list.
- *
- * Calling/Exit State:
- * Resets elements pointers to empty list state.
- */
-#ifdef lint
-void
-nsc_ddi_ls_remove(ls_elt_t *p)
-#else
-void
-ls_remove(ls_elt_t *p)
-#endif
-{
- p->ls_prev->ls_next = p->ls_next;
- p->ls_next->ls_prev = p->ls_prev;
- LS_INIT(p);
-}
diff --git a/usr/src/uts/common/avs/ns/solaris/nsc_ddi.h b/usr/src/uts/common/avs/ns/solaris/nsc_ddi.h
deleted file mode 100644
index 41172e2b92..0000000000
--- a/usr/src/uts/common/avs/ns/solaris/nsc_ddi.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _NSC_DDI_H
-#define _NSC_DDI_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * before we redefine our thread calls we must be sure that solaris has its
- * thread stuff defined else we'll redefine it also.
- */
-
-#include <sys/stat.h> /* for S_IFCHR and friends */
-#include <sys/ddi.h>
-#include <sys/sunddi.h>
-
-#ifdef _KERNEL
-
-/*
- * Misc
- */
-
-typedef caddr_t vaddr_t;
-
-#ifndef _BLIND_T
-#define _BLIND_T
-typedef void * blind_t;
-#endif /* _BLIND_T */
-
-typedef int (*blindfn_t)();
-typedef uintptr_t mc_io_addr_t;
-
-/*
- * You would think that sys/ddi.h would define these, as they are in the ddi.
- */
-extern int copyout(const void *, void *, size_t);
-extern int copyin(const void *, void *, size_t);
-
-#endif /* _KERNEL */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _NSC_DDI_H */
diff --git a/usr/src/uts/common/avs/ns/solaris/nsc_list.c b/usr/src/uts/common/avs/ns/solaris/nsc_list.c
deleted file mode 100644
index 07a3dfff34..0000000000
--- a/usr/src/uts/common/avs/ns/solaris/nsc_list.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * Generic lists
- * Lists are circular, doubly-linked, with headers.
- * When a list is empty, both pointers in the header
- * point to the header itself.
- */
-
-#include "nsc_list.h"
-/*
- * void
- * ls_remove(ls_elt_t *)
- * Unlink donated element for list.
- *
- * Calling/Exit State:
- * Resets elements pointers to empty list state.
- */
-void
-ls_remove(ls_elt_t *p)
-{
- p->ls_prev->ls_next = p->ls_next;
- p->ls_next->ls_prev = p->ls_prev;
- LS_INIT(p);
-}
-/*
- * void
- * ls_ins_after(ls_elt_t *, ls_elt_t *)
- *
- * Link new into list after old.
- *
- * Calling/Exit State:
- *
- * None.
- */
-void
-ls_ins_after(ls_elt_t *old, ls_elt_t *new)
-{
- new->ls_next = old->ls_next;
- new->ls_prev = old;
- new->ls_next->ls_prev = new;
- new->ls_prev->ls_next = new;
-}
-
-
-/*
- * void
- * ls_ins_before(ls_elt_t *, ls_elt_t *)
- * Link new into list after old.
- *
- * Calling/Exit State:
- *
- * None.
- */
-void
-ls_ins_before(ls_elt_t *old, ls_elt_t *new)
-{
- new->ls_prev = old->ls_prev;
- new->ls_next = old;
- new->ls_prev->ls_next = new;
- new->ls_next->ls_prev = new;
-}
diff --git a/usr/src/uts/common/avs/ns/solaris/nsc_list.h b/usr/src/uts/common/avs/ns/solaris/nsc_list.h
deleted file mode 100644
index 771053c5cf..0000000000
--- a/usr/src/uts/common/avs/ns/solaris/nsc_list.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _NSC_LIST_H
-#define _NSC_LIST_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Generic lists support.
- */
-
-
-/*
- * Lists are circular and doubly-linked, with headers.
- * When a list is empty, both pointers in the header
- * point to the header itself.
- */
-
-#if defined(_KERNEL) || defined(_KMEMUSER)
-
-/* list element */
-typedef struct ls_elt {
- struct ls_elt *ls_next;
- struct ls_elt *ls_prev;
-} ls_elt_t;
-
-#endif /* _KERNEL || _KMEMUSER */
-
-#ifdef _KERNEL
-
-/*
- * All take as arguments side effect-free pointers to list structures
- */
-#define LS_ISEMPTY(listp) \
- (((ls_elt_t *)(listp))->ls_next == (ls_elt_t *)(listp))
-#define LS_INIT(listp) { \
- ((ls_elt_t *)(listp))->ls_next = \
- ((ls_elt_t *)(listp))->ls_prev = \
- ((ls_elt_t *)(listp)); \
-}
-
-#define LS_REMOVE(listp) ls_remove((ls_elt_t *)(listp))
-
-/*
- * For these five, ptrs are to list elements, but qp and stackp are
- * implicitly headers.
- */
-#define LS_INS_BEFORE(oldp, newp) \
- ls_ins_before((ls_elt_t *)(oldp), (ls_elt_t *)(newp))
-
-#define LS_INS_AFTER(oldp, newp) \
- ls_ins_after((ls_elt_t *)(oldp), (ls_elt_t *)(newp))
-
-#define LS_INSQUE(qp, eltp) \
- ls_ins_before((ls_elt_t *)(qp), (ls_elt_t *)(eltp))
-
-/* result needs cast; 0 result if empty queue */
-#define LS_REMQUE(qp) ls_remque((ls_elt_t *)(qp))
-
-#define LS_PUSH(stackp, newp) \
- ls_ins_after((ls_elt_t *)(stackp), (ls_elt_t *)(newp))
-
-/* result needs cast; 0 result if empty stack */
-#define LS_POP(stackp) ls_remque((ls_elt_t *)(stackp))
-
-/* public function declarations */
-void ls_ins_before(ls_elt_t *, ls_elt_t *);
-void ls_ins_after(ls_elt_t *, ls_elt_t *);
-ls_elt_t *ls_remque(ls_elt_t *);
-void ls_remove(ls_elt_t *);
-
-#endif /* _KERNEL */
-
-#if defined(_KERNEL) || defined(_KMEMUSER)
-
-typedef struct llist {
- struct llist *volatile flink; /* forward link */
- struct llist *volatile rlink; /* reverse link */
-} llist_t;
-
-#endif /* _KERNEL || _KMEMUSER */
-
-#ifdef _KERNEL
-
-#define INITQUE(l) ((l)->flink = (l)->rlink = (l))
-#define EMPTYQUE(l) ((l)->flink == (l))
-
-#endif /* _KERNEL */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _NSC_LIST_H */
diff --git a/usr/src/uts/common/avs/ns/solaris/nsc_proc.c b/usr/src/uts/common/avs/ns/solaris/nsc_proc.c
deleted file mode 100644
index 317f1871f5..0000000000
--- a/usr/src/uts/common/avs/ns/solaris/nsc_proc.c
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/ksynch.h>
-#include <sys/errno.h>
-#include <sys/cmn_err.h>
-#include <sys/conf.h>
-#include <sys/kmem.h>
-#include <sys/ddi.h>
-
-#define __NSC_GEN__
-#include <sys/nsctl/nsc_rmspin.h>
-#include "../nsctl.h"
-#include "nskernd.h"
-
-struct nsc_nlwp {
- struct nsc_nlwp *next;
- void (*fn)(void *);
- void *arg;
- volatile int ready;
- int errno;
- kcondvar_t child_cv;
-};
-
-kmutex_t nsc_proc_lock;
-kcondvar_t nsc_proc_cv;
-
-static struct nsc_nlwp *nsc_nlwp_top;
-
-void
-_nsc_start_proc(void)
-{
- mutex_init(&nsc_proc_lock, NULL, MUTEX_DRIVER, NULL);
- cv_init(&nsc_proc_cv, NULL, CV_DRIVER, NULL);
-}
-
-
-void
-_nsc_stop_proc(void)
-{
- mutex_destroy(&nsc_proc_lock);
- cv_destroy(&nsc_proc_cv);
-}
-
-
-/*
- * Create a daemon (server) proc.
- *
- * If 'rt' is TRUE, then increase the scheduling priority of the lwp.
- * Exactly how, if at all, this feature is implemented is at the
- * discretion of nskernd.
- *
- * Returns 0 or errno.
- */
-
-int
-nsc_create_process(void (*func)(void *), void *arg, boolean_t rt)
-{
- struct nsc_nlwp *nlwp, **nlwpp;
- struct nskernd *nsk = NULL;
- int rc = 0;
-
- nlwp = kmem_zalloc(sizeof (*nlwp), KM_NOSLEEP);
- nsk = kmem_zalloc(sizeof (*nsk), KM_NOSLEEP);
- if (!nlwp || !nsk) {
- if (nlwp) {
- kmem_free(nlwp, sizeof (*nlwp));
- }
- if (nsk) {
- kmem_free(nsk, sizeof (*nsk));
- }
- return (ENOMEM);
- }
-
- nlwp->fn = func;
- nlwp->arg = arg;
-
- mutex_enter(&nsc_proc_lock);
-
- nlwp->next = nsc_nlwp_top;
- nsc_nlwp_top = nlwp;
-
- mutex_exit(&nsc_proc_lock);
-
- nsk->command = NSKERND_NEWLWP;
- nsk->data1 = (uint64_t)(unsigned long)nlwp;
- nsk->data2 = (uint64_t)rt;
-
- rc = nskernd_get(nsk);
-
- /* user level returns error in nsk->data1 */
- if (!rc && nsk->data1)
- rc = nsk->data1;
-
- mutex_enter(&nsc_proc_lock);
-
- if (!rc) {
- /*
- * wait for the child to start and check in.
- */
-
- while (! nlwp->ready) {
- cv_wait(&nsc_proc_cv, &nsc_proc_lock);
- }
- }
-
- /*
- * remove from list of outstanding requests.
- */
-
- for (nlwpp = &nsc_nlwp_top; (*nlwpp); nlwpp = &((*nlwpp)->next)) {
- if (*nlwpp == nlwp) {
- *nlwpp = nlwp->next;
- break;
- }
- }
-
- mutex_exit(&nsc_proc_lock);
-
- kmem_free(nlwp, sizeof (*nlwp));
- kmem_free(nsk, sizeof (*nsk));
- return (rc);
-}
-
-
-/*
- * Child lwp calls this function when it returns to the kernel.
- *
- * Check if the args are still on the pending list. If they are, then
- * run the required function. If they are not, then something went
- * wrong, so just return back to userland and die.
- */
-void
-nsc_runlwp(uint64_t arg)
-{
- struct nsc_nlwp *nlwp;
- void (*fn)(void *);
- void *fn_arg;
-
- fn_arg = NULL;
- fn = NULL;
-
- mutex_enter(&nsc_proc_lock);
-
- /*
- * check that the request is still on the list of work to do
- */
-
- for (nlwp = nsc_nlwp_top; nlwp; nlwp = nlwp->next) {
- if (nlwp == (struct nsc_nlwp *)(unsigned long)arg) {
- fn_arg = nlwp->arg;
- fn = nlwp->fn;
-
- /* mark as ready */
- nlwp->ready = 1;
- cv_broadcast(&nsc_proc_cv);
-
- break;
- }
- }
-
- mutex_exit(&nsc_proc_lock);
-
- if (fn) {
- (*fn)(fn_arg);
- }
-}
-
-
-/*
- * Create a thread that acquires an inter-node lock.
- *
- * mode - 0 (read), 1 (write).
- * lockp - used to return the opaque address of a sync structure, which
- * must be passed to nsc_do_unlock() later.
- *
- * Returns 0 or errno.
- */
-
-int
-nsc_do_lock(int mode, void **lockp)
-{
- struct nsc_nlwp *nlwp = NULL, **nlwpp;
- struct nskernd *nsk = NULL;
- int rc = 0;
-
- nlwp = kmem_zalloc(sizeof (*nlwp), KM_NOSLEEP);
- nsk = kmem_zalloc(sizeof (*nsk), KM_NOSLEEP);
- if (!nlwp || !nsk) {
- if (nlwp) {
- kmem_free(nlwp, sizeof (*nlwp));
- }
- if (nsk) {
- kmem_free(nsk, sizeof (*nsk));
- }
- return (ENOMEM);
- }
-
- cv_init(&nlwp->child_cv, NULL, CV_DRIVER, NULL);
-
- mutex_enter(&nsc_proc_lock);
-
- nlwp->next = nsc_nlwp_top;
- nsc_nlwp_top = nlwp;
-
- mutex_exit(&nsc_proc_lock);
-
- nsk->command = NSKERND_LOCK;
- nsk->data1 = (uint64_t)(unsigned long)nlwp;
- nsk->data2 = (uint64_t)mode;
-
- rc = nskernd_get(nsk);
-
- /* user level returns error in nsk->data1 */
- if (!rc && nsk->data1)
- rc = nsk->data1;
-
- mutex_enter(&nsc_proc_lock);
-
- if (!rc) {
- /*
- * wait for the child to start and check in.
- */
-
- while (! nlwp->ready) {
- cv_wait(&nsc_proc_cv, &nsc_proc_lock);
- }
-
- /* retrieve errno from child's lock operation */
- rc = (int)nlwp->errno;
- }
-
- if (rc) {
- /*
- * error - remove from list of outstanding requests as
- * child will not be checking in (nskernd_get() failed
- * or user thread create failed) or will not be waiting
- * (child thread lock failure).
- */
-
- for (nlwpp = &nsc_nlwp_top; (*nlwpp);
- nlwpp = &((*nlwpp)->next)) {
- if (*nlwpp == nlwp) {
- *nlwpp = nlwp->next;
- break;
- }
- }
-
- mutex_exit(&nsc_proc_lock);
-
- cv_destroy(&nlwp->child_cv);
- kmem_free(nlwp, sizeof (*nlwp));
- kmem_free(nsk, sizeof (*nsk));
- *lockp = NULL;
- return (rc);
- }
-
- /* success, return argument for nsc_do_unlock() */
-
- mutex_exit(&nsc_proc_lock);
-
- kmem_free(nsk, sizeof (*nsk));
- *lockp = nlwp;
- return (0);
-}
-
-
-void
-nsc_do_unlock(void *arg)
-{
- struct nsc_nlwp *nlwp;
-
- /* find child on work list */
-
- mutex_enter(&nsc_proc_lock);
-
- for (nlwp = nsc_nlwp_top; nlwp; nlwp = nlwp->next) {
- if (nlwp == (struct nsc_nlwp *)arg) {
- /* signal unlock */
- nlwp->ready = 0;
- cv_broadcast(&nlwp->child_cv);
- }
- }
-
- mutex_exit(&nsc_proc_lock);
-}
-
-
-/*
- * Lock child thread calls this function when it returns to the kernel.
- *
- * Check if the args are still on the pending list. If they are, then
- * post the lock results and wait for the unlock. If they are not,
- * then something went wrong, so just return back to userland and die.
- */
-void
-nsc_lockchild(uint64_t arg, uint64_t errno)
-{
- struct nsc_nlwp *nlwp, **nlwpp;
-
- if (!arg) {
- return;
- }
-
- mutex_enter(&nsc_proc_lock);
-
- /*
- * check that the request is still on the list of work to do
- */
-
- for (nlwp = nsc_nlwp_top; nlwp; nlwp = nlwp->next) {
- if (nlwp == (struct nsc_nlwp *)(unsigned long)arg) {
- /* mark as ready */
- nlwp->errno = (int)errno;
- nlwp->ready = 1;
- cv_broadcast(&nsc_proc_cv);
- break;
- }
- }
-
- if (!nlwp || errno) {
- /*
- * Error - either this request is no longer on the work
- * queue, or there was an error in the userland lock code
- * in which case the lock caller (currently blocked in
- * nsc_do_lock() will do the cleanup.
- */
- mutex_exit(&nsc_proc_lock);
- return;
- }
-
- /*
- * no errors, so wait for an unlock
- */
-
- while (nlwp->ready) {
- cv_wait(&nlwp->child_cv, &nsc_proc_lock);
- }
-
- /*
- * remove self from list of outstanding requests.
- */
-
- for (nlwpp = &nsc_nlwp_top; (*nlwpp); nlwpp = &((*nlwpp)->next)) {
- if (*nlwpp == nlwp) {
- *nlwpp = nlwp->next;
- break;
- }
- }
-
- /*
- * cleanup
- */
-
- cv_destroy(&nlwp->child_cv);
- kmem_free(nlwp, sizeof (*nlwp));
-
- mutex_exit(&nsc_proc_lock);
-}
diff --git a/usr/src/uts/common/avs/ns/solaris/nsc_raw.c b/usr/src/uts/common/avs/ns/solaris/nsc_raw.c
deleted file mode 100644
index 171ac3ec07..0000000000
--- a/usr/src/uts/common/avs/ns/solaris/nsc_raw.c
+++ /dev/null
@@ -1,853 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/debug.h>
-#include <sys/kmem.h>
-#include <sys/ksynch.h>
-#ifndef DS_DDICT
-#include <sys/vnode.h>
-#endif
-#include <sys/cmn_err.h>
-#include <sys/open.h>
-#include <sys/file.h>
-#include <sys/cred.h>
-#include <sys/conf.h>
-#include <sys/errno.h>
-#include <sys/uio.h>
-#ifndef DS_DDICT
-#include <sys/pathname.h> /* for lookupname */
-#endif
-#include <sys/ddi.h>
-#include <sys/sunddi.h>
-#include <sys/sunldi.h>
-
-#include <ns/solaris/nsc_thread.h>
-#ifdef DS_DDICT
-#include "../contract.h"
-#endif
-#include "../nsctl.h"
-#include "nskernd.h"
-
-
-typedef struct raw_maj {
- struct raw_maj *next;
- major_t major;
- struct dev_ops *devops;
- strategy_fn_t strategy;
- int (*open)(dev_t *, int, int, cred_t *);
- int (*close)(dev_t, int, int, cred_t *);
- int (*ioctl)(dev_t, int, intptr_t, int, cred_t *, int *);
-} raw_maj_t;
-
-typedef struct raw_dev {
- ldi_handle_t lh; /* Solaris layered driver handle */
- struct vnode *vp; /* vnode of device */
- uint64_t size; /* size of device in blocks */
- raw_maj_t *major; /* pointer to major structure */
- char *path; /* pathname -- kmem_alloc'd */
- int plen; /* length of kmem_alloc for pathname */
- dev_t rdev; /* device number */
- char in_use; /* flag */
- int partition; /* partition number */
-} raw_dev_t;
-
-static int fd_hwm = 0; /* first never used entry in _nsc_raw_files */
-
-static raw_dev_t *_nsc_raw_files;
-static raw_maj_t *_nsc_raw_majors;
-
-kmutex_t _nsc_raw_lock;
-
-int _nsc_raw_flags = 0; /* required by nsctl */
-static int _nsc_raw_maxdevs; /* local copy */
-
-static int _raw_strategy(struct buf *); /* forward decl */
-
-static dev_t
-ldi_get_dev_t_from_path(char *path)
-{
- vnode_t *vp;
- dev_t rdev;
-
- /* Validate parameters */
- if (path == NULL)
- return (NULL);
-
- /* Lookup path */
- vp = NULL;
- if (lookupname(path, UIO_SYSSPACE, FOLLOW, NULLVPP, &vp))
- return (NULL);
-
- /* Validate resulting vnode */
- if ((vp) && (vp->v_type == VCHR))
- rdev = vp->v_rdev;
- else
- rdev = (dev_t)NULL;
-
- /* Release vnode */
- if (vp)
- VN_RELE(vp);
-
- return (rdev);
-}
-
-int
-_nsc_init_raw(int maxdevs)
-{
- _nsc_raw_files =
- kmem_zalloc(sizeof (*_nsc_raw_files) * maxdevs, KM_SLEEP);
- if (!_nsc_raw_files)
- return (ENOMEM);
-
- _nsc_raw_maxdevs = maxdevs;
- _nsc_raw_majors = NULL;
-
- mutex_init(&_nsc_raw_lock, NULL, MUTEX_DRIVER, NULL);
- return (0);
-}
-
-
-void
-_nsc_deinit_raw(void)
-{
- raw_maj_t *maj = _nsc_raw_majors;
- raw_maj_t *next;
-
- /* Free the memory allocated for strategy pointers */
- while (maj != NULL) {
- next = maj->next;
- kmem_free(maj, sizeof (*maj));
- maj = next;
- }
-
- mutex_destroy(&_nsc_raw_lock);
- kmem_free(_nsc_raw_files, sizeof (*_nsc_raw_files) * _nsc_raw_maxdevs);
- _nsc_raw_files = NULL;
- _nsc_raw_maxdevs = 0;
-}
-
-
-/* must be called with the _nsc_raw_lock held */
-static raw_maj_t *
-_raw_get_maj_info(major_t umaj)
-{
- raw_maj_t *maj = _nsc_raw_majors;
-
- ASSERT(MUTEX_HELD(&_nsc_raw_lock));
-
- /* Walk through the linked list */
- while (maj != NULL) {
- if (maj->major == umaj) {
- /* Found major number */
- break;
- }
- maj = maj->next;
- }
-
- if (maj == NULL) {
- struct dev_ops *ops = NULL;
-#ifdef DEBUG
- const int maxtry = 5;
- int try = maxtry;
-#endif
-
- /*
- * The earlier ldi_open call has locked the driver
- * for this major number into memory, so just index into
- * the devopsp array to get the dev_ops pointer which
- * must be valid.
- */
-
- ops = devopsp[umaj];
-
- if (ops == NULL || ops->devo_cb_ops == NULL) {
- cmn_err(CE_WARN,
- "nskern: cannot find dev_ops for major %d", umaj);
-
- return (NULL);
- }
-
-#ifdef DEBUG
- cmn_err(CE_NOTE,
- "nsc_raw: held driver (%d) after %d attempts",
- umaj, (maxtry - try));
-#endif /* DEBUG */
-
- maj = kmem_zalloc(sizeof (raw_maj_t), KM_NOSLEEP);
- if (!maj) {
- return (NULL);
- }
-
- maj->strategy = ops->devo_cb_ops->cb_strategy;
- maj->ioctl = ops->devo_cb_ops->cb_ioctl;
- maj->close = ops->devo_cb_ops->cb_close;
- maj->open = ops->devo_cb_ops->cb_open;
- maj->major = umaj;
- maj->devops = ops;
-
- if (maj->strategy == NULL ||
- maj->strategy == nodev ||
- maj->strategy == nulldev) {
- cmn_err(CE_WARN,
- "nskern: no strategy function for "
- "disk driver (major %d)",
- umaj);
- kmem_free(maj, sizeof (*maj));
- return (NULL);
- }
-
- maj->next = _nsc_raw_majors;
- _nsc_raw_majors = maj;
- }
-
- return (maj);
-}
-
-
-/*
- * nsc_get_strategy returns the strategy function associated with
- * the major number umaj. NULL is returned if no strategy is found.
- */
-strategy_fn_t
-nsc_get_strategy(major_t umaj)
-{
- raw_maj_t *maj;
- strategy_fn_t strategy = NULL;
-
- mutex_enter(&_nsc_raw_lock);
-
- for (maj = _nsc_raw_majors; maj != NULL; maj = maj->next) {
- if (maj->major == umaj) {
- /* Found major number */
- strategy = maj->strategy;
- break;
- }
- }
-
- mutex_exit(&_nsc_raw_lock);
-
- return (strategy);
-}
-
-
-void *
-nsc_get_devops(major_t umaj)
-{
- raw_maj_t *maj;
- void *devops = NULL;
-
- mutex_enter(&_nsc_raw_lock);
-
- for (maj = _nsc_raw_majors; maj != NULL; maj = maj->next) {
- if (maj->major == umaj) {
- devops = maj->devops;
- break;
- }
- }
-
- mutex_exit(&_nsc_raw_lock);
-
- return (devops);
-}
-
-
-/*
- * _raw_open
- *
- * Multiple opens, single close.
- */
-
-/* ARGSUSED */
-static int
-_raw_open(char *path, int flag, blind_t *cdp, void *iodev)
-{
- struct cred *cred;
- raw_dev_t *cdi = NULL;
- char *spath;
- dev_t rdev;
- int rc, cd, the_cd;
- int plen;
- ldi_ident_t li;
-
- if (proc_nskernd == NULL) {
- cmn_err(CE_WARN, "nskern: no nskernd daemon running!");
- return (ENXIO);
- }
-
- if (_nsc_raw_maxdevs == 0) {
- cmn_err(CE_WARN, "nskern: _raw_open() before _nsc_init_raw()!");
- return (ENXIO);
- }
-
- plen = strlen(path) + 1;
- spath = kmem_alloc(plen, KM_SLEEP);
- if (spath == NULL) {
- cmn_err(CE_WARN,
- "nskern: unable to alloc memory in _raw_open()");
- return (ENOMEM);
- }
-
- (void) strcpy(spath, path);
-
- /*
- * Lookup the vnode to extract the dev_t info,
- * then release the vnode.
- */
- if ((rdev = ldi_get_dev_t_from_path(path)) == 0) {
- kmem_free(spath, plen);
- return (ENXIO);
- }
-
- /*
- * See if this device is already opened
- */
-
- the_cd = -1;
-
- mutex_enter(&_nsc_raw_lock);
-
- for (cd = 0, cdi = _nsc_raw_files; cd < fd_hwm; cd++, cdi++) {
- if (rdev == cdi->rdev) {
- the_cd = cd;
- break;
- } else if (the_cd == -1 && !cdi->in_use)
- the_cd = cd;
- }
-
- if (the_cd == -1) {
- if (fd_hwm < _nsc_raw_maxdevs)
- the_cd = fd_hwm++;
- else {
- mutex_exit(&_nsc_raw_lock);
- cmn_err(CE_WARN, "_raw_open: too many open devices");
- kmem_free(spath, plen);
- return (EIO);
- }
- }
-
- cdi = &_nsc_raw_files[the_cd];
- if (cdi->in_use) {
- /* already set up - just return */
- mutex_exit(&_nsc_raw_lock);
- *cdp = (blind_t)cdi->rdev;
- kmem_free(spath, plen);
- return (0);
- }
-
- cdi->partition = -1;
- cdi->size = (uint64_t)0;
- cdi->rdev = rdev;
- cdi->path = spath;
- cdi->plen = plen;
-
- cred = ddi_get_cred();
-
- /*
- * Layered driver
- *
- * We use xxx_open_by_dev() since this guarantees that a
- * specfs vnode is created and used, not a standard filesystem
- * vnode. This is necessary since in a cluster PXFS will block
- * vnode operations during switchovers, so we have to use the
- * underlying specfs vnode not the PXFS vnode.
- *
- */
-
- if ((rc = ldi_ident_from_dev(cdi->rdev, &li)) == 0) {
- rc = ldi_open_by_dev(&cdi->rdev,
- OTYP_BLK, FREAD|FWRITE, cred, &cdi->lh, li);
- }
- if (rc != 0) {
- cdi->lh = NULL;
- goto failed;
- }
-
- /*
- * grab the major_t related information
- */
-
- cdi->major = _raw_get_maj_info(getmajor(rdev));
- if (cdi->major == NULL) {
- /* Out of memory */
- cmn_err(CE_WARN,
- "_raw_open: cannot alloc major number structure");
-
- rc = ENOMEM;
- goto failed;
- }
-
- *cdp = (blind_t)cdi->rdev;
- cdi->in_use++;
-
- mutex_exit(&_nsc_raw_lock);
-
- return (rc);
-
-failed:
-
- if (cdi->lh)
- (void) ldi_close(cdi->lh, FWRITE|FREAD, cred);
-
- bzero(cdi, sizeof (*cdi));
-
- mutex_exit(&_nsc_raw_lock);
-
- kmem_free(spath, plen);
- return (rc);
-}
-
-
-static int
-__raw_get_cd(dev_t fd)
-{
- int cd;
-
- if (_nsc_raw_maxdevs != 0) {
- for (cd = 0; cd < fd_hwm; cd++) {
- if (fd == _nsc_raw_files[cd].rdev)
- return (cd);
- }
- }
-
- return (-1);
-}
-
-
-/*
- * _raw_close
- *
- * Multiple opens, single close.
- */
-
-static int
-_raw_close(dev_t fd)
-{
- struct cred *cred;
- raw_dev_t *cdi;
- int rc;
- int cd;
-
- mutex_enter(&_nsc_raw_lock);
-
- if ((cd = __raw_get_cd(fd)) == -1 || !_nsc_raw_files[cd].in_use) {
- mutex_exit(&_nsc_raw_lock);
- return (EIO);
- }
-
- cdi = &_nsc_raw_files[cd];
-
- cred = ddi_get_cred();
-
- rc = ldi_close(cdi->lh, FREAD|FWRITE, cred);
- if (rc != 0) {
- mutex_exit(&_nsc_raw_lock);
- return (rc);
- }
-
- kmem_free(cdi->path, cdi->plen);
-
- bzero(cdi, sizeof (*cdi));
-
- mutex_exit(&_nsc_raw_lock);
-
- return (0);
-}
-
-
-/* ARGSUSED */
-static int
-_raw_uread(dev_t fd, uio_t *uiop, cred_t *crp)
-{
- return (physio(_raw_strategy, 0, fd, B_READ, minphys, uiop));
-}
-
-
-/* ARGSUSED */
-static int
-_raw_uwrite(dev_t fd, uio_t *uiop, cred_t *crp)
-{
- return (physio(_raw_strategy, 0, fd, B_WRITE, minphys, uiop));
-}
-
-
-static int
-_raw_strategy(struct buf *bp)
-{
- int cd = __raw_get_cd(bp->b_edev);
-
- if (cd == -1 || _nsc_raw_files[cd].major == NULL) {
- bioerror(bp, ENXIO);
- biodone(bp);
- return (NULL);
- }
-
- return ((*_nsc_raw_files[cd].major->strategy)(bp));
-}
-
-
-static int
-_raw_partsize(dev_t fd, nsc_size_t *rvalp)
-{
- int cd;
-
- if ((cd = __raw_get_cd(fd)) == -1 || !_nsc_raw_files[cd].in_use)
- return (EIO);
-
- *rvalp = (nsc_size_t)_nsc_raw_files[cd].size;
- return (0);
-}
-
-
-/*
- * Return largest i/o size.
- */
-
-static nsc_size_t nsc_rawmaxfbas = 0;
-/* ARGSUSED */
-static int
-_raw_maxfbas(dev_t dev, int flag, nsc_size_t *ptr)
-{
- struct buf *bp;
- if (flag == NSC_CACHEBLK)
- *ptr = 1;
- else {
- if (nsc_rawmaxfbas == 0) {
- bp = getrbuf(KM_SLEEP);
- bp->b_bcount = 4096 * 512;
- minphys(bp);
- nsc_rawmaxfbas = FBA_NUM(bp->b_bcount);
- freerbuf(bp);
- }
- *ptr = nsc_rawmaxfbas;
- }
- return (0);
-}
-
-
-/*
- * Control device or system.
- */
-
-/* ARGSUSED */
-static int
-_raw_control(dev_t dev, int cmd, int *ptr)
-{
-#ifdef DEBUG
- cmn_err(CE_WARN, "unrecognised nsc_control: %x", cmd);
-#endif
- return (EINVAL); /* no control commands understood */
-}
-
-
-static int
-_raw_get_bsize(dev_t dev, uint64_t *bsizep, int *partitionp)
-{
-#ifdef DKIOCPARTITION
- struct partition64 *p64 = NULL;
-#endif
- struct dk_cinfo *dki_info = NULL;
- struct dev_ops *ops;
- struct cred *cred;
- struct vtoc *vtoc = NULL;
- dev_info_t *dip;
- raw_dev_t *cdi;
- int rc, cd;
- int flags;
- int rval;
-
- *partitionp = -1;
- *bsizep = 0;
-
- if ((cd = __raw_get_cd(dev)) == -1 || !_nsc_raw_files[cd].in_use)
- return (-1);
-
- cdi = &_nsc_raw_files[cd];
- ops = cdi->major->devops;
-
- if (ops == NULL) {
- return (-1);
- }
-
- rc = (*ops->devo_getinfo)(NULL, DDI_INFO_DEVT2DEVINFO,
- (void *)dev, (void **)&dip);
-
- if (rc != DDI_SUCCESS || dip == NULL) {
- return (-1);
- }
-
- if (!ddi_prop_exists(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, DDI_KERNEL_IOCTL)) {
- return (-1);
- }
-
- cred = ddi_get_cred();
-
- flags = FKIOCTL | FREAD | FWRITE | DATAMODEL_NATIVE;
-
- dki_info = kmem_alloc(sizeof (*dki_info), KM_SLEEP);
-
- /* DKIOCINFO */
- rc = (*cdi->major->ioctl)(dev, DKIOCINFO,
- (intptr_t)dki_info, flags, cred, &rval);
-
- if (rc != 0) {
- goto out;
- }
-
- /* return partition number */
- *partitionp = (int)dki_info->dki_partition;
-
- vtoc = kmem_alloc(sizeof (*vtoc), KM_SLEEP);
-
- /* DKIOCGVTOC */
- rc = (*cdi->major->ioctl)(dev, DKIOCGVTOC,
- (intptr_t)vtoc, flags, cred, &rval);
-
- if (rc) {
- /* DKIOCGVTOC failed, but there might be an EFI label */
- rc = -1;
-
-#ifdef DKIOCPARTITION
- /* do we have an EFI partition table? */
- p64 = kmem_alloc(sizeof (*p64), KM_SLEEP);
- p64->p_partno = (uint_t)*partitionp;
-
- /* DKIOCPARTITION */
- rc = (*cdi->major->ioctl)(dev, DKIOCPARTITION,
- (intptr_t)p64, flags, cred, &rval);
-
- if (rc == 0) {
- /* found EFI, return size */
- *bsizep = (uint64_t)p64->p_size;
- } else {
- /* both DKIOCGVTOC and DKIOCPARTITION failed - error */
- rc = -1;
- }
-#endif
-
- goto out;
- }
-
- if ((vtoc->v_sanity != VTOC_SANE) ||
- (vtoc->v_version != V_VERSION && vtoc->v_version != 0) ||
- (dki_info->dki_partition > V_NUMPAR)) {
- rc = -1;
- goto out;
- }
-
- *bsizep = (uint64_t)vtoc->v_part[(int)dki_info->dki_partition].p_size;
- rc = 0;
-
-out:
- if (dki_info) {
- kmem_free(dki_info, sizeof (*dki_info));
- }
-
- if (vtoc) {
- kmem_free(vtoc, sizeof (*vtoc));
- }
-
-#ifdef DKIOCPARTITION
- if (p64) {
- kmem_free(p64, sizeof (*p64));
- }
-#endif
-
- return (rc);
-}
-
-
-/*
- * Ugly, ugly, ugly.
- *
- * Some volume managers (Veritas) don't support layered ioctls
- * (no FKIOCTL support, no DDI_KERNEL_IOCTL property defined) AND
- * do not support the properties for bdev_Size()/bdev_size().
- *
- * If the underlying driver has specified DDI_KERNEL_IOCTL, then we use
- * the FKIOCTL technique. Otherwise ...
- *
- * The only reliable way to get the partition size, is to bounce the
- * command through user land (nskernd).
- *
- * Then, SunCluster PXFS blocks access at the vnode level to device
- * nodes during failover / switchover, so a read_vtoc() function call
- * from user land deadlocks. So, we end up coming back into the kernel
- * to go directly to the underlying device driver - that's what
- * nskern_bsize() is doing below.
- *
- * There has to be a better way ...
- */
-
-static int
-_raw_init_dev(dev_t fd, uint64_t *sizep, int *partitionp)
-{
- struct nskernd *nsk;
- int rc, cd;
-
- if ((cd = __raw_get_cd(fd)) == -1 || !_nsc_raw_files[cd].in_use)
- return (EIO);
-
- /* try the in-kernel way */
-
- rc = _raw_get_bsize(fd, sizep, partitionp);
- if (rc == 0) {
- return (0);
- }
-
- /* fallback to the the slow way */
-
- nsk = kmem_zalloc(sizeof (*nsk), KM_SLEEP);
- nsk->command = NSKERND_BSIZE;
- nsk->data1 = (uint64_t)0;
- nsk->data2 = (uint64_t)fd;
- (void) strncpy(nsk->char1, _nsc_raw_files[cd].path, NSC_MAXPATH);
-
- rc = nskernd_get(nsk);
- if (rc == 0) {
- *partitionp = (int)nsk->data2;
- *sizep = nsk->data1;
- }
-
- kmem_free(nsk, sizeof (*nsk));
- return (rc < 0 ? EIO : 0);
-}
-
-
-static int
-_raw_attach_io(dev_t fd)
-{
- int cd;
-
- if ((cd = __raw_get_cd(fd)) == -1 || !_nsc_raw_files[cd].in_use)
- return (EIO);
-
- return (_raw_init_dev(fd, &_nsc_raw_files[cd].size,
- &_nsc_raw_files[cd].partition));
-}
-
-
-/*
- * See the comment above _raw_init_dev().
- */
-
-int
-nskern_bsize(struct nscioc_bsize *bsize, int *rvp)
-{
- struct cred *cred;
- raw_dev_t *cdi;
- int errno = 0;
- int flag;
- int cd;
-
- *rvp = 0;
-
- if (bsize == NULL || rvp == NULL)
- return (EINVAL);
-
- cd = __raw_get_cd(bsize->raw_fd);
- if (cd == -1 || !_nsc_raw_files[cd].in_use)
- return (EIO);
-
- cdi = &_nsc_raw_files[cd];
- cred = ddi_get_cred();
-
- /*
- * ddi_mmap_get_model() returns the model for this user thread
- * which is what we want - get_udatamodel() is not public.
- */
-
- flag = FREAD | FWRITE | ddi_mmap_get_model();
-
- if (bsize->efi == 0) {
- /* DKIOCINFO */
- errno = (*cdi->major->ioctl)(bsize->raw_fd,
- DKIOCINFO, (intptr_t)bsize->dki_info, flag, cred, rvp);
-
- if (errno) {
- return (errno);
- }
-
- /* DKIOCGVTOC */
- errno = (*cdi->major->ioctl)(bsize->raw_fd,
- DKIOCGVTOC, (intptr_t)bsize->vtoc, flag, cred, rvp);
-
- if (errno) {
- return (errno);
- }
- } else {
-#ifdef DKIOCPARTITION
- /* do we have an EFI partition table? */
- errno = (*cdi->major->ioctl)(bsize->raw_fd,
- DKIOCPARTITION, (intptr_t)bsize->p64, flag, cred, rvp);
-
- if (errno) {
- return (errno);
- }
-#endif
- }
-
- return (0);
-}
-
-
-/*
- * Private function for sv to use.
- */
-int
-nskern_partition(dev_t fd, int *partitionp)
-{
- uint64_t size;
- int cd, rc;
-
- if ((cd = __raw_get_cd(fd)) == -1 || !_nsc_raw_files[cd].in_use)
- return (EIO);
-
- if ((*partitionp = _nsc_raw_files[cd].partition) != -1) {
- return (0);
- }
-
- rc = _raw_init_dev(fd, &size, partitionp);
- if (rc != 0 || *partitionp < 0) {
- return (EIO);
- }
-
- return (0);
-}
-
-
-nsc_def_t _nsc_raw_def[] = {
- "Open", (uintptr_t)_raw_open, 0,
- "Close", (uintptr_t)_raw_close, 0,
- "Attach", (uintptr_t)_raw_attach_io, 0,
- "UserRead", (uintptr_t)_raw_uread, 0,
- "UserWrite", (uintptr_t)_raw_uwrite, 0,
- "PartSize", (uintptr_t)_raw_partsize, 0,
- "MaxFbas", (uintptr_t)_raw_maxfbas, 0,
- "Control", (uintptr_t)_raw_control, 0,
- "Provide", NSC_DEVICE, 0,
- 0, 0, 0
-};
diff --git a/usr/src/uts/common/avs/ns/solaris/nsc_solaris.c b/usr/src/uts/common/avs/ns/solaris/nsc_solaris.c
deleted file mode 100644
index e4894875a9..0000000000
--- a/usr/src/uts/common/avs/ns/solaris/nsc_solaris.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * This file contains interface code to the kernel.
- */
-
-/* LINTLIBRARY */
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/errno.h>
-#include <sys/kmem.h>
-#include <sys/ksynch.h>
-#include <sys/cmn_err.h>
-#include <sys/uio.h>
-#include <sys/conf.h>
-#include <sys/ddi.h>
-
-#include <sys/nsctl/nsctl.h>
-#include "nsc_list.h"
-
-/*
- * _nsc_init_start
- *
- * ARGUMENTS:
- *
- * RETURNS:
- *
- * USAGE:
- *
- * CALLED BY:
- */
-void
-_nsc_init_start(void)
-{
-}
-
-/*
- * _nsc_init_os -
- *
- * ARGUMENTS:
- *
- * RETURNS:
- *
- * USAGE:
- *
- * CALLED BY:
- */
-void
-_nsc_init_os(void)
-{
-}
-
-/*
- * _nsc_deinit_os -
- *
- * ARGUMENTS:
- *
- * RETURNS:
- *
- * USAGE:
- *
- * CALLED BY:
- */
-void
-_nsc_deinit_os(void)
-{
-}
-
-/* dummy routine unless RMS/MC is really running */
-void
-_nsc_self_alive()
-{
-}
-
-/*
- * Check other nodes: checks for the heart_beat of other nodes and decides
- * if a node that was up went down... or a node that was down is now
- * up. Events NODE_UP and NODE_DOWN are posted to myself (this node)
- * Any processing that happens in these event handlers SHOULD abide by
- * the health monitor rules for the health monitor to work correctly.
- * If excessive computation during these events is required, consider the
- * possibility of forking of a process OR breaking up the computation into
- * smaller parts, and making sure that we call "SELF_ALIVE()" "often".
- * This is not the suggested mechanism, but there are times when we need it.
- */
-
-void
-_nsc_check_other_nodes()
-{
-}
-
-/*
- * Is our partner active ? (Should never block)
- */
-int
-alternate_health_hbeat()
-{
- return (0);
-}
-
-
-static int
-mark_rm_pages_to_dump(addr, size, dump)
-caddr_t addr;
-int size, dump;
-{
- return (0);
-}
-
-
-void
-_nsc_mark_pages(caddr_t addr, size_t size, int dump)
-{
- if (mark_rm_pages_to_dump(addr, (int)size, dump) < 0)
- cmn_err(CE_WARN, "_nsc_mark_pages: %s failed - 0x%p size %d",
- (dump ? "mark" : "unmark"), addr, (int)size);
-}
diff --git a/usr/src/uts/common/avs/ns/solaris/nsc_thread.c b/usr/src/uts/common/avs/ns/solaris/nsc_thread.c
deleted file mode 100644
index d75cddf200..0000000000
--- a/usr/src/uts/common/avs/ns/solaris/nsc_thread.c
+++ /dev/null
@@ -1,1026 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/debug.h>
-#include <sys/ksynch.h>
-#include <sys/cmn_err.h>
-#include <sys/kmem.h>
-#include <sys/ddi.h>
-#include <sys/errno.h>
-#include "nsc_thread.h"
-
-#ifdef DS_DDICT
-#include "../contract.h"
-#endif
-
-#include "../nsctl.h"
-#include "nskernd.h"
-#include <sys/nsctl/nsctl.h>
-
-#include <sys/sdt.h> /* dtrace is S10 or later */
-
-
-/*
- * Global data
- */
-static nstset_t *nst_sets;
-static nsthread_t *nst_pending;
-static kmutex_t nst_global_lock; /* nst_sets, nst_pending */
-
-
-/*
- * nst_kmem_xalloc
- *
- * Poll for memory.
- */
-static void *
-nst_kmem_xalloc(size_t size, int sec, void *(*alloc)(size_t, int))
-{
- clock_t usec = sec * 1000000;
- void *p = NULL;
-
- while (usec > 0) {
- if ((p = (*alloc)(size, KM_NOSLEEP)) != NULL)
- return (p);
-
- delay(drv_usectohz((clock_t)NST_MEMORY_TIMEOUT));
- usec -= NST_MEMORY_TIMEOUT;
- }
-
- cmn_err(CE_WARN, "!nst_kmem_xalloc: failed to alloc %ld bytes", size);
- return (NULL);
-}
-
-
-#if 0
-/* currently unused */
-static void *
-nst_kmem_alloc(size_t size, int sec)
-{
- return (nst_kmem_xalloc(size, sec, kmem_alloc));
-}
-#endif
-
-
-static void *
-nst_kmem_zalloc(size_t size, int sec)
-{
- return (nst_kmem_xalloc(size, sec, kmem_zalloc));
-}
-
-
-/*
- * Queue stuff that should be in the DDI.
- */
-
-/*
- * nst_insque
- *
- * Insert entryp after predp in a doubly linked list.
- */
-static void
-nst_insque(nst_q_t *entryp, nst_q_t *predp)
-{
- entryp->q_back = predp;
- entryp->q_forw = predp->q_forw;
- predp->q_forw = entryp;
- entryp->q_forw->q_back = entryp;
-}
-#ifndef DS_DDICT
-#pragma inline(nst_insque) /* compiler hint to inline this function */
-#endif
-
-
-/*
- * nst_remque
- *
- * Remove entryp from a doubly linked list.
- */
-static void
-nst_remque(nst_q_t *entryp)
-{
- entryp->q_back->q_forw = entryp->q_forw;
- entryp->q_forw->q_back = entryp->q_back;
- entryp->q_forw = entryp->q_back = NULL;
-}
-#ifndef DS_DDICT
-#pragma inline(nst_remque) /* compiler hint to inline this function */
-#endif
-
-
-/*
- * nst_thread_init
- *
- * Initialise the dynamic part of a thread
- */
-static void
-nst_thread_init(nsthread_t *tp)
-{
- ASSERT(MUTEX_HELD(&((tp->tp_set)->set_lock)));
- ASSERT(!(tp->tp_flag & NST_TF_INUSE));
- tp->tp_flag = NST_TF_INUSE;
- tp->tp_func = NULL;
- tp->tp_arg = NULL;
-}
-#ifndef DS_DDICT
-#pragma inline(nst_thread_init) /* compiler hint to inline this function */
-#endif
-
-
-/*
- * nst_thread_alloc
- *
- * Return an nsthread from the free pool, NULL if none
- */
-static nsthread_t *
-nst_thread_alloc(nstset_t *set, const int sleep)
-{
- nsthread_t *tp = NULL;
-
- mutex_enter(&set->set_lock);
-
- if (set->set_flag & NST_SF_KILL) {
- mutex_exit(&set->set_lock);
- DTRACE_PROBE1(nst_thread_alloc_err_kill, nstset_t *, set);
- return (NULL);
- }
-
- do {
- tp = (nsthread_t *)set->set_free.q_forw;
- if (tp != (nsthread_t *)&set->set_free)
- nst_remque(&tp->tp_link);
- else {
- tp = NULL;
-
- if (!sleep)
- break;
-
- set->set_res_cnt++;
-
- DTRACE_PROBE2(nst_thread_alloc_sleep, nstset_t *, set,
- int, set->set_res_cnt);
-
- cv_wait(&set->set_res_cv, &set->set_lock);
-
- DTRACE_PROBE1(nst_thread_alloc_wake, nstset_t *, set);
-
- set->set_res_cnt--;
-
- if (set->set_flag & NST_SF_KILL)
- break;
- }
- } while (tp == NULL);
-
- /* initialise the thread */
-
- if (tp != NULL) {
- nst_thread_init(tp);
- set->set_nlive++;
- }
-
- mutex_exit(&set->set_lock);
-
- return (tp);
-}
-
-
-/*
- * nst_thread_free
- *
- * Requeue a thread on the free or reuse pools. Threads are always
- * queued to the tail of the list to prevent rapid recycling.
- *
- * Must be called with set->set_lock held.
- */
-static void
-nst_thread_free(nsthread_t *tp)
-{
- nstset_t *set = tp->tp_set;
-
- if (!set)
- return;
-
- ASSERT(MUTEX_HELD(&set->set_lock));
-
- tp->tp_flag &= ~NST_TF_INUSE;
- if (tp->tp_flag & NST_TF_DESTROY) {
- /* add self to reuse pool */
- nst_insque(&tp->tp_link, set->set_reuse.q_back);
- } else {
- /* add self to free pool */
- nst_insque(&tp->tp_link, set->set_free.q_back);
- if (set->set_res_cnt > 0)
- cv_broadcast(&set->set_res_cv);
- }
-}
-
-
-/*
- * nst_thread_run
- *
- * The first function that a new thread runs on entry from user land.
- * This is the main thread function that handles thread work and death.
- */
-static void
-nst_thread_run(void *arg)
-{
- nsthread_t *tp;
- nstset_t *set;
- int first = 1;
-
- mutex_enter(&nst_global_lock);
-
- /* check if this thread is still on the pending list */
-
- for (tp = nst_pending; tp; tp = tp->tp_chain) {
- if (tp == (nsthread_t *)arg) {
- break;
- }
- }
-
- if (!tp) {
- mutex_exit(&nst_global_lock);
- return;
- }
-
- if (!tp->tp_set) {
- mutex_exit(&nst_global_lock);
-#ifdef DEBUG
- cmn_err(CE_WARN, "!nst_thread_run(%p): already dead?",
- (void *)tp);
-#endif
- return;
- }
-
- /* check that the set is still on the list of sets */
-
- for (set = nst_sets; set; set = set->set_next) {
- if (set == tp->tp_set) {
- break;
- }
- }
-
- if (!set) {
- mutex_exit(&nst_global_lock);
-#ifdef DEBUG
- cmn_err(CE_WARN, "!nst_thread_run(%p): no set?", (void *)tp);
-#endif
- return;
- }
-
- mutex_enter(&set->set_lock);
-
- mutex_exit(&nst_global_lock);
-
- /*
- * Mark the parent.
- * The parent won't actually run until set->set_lock is dropped.
- */
-
- tp->tp_flag &= ~NST_TF_PENDING;
- cv_broadcast(&tp->tp_cv);
-
- /*
- * Main loop.
- */
-
- while (!(set->set_flag & NST_SF_KILL) &&
- !(tp->tp_flag & NST_TF_KILL)) {
- /*
- * On initial entry the caller will add this thread to
- * the free pool if required, there after the thread
- * must do it for itself.
- */
-
- if (first) {
- first = 0;
- } else {
- nst_thread_free(tp);
- set->set_nlive--;
- }
-
- DTRACE_PROBE1(nst_thread_run_sleep, nsthread_t *, tp);
-
- cv_wait(&tp->tp_cv, &set->set_lock);
-
- DTRACE_PROBE1(nst_thread_run_wake, nsthread_t *, tp);
-
- if ((set->set_flag & NST_SF_KILL) ||
- (tp->tp_flag & NST_TF_KILL)) {
- break;
- }
-
- mutex_exit(&set->set_lock);
-
- if (tp->tp_func) {
- (*tp->tp_func)(tp->tp_arg);
- tp->tp_func = 0;
- tp->tp_arg = 0;
- }
-#ifdef DEBUG
- else {
- cmn_err(CE_WARN,
- "!nst_thread_run(%p): NULL function pointer",
- (void *)tp);
- }
-#endif
-
- mutex_enter(&set->set_lock);
- }
-
- /* remove self from the free and/or reuse pools */
- if (tp->tp_link.q_forw != NULL || tp->tp_link.q_back != NULL) {
- ASSERT(tp->tp_link.q_forw != NULL &&
- tp->tp_link.q_back != NULL);
- nst_remque(&tp->tp_link);
- }
-
- set->set_nthread--;
- tp->tp_flag &= ~NST_TF_KILL;
-
- /* wake the context that is running nst_destroy() or nst_del_thread() */
- cv_broadcast(&set->set_kill_cv);
-
- mutex_exit(&set->set_lock);
-
- /* suicide */
-}
-
-
-/*
- * nst_thread_destroy
- *
- * Free up the kernel level resources. The thread must already be
- * un-chained from the set, and the caller must not be the thread
- * itself.
- */
-static void
-nst_thread_destroy(nsthread_t *tp)
-{
- if (!tp)
- return;
-
- ASSERT(tp->tp_chain == NULL);
-
- tp->tp_set = NULL;
-
- if (tp->tp_flag & NST_TF_INUSE) {
- cmn_err(CE_WARN, "!nst_thread_destroy(%p): still in use!",
- (void *)tp);
- /* leak the thread */
- return;
- }
-
- cv_destroy(&tp->tp_cv);
- kmem_free(tp, sizeof (*tp));
-}
-
-
-/*
- * nst_thread_create
- *
- * Create and return a new thread from a threadset.
- */
-static nsthread_t *
-nst_thread_create(nstset_t *set)
-{
- nsthread_t *tp, **tpp;
- int rc;
-
- /* try and reuse a thread first */
-
- if (set->set_reuse.q_forw != &set->set_reuse) {
- mutex_enter(&set->set_lock);
-
- tp = (nsthread_t *)set->set_reuse.q_forw;
- if (tp != (nsthread_t *)&set->set_reuse)
- nst_remque(&tp->tp_link);
- else
- tp = NULL;
-
- mutex_exit(&set->set_lock);
-
- if (tp) {
- DTRACE_PROBE2(nst_thread_create_end, nstset_t *, set,
- nsthread_t *, tp);
- return (tp);
- }
- }
-
- /* create a thread using nskernd */
-
- tp = nst_kmem_zalloc(sizeof (*tp), 2);
- if (!tp) {
- DTRACE_PROBE1(nst_thread_create_err_mem, nstset_t *, set);
- return (NULL);
- }
-
- cv_init(&tp->tp_cv, NULL, CV_DRIVER, NULL);
- tp->tp_flag = NST_TF_PENDING;
- tp->tp_set = set;
-
- mutex_enter(&set->set_lock);
-
- if (set->set_flag & NST_SF_KILL) {
- mutex_exit(&set->set_lock);
- nst_thread_destroy(tp);
-#ifdef DEBUG
- cmn_err(CE_WARN, "!nst_thread_create: called during destroy");
-#endif
- DTRACE_PROBE2(nst_thread_create_err_kill, nstset_t *, set,
- nsthread_t *, tp);
- return (NULL);
- }
-
- set->set_pending++;
-
- mutex_exit(&set->set_lock);
-
- mutex_enter(&nst_global_lock);
-
- tp->tp_chain = nst_pending;
- nst_pending = tp;
-
- mutex_exit(&nst_global_lock);
-
- DTRACE_PROBE2(nst_dbg_thr_create_proc_start, nstset_t *, set,
- nsthread_t *, tp);
-
- rc = nsc_create_process(nst_thread_run, tp, 0);
-
- DTRACE_PROBE2(nst_dbg_thr_create_proc_end, nstset_t *, set,
- nsthread_t *, tp);
-
- if (!rc) {
- /*
- * wait for child to start and check in.
- */
-
- mutex_enter(&set->set_lock);
-
- while (tp->tp_flag & NST_TF_PENDING)
- cv_wait(&tp->tp_cv, &set->set_lock);
-
- mutex_exit(&set->set_lock);
- }
-
- /*
- * remove from pending chain.
- */
-
- mutex_enter(&nst_global_lock);
-
- for (tpp = &nst_pending; (*tpp); tpp = &((*tpp)->tp_chain)) {
- if (*tpp == tp) {
- *tpp = tp->tp_chain;
- tp->tp_chain = NULL;
- break;
- }
- }
-
- mutex_exit(&nst_global_lock);
-
- /*
- * Check for errors and return if required.
- */
-
- mutex_enter(&set->set_lock);
-
- set->set_pending--;
-
- if (rc ||
- (set->set_flag & NST_SF_KILL) ||
- (set->set_nthread + 1) > USHRT_MAX) {
- if (rc == 0) {
- /*
- * Thread is alive, and needs to be woken and killed.
- */
- tp->tp_flag |= NST_TF_KILL;
- cv_broadcast(&tp->tp_cv);
-
- while (tp->tp_flag & NST_TF_KILL)
- cv_wait(&set->set_kill_cv, &set->set_lock);
- }
- mutex_exit(&set->set_lock);
-
- nst_thread_destroy(tp);
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!nst_thread_create: error (rc %d, set_flag %x, "
- "set_nthread %d)", rc, set->set_flag, set->set_nthread);
-#endif
- DTRACE_PROBE2(nst_thread_create_err_proc, nstset_t *, set,
- nsthread_t *, tp);
-
- return (NULL);
- }
-
- /*
- * Move into set proper.
- */
-
- tp->tp_chain = set->set_chain;
- set->set_chain = tp;
- set->set_nthread++;
-
- mutex_exit(&set->set_lock);
-
- return (tp);
-}
-
-
-/*
- * nst_create
- *
- * Start a new thread from a thread set, returning the
- * address of the thread, or NULL on failure.
- *
- * All threads are created detached.
- *
- * Valid flag values:
- *
- * NST_CREATE - create a new thread rather than using one
- * from the threadset. Once the thread
- * completes it will not be added to the active
- * portion of the threadset, but will be cached
- * on the reuse chain, and so is available for
- * subsequent NST_CREATE or nst_add_thread()
- * operations.
- *
- * NST_SLEEP - wait for a thread to be available instead of
- * returning NULL. Has no meaning with NST_CREATE.
- *
- * Returns a pointer to the new thread, or NULL.
- */
-nsthread_t *
-nst_create(nstset_t *set, void (*func)(), blind_t arg, int flags)
-{
- nsthread_t *tp = NULL;
-
- if (!set)
- return (NULL);
-
- if (set->set_flag & NST_SF_KILL) {
- DTRACE_PROBE1(nst_create_err_kill, nstset_t *, set);
- return (NULL);
- }
-
- if (flags & NST_CREATE) {
- /* get new thread */
-
- if ((tp = nst_thread_create(set)) == NULL)
- return (NULL);
-
- /* initialise the thread */
-
- mutex_enter(&set->set_lock);
- nst_thread_init(tp);
- tp->tp_flag |= NST_TF_DESTROY;
- set->set_nlive++;
- mutex_exit(&set->set_lock);
- } else {
- if (!(tp = nst_thread_alloc(set, (flags & NST_SLEEP))))
- return (NULL);
- }
-
- /* set thread running */
-
- tp->tp_func = func;
- tp->tp_arg = arg;
-
- mutex_enter(&set->set_lock);
- cv_broadcast(&tp->tp_cv);
- mutex_exit(&set->set_lock);
-
- return (tp);
-}
-
-
-/*
- * nst_destroy
- *
- * Destroy a thread set created by nst_init(). It is the
- * caller's responsibility to ensure that all prior thread
- * calls have completed prior to this call and that the
- * caller is not executing from within thread context.
- */
-void
-nst_destroy(nstset_t *set)
-{
- nsthread_t *tp, *ntp;
- nstset_t *sp, **spp;
-
- if (!set)
- return;
-
- mutex_enter(&nst_global_lock);
-
- for (sp = nst_sets; sp; sp = sp->set_next) {
- if (sp == set) {
- break;
- }
- }
-
- if (!sp) {
- mutex_exit(&nst_global_lock);
-#ifdef DEBUG
- cmn_err(CE_WARN, "!nst_destroy(%p): no set?", (void *)set);
-#endif
- DTRACE_PROBE1(nst_destroy_err_noset, nstset_t *, set);
- return;
- }
-
- mutex_enter(&set->set_lock);
-
- mutex_exit(&nst_global_lock);
-
- if (set->set_flag & NST_SF_KILL) {
- /*
- * Wait for a pending destroy to complete
- */
-
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!nst_destroy(%p): duplicate destroy of set", (void *)set);
-#endif
-
- set->set_destroy_cnt++;
- (void) cv_wait_sig(&set->set_destroy_cv, &set->set_lock);
- set->set_destroy_cnt--;
-
- mutex_exit(&set->set_lock);
-
- DTRACE_PROBE1(nst_destroy_end, nstset_t *, set);
-
- return;
- }
-
- set->set_flag |= NST_SF_KILL;
-
- /* Wake all threads in nst_create(NST_SLEEP) */
- cv_broadcast(&set->set_res_cv);
-
- /*
- * Wake all the threads chained in the set.
- */
-
- for (tp = set->set_chain; tp; tp = tp->tp_chain)
- cv_broadcast(&tp->tp_cv);
-
- /* Wait for the threads to exit */
-
- while ((set->set_free.q_forw != &set->set_free) ||
- (set->set_reuse.q_forw != &set->set_reuse))
- cv_wait(&set->set_kill_cv, &set->set_lock);
-
- /* Unchain and destroy all the threads in the set */
-
- tp = set->set_chain;
- set->set_chain = 0;
-
- while (tp) {
- ntp = tp->tp_chain;
- tp->tp_chain = 0;
-
- nst_thread_destroy(tp);
-
- tp = ntp;
- }
-
- mutex_exit(&set->set_lock);
-
- mutex_enter(&nst_global_lock);
-
- /* remove the set from the chain */
-
- for (spp = &nst_sets; *spp; spp = &((*spp)->set_next)) {
- if (*spp == set) {
- *spp = set->set_next;
- set->set_next = NULL;
- break;
- }
- }
-
- mutex_exit(&nst_global_lock);
-
- mutex_enter(&set->set_lock);
-
-#ifdef DEBUG
- if (set->set_nthread != 0) {
- cmn_err(CE_WARN, "!nst_destroy(%p): nthread != 0 (%d)",
- (void *)set, set->set_nthread);
- }
-#endif
-
- /* Allow any waiters (above) to continue */
-
- cv_broadcast(&set->set_destroy_cv);
-
- while (set->set_destroy_cnt > 0 || set->set_pending > 0 ||
- set->set_res_cnt > 0) {
- mutex_exit(&set->set_lock);
- delay(drv_usectohz((clock_t)NST_KILL_TIMEOUT));
- mutex_enter(&set->set_lock);
- }
-
- mutex_exit(&set->set_lock);
-
- if (set->set_nthread != 0) {
- /* leak the set control structure */
-
- DTRACE_PROBE1(nst_destroy_end, nstset_t *, set);
-
- return;
- }
-
- cv_destroy(&set->set_res_cv);
- cv_destroy(&set->set_kill_cv);
- cv_destroy(&set->set_destroy_cv);
- mutex_destroy(&set->set_lock);
- kmem_free(set, sizeof (*set));
-
-}
-
-
-/*
- * nst_add_thread
- *
- * Add more threads into an existing thread set.
- * Returns the number successfully added.
- */
-int
-nst_add_thread(nstset_t *set, int nthread)
-{
- nsthread_t *tp;
- int i;
-
- if (!set || nthread < 1) {
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!nst_add_thread(%p, %d) - bad args", (void *)set, nthread);
-#endif
- return (0);
- }
-
- for (i = 0; i < nthread; i++) {
- /* get new thread */
-
- if ((tp = nst_thread_create(set)) == NULL)
- break;
-
- /* add to free list */
-
- mutex_enter(&set->set_lock);
- nst_thread_free(tp);
- mutex_exit(&set->set_lock);
- }
-
- return (i);
-}
-
-
-/*
- * nst_del_thread
- *
- * Removes threads from an existing thread set.
- * Returns the number successfully removed.
- */
-int
-nst_del_thread(nstset_t *set, int nthread)
-{
- nsthread_t **tpp, *tp;
- int i;
-
- if (!set || nthread < 1) {
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!nst_del_thread(%p, %d) - bad args", (void *)set, nthread);
-#endif
- return (0);
- }
-
- for (i = 0; i < nthread; i++) {
- /* get thread */
-
- if (!(tp = nst_thread_alloc(set, FALSE)))
- break;
-
- mutex_enter(&set->set_lock);
-
- /* unlink from the set */
-
- for (tpp = &set->set_chain; *tpp; tpp = &(*tpp)->tp_chain) {
- if (*tpp == tp) {
- *tpp = tp->tp_chain;
- tp->tp_chain = NULL;
- break;
- }
- }
-
- /* kill the thread */
-
- tp->tp_flag |= NST_TF_KILL;
- tp->tp_flag &= ~NST_TF_INUSE;
- cv_broadcast(&tp->tp_cv);
-
- /* wait for thread to exit */
-
- while (tp->tp_flag & NST_TF_KILL)
- cv_wait(&set->set_kill_cv, &set->set_lock);
-
- set->set_nlive--;
- mutex_exit(&set->set_lock);
-
- /* free kernel resources */
-
- nst_thread_destroy(tp);
- }
-
- return (i);
-}
-
-
-/*
- * nst_init
- *
- * Initialise a new nsthread set, returning its address or
- * NULL in the event of failure. The set should be destroyed
- * by calling nst_destroy().
- */
-nstset_t *
-nst_init(char *name, int nthread)
-{
- nstset_t *set, *sp;
- int len, i;
-
- if (nthread < 1) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!nst_init: invalid arg");
-#endif
- return (NULL);
- }
-
- if (nthread > USHRT_MAX) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "!nst_init: arg limit exceeded");
-#endif
- return (NULL);
- }
-
- if (!(set = nst_kmem_zalloc(sizeof (*set), 2)))
- return (NULL);
-
- len = strlen(name);
- if (len >= sizeof (set->set_name))
- len = sizeof (set->set_name) - 1;
-
- bcopy(name, set->set_name, len);
-
- mutex_init(&set->set_lock, NULL, MUTEX_DRIVER, NULL);
- cv_init(&set->set_destroy_cv, NULL, CV_DRIVER, NULL);
- cv_init(&set->set_kill_cv, NULL, CV_DRIVER, NULL);
- cv_init(&set->set_res_cv, NULL, CV_DRIVER, NULL);
-
- set->set_reuse.q_forw = set->set_reuse.q_back = &set->set_reuse;
- set->set_free.q_forw = set->set_free.q_back = &set->set_free;
-
- mutex_enter(&nst_global_lock);
-
- /* check for duplicates */
-
- for (sp = nst_sets; sp; sp = sp->set_next) {
- if (strcmp(sp->set_name, set->set_name) == 0) {
- /* duplicate */
- mutex_exit(&nst_global_lock);
- cv_destroy(&set->set_res_cv);
- cv_destroy(&set->set_kill_cv);
- cv_destroy(&set->set_destroy_cv);
- mutex_destroy(&set->set_lock);
- kmem_free(set, sizeof (*set));
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!nst_init: duplicate set \"%s\"", name);
-#endif
- /* add threads if necessary */
-
- if (nthread > sp->set_nthread) {
- i = nst_add_thread(sp,
- nthread - sp->set_nthread);
-#ifdef DEBUG
- if (i != (nthread - sp->set_nthread))
- cmn_err(CE_WARN,
- "!nst_init: failed to allocate %d "
- "threads (got %d)",
- (nthread - sp->set_nthread), i);
-#endif
- }
-
- /* return pointer to existing set */
-
- return (sp);
- }
- }
-
- /* add new set to chain */
- set->set_next = nst_sets;
- nst_sets = set;
-
- mutex_exit(&nst_global_lock);
-
- i = nst_add_thread(set, nthread);
-
- if (i != nthread) {
-#ifdef DEBUG
- cmn_err(CE_WARN,
- "!nst_init: failed to allocate %d threads (got %d)",
- nthread, i);
-#endif
- nst_destroy(set);
- return (NULL);
- }
-
- return (set);
-}
-
-
-/*
- * nst_nlive
- *
- * Return the number of live threads in a set.
- */
-int
-nst_nlive(nstset_t *set)
-{
- return (set ? set->set_nlive : 0);
-}
-
-
-/*
- * nst_nthread
- *
- * Return the number of threads in the set.
- */
-int
-nst_nthread(nstset_t *set)
-{
- return (set ? set->set_nthread : 0);
-}
-
-
-/*
- * nst_shutdown
- *
- * Called by nskern to shutdown the nsthread software.
- */
-void
-nst_shutdown(void)
-{
- nstset_t *set;
-
- mutex_enter(&nst_global_lock);
-
- while ((set = nst_sets) != NULL) {
- mutex_exit(&nst_global_lock);
- nst_destroy(set);
- mutex_enter(&nst_global_lock);
- }
-
- mutex_exit(&nst_global_lock);
- mutex_destroy(&nst_global_lock);
-}
-
-
-/*
- * nst_startup
- *
- * Called by nskern to initialise the nsthread software
- */
-int
-nst_startup(void)
-{
- mutex_init(&nst_global_lock, NULL, MUTEX_DRIVER, NULL);
- return (0);
-}
diff --git a/usr/src/uts/common/avs/ns/solaris/nsc_thread.h b/usr/src/uts/common/avs/ns/solaris/nsc_thread.h
deleted file mode 100644
index d41901820e..0000000000
--- a/usr/src/uts/common/avs/ns/solaris/nsc_thread.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _NSC_THREAD_H
-#define _NSC_THREAD_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef _KERNEL
-
-#include <sys/ksynch.h> /* for kmutex_t and kcondvar_t */
-
-/*
- * A simple way to marshal kthreads into sets for use by nsctl / nskern
- * clients. The ns threads are created in user land by nskernd, and
- * then call into the nskern kernel module for allocation into sets.
- */
-
-struct nsthread;
-struct nstset;
-
-#ifndef _BLIND_T
-#define _BLIND_T
-typedef void * blind_t;
-#endif /* _BLIND_T */
-
-
-/*
- * Queue stuff that should really be in the DDI.
- */
-
-typedef struct nst_q {
- struct nst_q *q_forw;
- struct nst_q *q_back;
-} nst_q_t;
-
-
-/*
- * Per thread data structure.
- */
-
-typedef struct nsthread {
- nst_q_t tp_link; /* Doubly linked free list */
-
- struct nstset *tp_set; /* Set to which thread belongs */
- struct nsthread *tp_chain; /* Link in chain of threads in set */
-
- kcondvar_t tp_cv; /* Suspend/resume synchronisation */
-
- /*
- * Everything past this point is cleared when the thread is
- * initialised for (re)use.
- */
-
- int tp_flag; /* State (below) */
-
- void (*tp_func)(); /* First function */
- blind_t tp_arg; /* Argument to tp_func */
-} nsthread_t;
-
-/*
- * Flags for nst_init
- */
-#define NST_CREATE 0x1 /* Create resources to run thread */
-#define NST_SLEEP 0x2 /* Wait for resources to be available */
-
-/*
- * Thread state flags
- */
-#define NST_TF_INUSE 0x1 /* Thread currently in use */
-#define NST_TF_ACTIVE 0x2 /* Thread is being manipulated */
-#define NST_TF_PENDING 0x4 /* Thread is pending a create */
-#define NST_TF_DESTROY 0x8 /* Destroy thread when finished */
-#define NST_TF_KILL 0x10 /* Thread is being killed */
-
-/*
- * Thread set.
- */
-typedef struct nstset {
- struct nstset *set_next; /* Next set in list of sets */
-
- nsthread_t *set_chain; /* Chain of all threads in set */
- nst_q_t set_reuse; /* Chain of reusable threads */
- nst_q_t set_free; /* Chain of free threads */
-
- char set_name[32]; /* Name associated with set */
-
- ushort_t set_nlive; /* No. of active threads */
- ushort_t set_nthread; /* No. of threads in set */
- int set_flag; /* State (below) */
- int set_pending; /* Operation is pending */
-
- kmutex_t set_lock; /* Mutex for chains and counts */
- kcondvar_t set_kill_cv; /* Kill synchronisation */
- kcondvar_t set_destroy_cv; /* Shutdown synchronisation */
- volatile int set_destroy_cnt; /* No. of waiters */
-
- kcondvar_t set_res_cv; /* Resource alloc synchronisation */
- int set_res_cnt; /* No. of waiters */
-} nstset_t;
-
-/*
- * Set state flags
- */
-#define NST_SF_KILL 1 /* Set is being killed */
-
-/*
- * General defines
- */
-#define NST_KILL_TIMEOUT 100000 /* usec to wait for threads to die */
-#define NST_MEMORY_TIMEOUT 500000 /* usec to wait for memory */
-
-/*
- * Function prototypes
- */
-
-int nst_add_thread(nstset_t *, int);
-nsthread_t *nst_create(nstset_t *, void (*)(), blind_t, int);
-int nst_del_thread(nstset_t *, int);
-void nst_destroy(nstset_t *);
-nstset_t *nst_init(char *, int);
-int nst_nlive(nstset_t *);
-int nst_nthread(nstset_t *);
-int nst_startup(void);
-void nst_shutdown(void);
-
-#endif /* _KERNEL */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _NSC_THREAD_H */
diff --git a/usr/src/uts/common/avs/ns/solaris/nskern.conf b/usr/src/uts/common/avs/ns/solaris/nskern.conf
deleted file mode 100644
index 1d5288f858..0000000000
--- a/usr/src/uts/common/avs/ns/solaris/nskern.conf
+++ /dev/null
@@ -1,24 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-name="nskern" parent="pseudo" instance=0;
diff --git a/usr/src/uts/common/avs/ns/solaris/nskernd.c b/usr/src/uts/common/avs/ns/solaris/nskernd.c
deleted file mode 100644
index e050bc917f..0000000000
--- a/usr/src/uts/common/avs/ns/solaris/nskernd.c
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/ksynch.h>
-#include <sys/errno.h>
-#include <sys/ddi.h>
-#include <sys/sunddi.h>
-
-#include "../nsctl.h"
-#include "../nsctl/nsc_ioctl.h"
-#include "nskernd.h"
-
-void *proc_nskernd;
-int nskernd_iscluster;
-
-static kmutex_t nskernd_lock;
-
-static kcondvar_t nskernd_ask_cv;
-static kcondvar_t nskernd_k_cv;
-static kcondvar_t nskernd_u_cv;
-
-static volatile int nskernd_k_wait;
-static volatile int nskernd_u_wait;
-
-static int nskernd_norun;
-
-static volatile int nskernd_ask;
-static struct nskernd nskernd_kdata;
-
-void
-nskernd_init(void)
-{
- mutex_init(&nskernd_lock, NULL, MUTEX_DRIVER, NULL);
- cv_init(&nskernd_ask_cv, NULL, CV_DRIVER, NULL);
- cv_init(&nskernd_k_cv, NULL, CV_DRIVER, NULL);
- cv_init(&nskernd_u_cv, NULL, CV_DRIVER, NULL);
-
- nskernd_norun = 0;
-}
-
-
-void
-nskernd_deinit(void)
-{
- mutex_destroy(&nskernd_lock);
- cv_destroy(&nskernd_ask_cv);
- cv_destroy(&nskernd_k_cv);
- cv_destroy(&nskernd_u_cv);
-}
-
-
-static int
-nskernd_start(const int iscluster)
-{
- int rc = 0;
-
- mutex_enter(&nskernd_lock);
-
- if (proc_nskernd != NULL) {
- rc = 1;
- } else if (nskernd_norun != 0) {
- rc = 2;
- } else {
- (void) drv_getparm(UPROCP, (void *)&proc_nskernd);
- nskernd_iscluster = iscluster;
- }
-
- mutex_exit(&nskernd_lock);
-
- return (rc);
-}
-
-
-/*
- * must be called with nskernd_lock held.
- */
-void
-nskernd_cleanup(void)
-{
- proc_nskernd = NULL;
- cv_broadcast(&nskernd_ask_cv);
- cv_broadcast(&nskernd_k_cv);
-}
-
-
-void
-nskernd_stop(void)
-{
- mutex_enter(&nskernd_lock);
-
- if (proc_nskernd == NULL) {
- nskernd_norun = 1;
- mutex_exit(&nskernd_lock);
- return;
- }
-
- while (nskernd_u_wait == 0) {
- nskernd_k_wait++;
- cv_wait(&nskernd_k_cv, &nskernd_lock);
- nskernd_k_wait--;
-
- if (proc_nskernd == NULL) {
- mutex_exit(&nskernd_lock);
- return;
- }
- }
-
- nskernd_kdata.command = NSKERND_STOP;
- nskernd_kdata.data1 = (uint64_t)1; /* kernel has done cleanup */
-
- nskernd_cleanup();
-
- cv_signal(&nskernd_u_cv);
- mutex_exit(&nskernd_lock);
-}
-
-
-int
-nskernd_get(struct nskernd *nskp)
-{
- mutex_enter(&nskernd_lock);
-
- if (proc_nskernd == NULL) {
- mutex_exit(&nskernd_lock);
- return (ENXIO);
- }
-
- while (nskernd_u_wait == 0 || nskernd_ask) {
- nskernd_k_wait++;
- cv_wait(&nskernd_k_cv, &nskernd_lock);
- nskernd_k_wait--;
-
- if (proc_nskernd == NULL) {
- mutex_exit(&nskernd_lock);
- return (ENXIO);
- }
- }
-
- bcopy(nskp, &nskernd_kdata, sizeof (*nskp));
- nskernd_ask++;
-
- cv_signal(&nskernd_u_cv);
-
- cv_wait(&nskernd_ask_cv, &nskernd_lock);
-
- if (proc_nskernd == NULL) {
- nskernd_ask--;
- mutex_exit(&nskernd_lock);
- return (ENXIO);
- }
-
- bcopy(&nskernd_kdata, nskp, sizeof (*nskp));
- nskernd_ask--;
-
- if (nskernd_k_wait > 0)
- cv_signal(&nskernd_k_cv);
-
- mutex_exit(&nskernd_lock);
- return (0);
-}
-
-
-int
-nskernd_command(intptr_t arg, int mode, int *rvalp)
-{
- struct nskernd *udata = NULL;
- uint64_t arg1, arg2;
- int rc;
-
- *rvalp = 0;
- rc = 0;
-
- udata = kmem_alloc(sizeof (*udata), KM_SLEEP);
- if (ddi_copyin((void *)arg, udata, sizeof (*udata), mode) < 0) {
- kmem_free(udata, sizeof (*udata));
- return (EFAULT);
- }
-
- switch (udata->command) {
- case NSKERND_START: /* User program start */
- *rvalp = nskernd_start(udata->data1);
- break;
-
- case NSKERND_STOP: /* User program requesting stop */
- mutex_enter(&nskernd_lock);
- nskernd_cleanup();
- mutex_exit(&nskernd_lock);
- break;
-
- case NSKERND_WAIT:
- mutex_enter(&nskernd_lock);
-
- bcopy(udata, &nskernd_kdata, sizeof (*udata));
-
- if (nskernd_ask > 0)
- cv_signal(&nskernd_ask_cv);
-
- nskernd_u_wait++;
-
- if (cv_wait_sig(&nskernd_u_cv, &nskernd_lock) != 0) {
- /*
- * woken by cv_signal() or cv_broadcast()
- */
- bcopy(&nskernd_kdata, udata, sizeof (*udata));
- } else {
- /*
- * signal - the user process has blocked all
- * signals except for SIGTERM and the
- * uncatchables, so the process is about to die
- * and we need to clean up.
- */
- udata->command = NSKERND_STOP;
- udata->data1 = (uint64_t)1; /* cleanup done */
-
- nskernd_cleanup();
- }
-
- nskernd_u_wait--;
-
- mutex_exit(&nskernd_lock);
-
- if (ddi_copyout(udata, (void *)arg,
- sizeof (*udata), mode) < 0) {
- rc = EFAULT;
- break;
- }
-
- break;
-
- case NSKERND_NEWLWP:
- /* save kmem by freeing the udata structure */
- arg1 = udata->data1;
- kmem_free(udata, sizeof (*udata));
- udata = NULL;
- nsc_runlwp(arg1);
- break;
-
- case NSKERND_LOCK:
- /* save kmem by freeing the udata structure */
- arg1 = udata->data1;
- arg2 = udata->data2;
- kmem_free(udata, sizeof (*udata));
- udata = NULL;
- nsc_lockchild(arg1, arg2);
- break;
-
- default:
- cmn_err(CE_WARN, "nskernd: unknown command %d", udata->command);
- rc = EINVAL;
- break;
- }
-
- if (udata != NULL) {
- kmem_free(udata, sizeof (*udata));
- udata = NULL;
- }
-
- return (rc);
-}
-
-/*
- * This function is included for SV ioctl processing only.
- */
-
-int
-nskernd_isdaemon(void)
-{
- void *this_proc;
-
- if (proc_nskernd == NULL)
- return (0);
- if (drv_getparm(UPROCP, (void *)&this_proc) != 0)
- return (0);
- return (proc_nskernd == this_proc);
-}
diff --git a/usr/src/uts/common/avs/ns/solaris/nskernd.h b/usr/src/uts/common/avs/ns/solaris/nskernd.h
deleted file mode 100644
index 7cd2bb4085..0000000000
--- a/usr/src/uts/common/avs/ns/solaris/nskernd.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _NSKERND_H
-#define _NSKERND_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/nsctl/nsc_ioctl.h> /* for struct nskernd */
-
-enum {
- NSKERND_START, /* Start of daemon processing */
- NSKERND_STOP, /* Stop daemon */
- NSKERND_WAIT, /* Wait for next command */
- NSKERND_BSIZE, /* Get size in blocks of device */
- NSKERND_NEWLWP, /* Create a new lwp */
- NSKERND_LOCK, /* Obtain an inter-node lock */
- NSKERND_IIBITMAP /* mark an II bitmap as failed */
-};
-
-/*
- * The following #define is used by the ii kernel to write any
- * flags information into the dscfg file when the bitmap volume
- * fails.
- */
-#define NSKERN_II_BMP_OPTION "flags"
-
-#ifdef _KERNEL
-
-extern void *proc_nskernd;
-extern int nskernd_iscluster;
-
-extern void nskernd_init(void);
-extern void nskernd_deinit(void);
-extern void nskernd_stop(void);
-extern int nskernd_get(struct nskernd *);
-
-extern void nsc_lockchild(uint64_t, uint64_t);
-extern void nsc_runlwp(uint64_t);
-
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _NSKERND_H */
diff --git a/usr/src/uts/common/avs/ns/sv/Makefile b/usr/src/uts/common/avs/ns/sv/Makefile
deleted file mode 100644
index 7da8b58703..0000000000
--- a/usr/src/uts/common/avs/ns/sv/Makefile
+++ /dev/null
@@ -1,50 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# include global definitions
-include ../../../../../Makefile.master
-
-HDRS= sv.h \
- sv_efi.h \
- sv_impl.h
-
-ROOTDIRS= $(ROOT)/usr/include/sys/nsctl
-
-ROOTHDRS= $(HDRS:%=$(ROOTDIRS)/%)
-
-CHECKHDRS= $(HDRS:%.h=%.check)
-
-# install rule
-$(ROOTDIRS)/%: %
- $(INS.file)
-
-.KEEP_STATE:
-
-.PARALLEL: $(CHECKHDRS)
-
-install_h: $(ROOTDIRS) $(ROOTHDRS)
-
-$(ROOTDIRS):
- $(INS.dir)
-
-check: $(CHECKHDRS)
diff --git a/usr/src/uts/common/avs/ns/sv/sv.c b/usr/src/uts/common/avs/ns/sv/sv.c
deleted file mode 100644
index 8ea464cb48..0000000000
--- a/usr/src/uts/common/avs/ns/sv/sv.c
+++ /dev/null
@@ -1,2816 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
- */
-
-/*
- * Storage Volume Character and Block Driver (SV)
- *
- * This driver implements a simplistic /dev/{r}dsk/ interface to a
- * specified disk volume that is otherwise managed by the Prism
- * software. The SV driver layers itself onto the underlying disk
- * device driver by changing function pointers in the cb_ops
- * structure.
- *
- * CONFIGURATION:
- *
- * 1. Configure the driver using the svadm utility.
- * 2. Access the device as before through /dev/rdsk/c?t?d?s?
- *
- * LIMITATIONS:
- *
- * This driver should NOT be used to share a device between another
- * DataServices user interface module (e.g., STE) and a user accessing
- * the device through the block device in O_WRITE mode. This is because
- * writes through the block device are asynchronous (due to the page
- * cache) and so consistency between the block device user and the
- * STE user cannot be guaranteed.
- *
- * Data is copied between system struct buf(9s) and nsc_vec_t. This is
- * wasteful and slow.
- */
-
-#include <sys/debug.h>
-#include <sys/types.h>
-
-#include <sys/ksynch.h>
-#include <sys/kmem.h>
-#include <sys/errno.h>
-#include <sys/varargs.h>
-#include <sys/file.h>
-#include <sys/open.h>
-#include <sys/conf.h>
-#include <sys/cred.h>
-#include <sys/buf.h>
-#include <sys/uio.h>
-#ifndef DS_DDICT
-#include <sys/pathname.h>
-#endif
-#include <sys/aio_req.h>
-#include <sys/dkio.h>
-#include <sys/vtoc.h>
-#include <sys/cmn_err.h>
-#include <sys/modctl.h>
-#include <sys/ddi.h>
-#include <sys/sysmacros.h>
-#include <sys/sunddi.h>
-#include <sys/sunldi.h>
-#include <sys/nsctl/nsvers.h>
-
-#include <sys/nsc_thread.h>
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_k.h>
-#include <sys/unistat/spcs_errors.h>
-
-#ifdef DS_DDICT
-#include "../contract.h"
-#endif
-
-#include "../nsctl.h"
-
-
-#include <sys/sdt.h> /* dtrace is S10 or later */
-
-#include "sv.h"
-#include "sv_impl.h"
-#include "sv_efi.h"
-
-#define MAX_EINTR_COUNT 1000
-
-/*
- * sv_mod_status
- */
-#define SV_PREVENT_UNLOAD 1
-#define SV_ALLOW_UNLOAD 2
-
-static const int sv_major_rev = ISS_VERSION_MAJ; /* Major number */
-static const int sv_minor_rev = ISS_VERSION_MIN; /* Minor number */
-static const int sv_micro_rev = ISS_VERSION_MIC; /* Micro number */
-static const int sv_baseline_rev = ISS_VERSION_NUM; /* Baseline number */
-
-#ifdef DKIOCPARTITION
-/*
- * CRC32 polynomial table needed for computing the checksums
- * in an EFI vtoc.
- */
-static const uint32_t sv_crc32_table[256] = { CRC32_TABLE };
-#endif
-
-static clock_t sv_config_time; /* Time of successful {en,dis}able */
-static int sv_debug; /* Set non-zero for debug to syslog */
-static int sv_mod_status; /* Set to prevent modunload */
-
-static dev_info_t *sv_dip; /* Single DIP for driver */
-static kmutex_t sv_mutex; /* Protect global lists, etc. */
-
-static nsc_mem_t *sv_mem; /* nsctl memory allocator token */
-
-
-/*
- * Per device and per major state.
- */
-
-#ifndef _SunOS_5_6
-#define UNSAFE_ENTER()
-#define UNSAFE_EXIT()
-#else
-#define UNSAFE_ENTER() mutex_enter(&unsafe_driver)
-#define UNSAFE_EXIT() mutex_exit(&unsafe_driver)
-#endif
-
- /* hash table of major dev structures */
-static sv_maj_t *sv_majors[SV_MAJOR_HASH_CNT] = {0};
-static sv_dev_t *sv_devs; /* array of per device structures */
-static int sv_max_devices; /* SV version of nsc_max_devices() */
-static int sv_ndevices; /* number of SV enabled devices */
-
-/*
- * Threading.
- */
-
-int sv_threads_max = 1024; /* maximum # to dynamically alloc */
-int sv_threads = 32; /* # to pre-allocate (see sv.conf) */
-int sv_threads_extra = 0; /* addl # we would have alloc'ed */
-
-static nstset_t *sv_tset; /* the threadset pointer */
-
-static int sv_threads_hysteresis = 4; /* hysteresis for threadset resizing */
-static int sv_threads_dev = 2; /* # of threads to alloc per device */
-static int sv_threads_inc = 8; /* increment for changing the set */
-static int sv_threads_needed; /* number of threads needed */
-static int sv_no_threads; /* number of nsc_create errors */
-static int sv_max_nlive; /* max number of threads running */
-
-
-
-/*
- * nsctl fd callbacks.
- */
-
-static int svattach_fd(blind_t);
-static int svdetach_fd(blind_t);
-
-static nsc_def_t sv_fd_def[] = {
- { "Attach", (uintptr_t)svattach_fd, },
- { "Detach", (uintptr_t)svdetach_fd, },
- { 0, 0, }
-};
-
-/*
- * cb_ops functions.
- */
-
-static int svopen(dev_t *, int, int, cred_t *);
-static int svclose(dev_t, int, int, cred_t *);
-static int svioctl(dev_t, int, intptr_t, int, cred_t *, int *);
-static int svprint(dev_t, char *);
-
-/*
- * These next functions are layered into the underlying driver's devops.
- */
-
-static int sv_lyr_open(dev_t *, int, int, cred_t *);
-static int sv_lyr_close(dev_t, int, int, cred_t *);
-static int sv_lyr_strategy(struct buf *);
-static int sv_lyr_read(dev_t, struct uio *, cred_t *);
-static int sv_lyr_write(dev_t, struct uio *, cred_t *);
-static int sv_lyr_aread(dev_t, struct aio_req *, cred_t *);
-static int sv_lyr_awrite(dev_t, struct aio_req *, cred_t *);
-static int sv_lyr_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
-
-static struct cb_ops sv_cb_ops = {
- svopen, /* open */
- svclose, /* close */
- nulldev, /* strategy */
- svprint,
- nodev, /* dump */
- nodev, /* read */
- nodev, /* write */
- svioctl,
- nodev, /* devmap */
- nodev, /* mmap */
- nodev, /* segmap */
- nochpoll, /* poll */
- ddi_prop_op,
- NULL, /* NOT a stream */
- D_NEW | D_MP | D_64BIT,
- CB_REV,
- nodev, /* aread */
- nodev, /* awrite */
-};
-
-
-/*
- * dev_ops functions.
- */
-
-static int sv_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
-static int sv_attach(dev_info_t *, ddi_attach_cmd_t);
-static int sv_detach(dev_info_t *, ddi_detach_cmd_t);
-
-static struct dev_ops sv_ops = {
- DEVO_REV,
- 0,
- sv_getinfo,
- nulldev, /* identify */
- nulldev, /* probe */
- sv_attach,
- sv_detach,
- nodev, /* reset */
- &sv_cb_ops,
- (struct bus_ops *)0
-};
-
-/*
- * Module linkage.
- */
-
-extern struct mod_ops mod_driverops;
-
-static struct modldrv modldrv = {
- &mod_driverops,
- "nws:Storage Volume:" ISS_VERSION_STR,
- &sv_ops
-};
-
-static struct modlinkage modlinkage = {
- MODREV_1,
- &modldrv,
- 0
-};
-
-
-int
-_init(void)
-{
- int error;
-
- mutex_init(&sv_mutex, NULL, MUTEX_DRIVER, NULL);
-
- if ((error = mod_install(&modlinkage)) != 0) {
- mutex_destroy(&sv_mutex);
- return (error);
- }
-
-#ifdef DEBUG
- cmn_err(CE_CONT, "!sv (revision %d.%d.%d.%d, %s, %s)\n",
- sv_major_rev, sv_minor_rev, sv_micro_rev, sv_baseline_rev,
- ISS_VERSION_STR, BUILD_DATE_STR);
-#else
- if (sv_micro_rev) {
- cmn_err(CE_CONT, "!sv (revision %d.%d.%d, %s, %s)\n",
- sv_major_rev, sv_minor_rev, sv_micro_rev,
- ISS_VERSION_STR, BUILD_DATE_STR);
- } else {
- cmn_err(CE_CONT, "!sv (revision %d.%d, %s, %s)\n",
- sv_major_rev, sv_minor_rev,
- ISS_VERSION_STR, BUILD_DATE_STR);
- }
-#endif
-
- return (error);
-}
-
-
-int
-_fini(void)
-{
- int error;
-
- if ((error = mod_remove(&modlinkage)) != 0)
- return (error);
-
- mutex_destroy(&sv_mutex);
-
- return (error);
-}
-
-
-int
-_info(struct modinfo *modinfop)
-{
- return (mod_info(&modlinkage, modinfop));
-}
-
-
-/*
- * Locking & State.
- *
- * sv_mutex protects config information - sv_maj_t and sv_dev_t lists;
- * threadset creation and sizing; sv_ndevices.
- *
- * If we need to hold both sv_mutex and sv_lock, then the sv_mutex
- * must be acquired first.
- *
- * sv_lock protects the sv_dev_t structure for an individual device.
- *
- * sv_olock protects the otyp/open members of the sv_dev_t. If we need
- * to hold both sv_lock and sv_olock, then the sv_lock must be acquired
- * first.
- *
- * nsc_reserve/nsc_release are used in NSC_MULTI mode to allow multiple
- * I/O operations to a device simultaneously, as above.
- *
- * All nsc_open/nsc_close/nsc_reserve/nsc_release operations that occur
- * with sv_lock write-locked must be done with (sv_state == SV_PENDING)
- * and (sv_pending == curthread) so that any recursion through
- * sv_lyr_open/sv_lyr_close can be detected.
- */
-
-
-static int
-sv_init_devs(void)
-{
- int i;
-
- ASSERT(MUTEX_HELD(&sv_mutex));
-
- if (sv_max_devices > 0)
- return (0);
-
- sv_max_devices = nsc_max_devices();
-
- if (sv_max_devices <= 0) {
- /* nsctl is not attached (nskernd not running) */
- if (sv_debug > 0)
- cmn_err(CE_CONT, "!sv: nsc_max_devices = 0\n");
- return (EAGAIN);
- }
-
- sv_devs = nsc_kmem_zalloc((sv_max_devices * sizeof (*sv_devs)),
- KM_NOSLEEP, sv_mem);
-
- if (sv_devs == NULL) {
- cmn_err(CE_WARN, "!sv: could not allocate sv_devs array");
- return (ENOMEM);
- }
-
- for (i = 0; i < sv_max_devices; i++) {
- mutex_init(&sv_devs[i].sv_olock, NULL, MUTEX_DRIVER, NULL);
- rw_init(&sv_devs[i].sv_lock, NULL, RW_DRIVER, NULL);
- }
-
- if (sv_debug > 0)
- cmn_err(CE_CONT, "!sv: sv_init_devs successful\n");
-
- return (0);
-}
-
-
-static int
-sv_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
-{
- int rc;
-
- switch (cmd) {
-
- case DDI_ATTACH:
- sv_dip = dip;
-
- if (ddi_create_minor_node(dip, "sv", S_IFCHR,
- 0, DDI_PSEUDO, 0) != DDI_SUCCESS)
- goto failed;
-
- mutex_enter(&sv_mutex);
-
- sv_mem = nsc_register_mem("SV", NSC_MEM_LOCAL, 0);
- if (sv_mem == NULL) {
- mutex_exit(&sv_mutex);
- goto failed;
- }
-
- rc = sv_init_devs();
- if (rc != 0 && rc != EAGAIN) {
- mutex_exit(&sv_mutex);
- goto failed;
- }
-
- mutex_exit(&sv_mutex);
-
-
- ddi_report_dev(dip);
-
- sv_threads = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
- "sv_threads", sv_threads);
-
- if (sv_debug > 0)
- cmn_err(CE_CONT, "!sv: sv_threads=%d\n", sv_threads);
-
- if (sv_threads > sv_threads_max)
- sv_threads_max = sv_threads;
-
- return (DDI_SUCCESS);
-
- default:
- return (DDI_FAILURE);
- }
-
-failed:
- DTRACE_PROBE(sv_attach_failed);
- (void) sv_detach(dip, DDI_DETACH);
- return (DDI_FAILURE);
-}
-
-
-static int
-sv_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
-{
- sv_dev_t *svp;
- int i;
-
- switch (cmd) {
-
- case DDI_DETACH:
-
- /*
- * Check that everything is disabled.
- */
-
- mutex_enter(&sv_mutex);
-
- if (sv_mod_status == SV_PREVENT_UNLOAD) {
- mutex_exit(&sv_mutex);
- DTRACE_PROBE(sv_detach_err_prevent);
- return (DDI_FAILURE);
- }
-
- for (i = 0; sv_devs && i < sv_max_devices; i++) {
- svp = &sv_devs[i];
-
- if (svp->sv_state != SV_DISABLE) {
- mutex_exit(&sv_mutex);
- DTRACE_PROBE(sv_detach_err_busy);
- return (DDI_FAILURE);
- }
- }
-
-
- for (i = 0; sv_devs && i < sv_max_devices; i++) {
- mutex_destroy(&sv_devs[i].sv_olock);
- rw_destroy(&sv_devs[i].sv_lock);
- }
-
- if (sv_devs) {
- nsc_kmem_free(sv_devs,
- (sv_max_devices * sizeof (*sv_devs)));
- sv_devs = NULL;
- }
- sv_max_devices = 0;
-
- if (sv_mem) {
- nsc_unregister_mem(sv_mem);
- sv_mem = NULL;
- }
-
- mutex_exit(&sv_mutex);
-
- /*
- * Remove all minor nodes.
- */
-
- ddi_remove_minor_node(dip, NULL);
- sv_dip = NULL;
-
- return (DDI_SUCCESS);
-
- default:
- return (DDI_FAILURE);
- }
-}
-
-static sv_maj_t *
-sv_getmajor(const dev_t dev)
-{
- sv_maj_t **insert, *maj;
- major_t umaj = getmajor(dev);
-
- /*
- * See if the hash table entry, or one of the hash chains
- * is already allocated for this major number
- */
- if ((maj = sv_majors[SV_MAJOR_HASH(umaj)]) != 0) {
- do {
- if (maj->sm_major == umaj)
- return (maj);
- } while ((maj = maj->sm_next) != 0);
- }
-
- /*
- * If the sv_mutex is held, there is design flaw, as the only non-mutex
- * held callers can be sv_enable() or sv_dev_to_sv()
- * Return an error, instead of panicing the system
- */
- if (MUTEX_HELD(&sv_mutex)) {
- cmn_err(CE_WARN, "!sv: could not allocate sv_maj_t");
- return (NULL);
- }
-
- /*
- * Determine where to allocate a new element in the hash table
- */
- mutex_enter(&sv_mutex);
- insert = &(sv_majors[SV_MAJOR_HASH(umaj)]);
- for (maj = *insert; maj; maj = maj->sm_next) {
-
- /* Did another thread beat us to it? */
- if (maj->sm_major == umaj)
- return (maj);
-
- /* Find a NULL insert point? */
- if (maj->sm_next == NULL)
- insert = &maj->sm_next;
- }
-
- /*
- * Located the new insert point
- */
- *insert = nsc_kmem_zalloc(sizeof (*maj), KM_NOSLEEP, sv_mem);
- if ((maj = *insert) != 0)
- maj->sm_major = umaj;
- else
- cmn_err(CE_WARN, "!sv: could not allocate sv_maj_t");
-
- mutex_exit(&sv_mutex);
-
- return (maj);
-}
-
-/* ARGSUSED */
-
-static int
-sv_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
-{
- int rc = DDI_FAILURE;
-
- switch (infocmd) {
-
- case DDI_INFO_DEVT2DEVINFO:
- *result = sv_dip;
- rc = DDI_SUCCESS;
- break;
-
- case DDI_INFO_DEVT2INSTANCE:
- /*
- * We only have a single instance.
- */
- *result = 0;
- rc = DDI_SUCCESS;
- break;
-
- default:
- break;
- }
-
- return (rc);
-}
-
-
-/*
- * Hashing of devices onto major device structures.
- *
- * Individual device structures are hashed onto one of the sm_hash[]
- * buckets in the relevant major device structure.
- *
- * Hash insertion and deletion -must- be done with sv_mutex held. Hash
- * searching does not require the mutex because of the sm_seq member.
- * sm_seq is incremented on each insertion (-after- hash chain pointer
- * manipulation) and each deletion (-before- hash chain pointer
- * manipulation). When searching the hash chain, the seq number is
- * checked before accessing each device structure, if the seq number has
- * changed, then we restart the search from the top of the hash chain.
- * If we restart more than SV_HASH_RETRY times, we take sv_mutex and search
- * the hash chain (we are guaranteed that this search cannot be
- * interrupted).
- */
-
-#define SV_HASH_RETRY 16
-
-static sv_dev_t *
-sv_dev_to_sv(const dev_t dev, sv_maj_t **majpp)
-{
- minor_t umin = getminor(dev);
- sv_dev_t **hb, *next, *svp;
- sv_maj_t *maj;
- int seq;
- int try;
-
- /* Get major hash table */
- maj = sv_getmajor(dev);
- if (majpp)
- *majpp = maj;
- if (maj == NULL)
- return (NULL);
-
- if (maj->sm_inuse == 0) {
- DTRACE_PROBE1(
- sv_dev_to_sv_end,
- dev_t, dev);
- return (NULL);
- }
-
- hb = &(maj->sm_hash[SV_MINOR_HASH(umin)]);
- try = 0;
-
-retry:
- if (try > SV_HASH_RETRY)
- mutex_enter(&sv_mutex);
-
- seq = maj->sm_seq;
- for (svp = *hb; svp; svp = next) {
- next = svp->sv_hash;
-
- nsc_membar_stld(); /* preserve register load order */
-
- if (maj->sm_seq != seq) {
- DTRACE_PROBE1(sv_dev_to_sv_retry, dev_t, dev);
- try++;
- goto retry;
- }
-
- if (svp->sv_dev == dev)
- break;
- }
-
- if (try > SV_HASH_RETRY)
- mutex_exit(&sv_mutex);
-
- return (svp);
-}
-
-
-/*
- * Must be called with sv_mutex held.
- */
-
-static int
-sv_get_state(const dev_t udev, sv_dev_t **svpp)
-{
- sv_dev_t **hb, **insert, *svp;
- sv_maj_t *maj;
- minor_t umin;
- int i;
-
- /* Get major hash table */
- if ((maj = sv_getmajor(udev)) == NULL)
- return (NULL);
-
- /* Determine which minor hash table */
- umin = getminor(udev);
- hb = &(maj->sm_hash[SV_MINOR_HASH(umin)]);
-
- /* look for clash */
-
- insert = hb;
-
- for (svp = *hb; svp; svp = svp->sv_hash) {
- if (svp->sv_dev == udev)
- break;
-
- if (svp->sv_hash == NULL)
- insert = &svp->sv_hash;
- }
-
- if (svp) {
- DTRACE_PROBE1(
- sv_get_state_enabled,
- dev_t, udev);
- return (SV_EENABLED);
- }
-
- /* look for spare sv_devs slot */
-
- for (i = 0; i < sv_max_devices; i++) {
- svp = &sv_devs[i];
-
- if (svp->sv_state == SV_DISABLE)
- break;
- }
-
- if (i >= sv_max_devices) {
- DTRACE_PROBE1(
- sv_get_state_noslots,
- dev_t, udev);
- return (SV_ENOSLOTS);
- }
-
- svp->sv_state = SV_PENDING;
- svp->sv_pending = curthread;
-
- *insert = svp;
- svp->sv_hash = NULL;
- maj->sm_seq++; /* must be after the store to the hash chain */
-
- *svpp = svp;
-
- /*
- * We do not know the size of the underlying device at
- * this stage, so initialise "nblocks" property to
- * zero, and update it whenever we succeed in
- * nsc_reserve'ing the underlying nsc_fd_t.
- */
-
- svp->sv_nblocks = 0;
-
- return (0);
-}
-
-
-/*
- * Remove a device structure from it's hash chain.
- * Must be called with sv_mutex held.
- */
-
-static void
-sv_rm_hash(sv_dev_t *svp)
-{
- sv_dev_t **svpp;
- sv_maj_t *maj;
-
- /* Get major hash table */
- if ((maj = sv_getmajor(svp->sv_dev)) == NULL)
- return;
-
- /* remove svp from hash chain */
-
- svpp = &(maj->sm_hash[SV_MINOR_HASH(getminor(svp->sv_dev))]);
- while (*svpp) {
- if (*svpp == svp) {
- /*
- * increment of sm_seq must be before the
- * removal from the hash chain
- */
- maj->sm_seq++;
- *svpp = svp->sv_hash;
- break;
- }
-
- svpp = &(*svpp)->sv_hash;
- }
-
- svp->sv_hash = NULL;
-}
-
-/*
- * Free (disable) a device structure.
- * Must be called with sv_lock(RW_WRITER) and sv_mutex held, and will
- * perform the exits during its processing.
- */
-
-static int
-sv_free(sv_dev_t *svp, const int error)
-{
- struct cb_ops *cb_ops;
- sv_maj_t *maj;
-
- /* Get major hash table */
- if ((maj = sv_getmajor(svp->sv_dev)) == NULL)
- return (NULL);
-
- svp->sv_state = SV_PENDING;
- svp->sv_pending = curthread;
-
- /*
- * Close the fd's before removing from the hash or swapping
- * back the cb_ops pointers so that the cache flushes before new
- * io can come in.
- */
-
- if (svp->sv_fd) {
- (void) nsc_close(svp->sv_fd);
- svp->sv_fd = 0;
- }
-
- sv_rm_hash(svp);
-
- if (error != SV_ESDOPEN &&
- error != SV_ELYROPEN && --maj->sm_inuse == 0) {
-
- if (maj->sm_dev_ops)
- cb_ops = maj->sm_dev_ops->devo_cb_ops;
- else
- cb_ops = NULL;
-
- if (cb_ops && maj->sm_strategy != NULL) {
- cb_ops->cb_strategy = maj->sm_strategy;
- cb_ops->cb_close = maj->sm_close;
- cb_ops->cb_ioctl = maj->sm_ioctl;
- cb_ops->cb_write = maj->sm_write;
- cb_ops->cb_open = maj->sm_open;
- cb_ops->cb_read = maj->sm_read;
- cb_ops->cb_flag = maj->sm_flag;
-
- if (maj->sm_awrite)
- cb_ops->cb_awrite = maj->sm_awrite;
-
- if (maj->sm_aread)
- cb_ops->cb_aread = maj->sm_aread;
-
- /*
- * corbin XXX
- * Leave backing device ops in maj->sm_*
- * to handle any requests that might come
- * in during the disable. This could be
- * a problem however if the backing device
- * driver is changed while we process these
- * requests.
- *
- * maj->sm_strategy = 0;
- * maj->sm_awrite = 0;
- * maj->sm_write = 0;
- * maj->sm_ioctl = 0;
- * maj->sm_close = 0;
- * maj->sm_aread = 0;
- * maj->sm_read = 0;
- * maj->sm_open = 0;
- * maj->sm_flag = 0;
- *
- */
- }
-
- if (maj->sm_dev_ops) {
- maj->sm_dev_ops = 0;
- }
- }
-
- if (svp->sv_lh) {
- cred_t *crp = ddi_get_cred();
-
- /*
- * Close the protective layered driver open using the
- * Sun Private layered driver i/f.
- */
-
- (void) ldi_close(svp->sv_lh, FREAD|FWRITE, crp);
- svp->sv_lh = NULL;
- }
-
- svp->sv_timestamp = nsc_lbolt();
- svp->sv_state = SV_DISABLE;
- svp->sv_pending = NULL;
- rw_exit(&svp->sv_lock);
- mutex_exit(&sv_mutex);
-
- return (error);
-}
-
-/*
- * Reserve the device, taking into account the possibility that
- * the reserve might have to be retried.
- */
-static int
-sv_reserve(nsc_fd_t *fd, int flags)
-{
- int eintr_count;
- int rc;
-
- eintr_count = 0;
- do {
- rc = nsc_reserve(fd, flags);
- if (rc == EINTR) {
- ++eintr_count;
- delay(2);
- }
- } while ((rc == EINTR) && (eintr_count < MAX_EINTR_COUNT));
-
- return (rc);
-}
-
-static int
-sv_enable(const caddr_t path, const int flag,
- const dev_t udev, spcs_s_info_t kstatus)
-{
- struct dev_ops *dev_ops;
- struct cb_ops *cb_ops;
- sv_dev_t *svp;
- sv_maj_t *maj;
- nsc_size_t nblocks;
- int rc;
- cred_t *crp;
- ldi_ident_t li;
-
- if (udev == (dev_t)-1 || udev == 0) {
- DTRACE_PROBE1(
- sv_enable_err_baddev,
- dev_t, udev);
- return (SV_EBADDEV);
- }
-
- if ((flag & ~(NSC_CACHE|NSC_DEVICE)) != 0) {
- DTRACE_PROBE1(sv_enable_err_amode, dev_t, udev);
- return (SV_EAMODE);
- }
-
- /* Get major hash table */
- if ((maj = sv_getmajor(udev)) == NULL)
- return (SV_EBADDEV);
-
- mutex_enter(&sv_mutex);
-
- rc = sv_get_state(udev, &svp);
- if (rc) {
- mutex_exit(&sv_mutex);
- DTRACE_PROBE1(sv_enable_err_state, dev_t, udev);
- return (rc);
- }
-
- rw_enter(&svp->sv_lock, RW_WRITER);
-
- /*
- * Get real fd used for io
- */
-
- svp->sv_dev = udev;
- svp->sv_flag = flag;
-
- /*
- * OR in NSC_DEVICE to ensure that nskern grabs the real strategy
- * function pointer before sv swaps them out.
- */
-
- svp->sv_fd = nsc_open(path, (svp->sv_flag | NSC_DEVICE),
- sv_fd_def, (blind_t)udev, &rc);
-
- if (svp->sv_fd == NULL) {
- if (kstatus)
- spcs_s_add(kstatus, rc);
- DTRACE_PROBE1(sv_enable_err_fd, dev_t, udev);
- return (sv_free(svp, SV_ESDOPEN));
- }
-
- /*
- * Perform a layered driver open using the Sun Private layered
- * driver i/f to ensure that the cb_ops structure for the driver
- * is not detached out from under us whilst sv is enabled.
- *
- */
-
- crp = ddi_get_cred();
- svp->sv_lh = NULL;
-
- if ((rc = ldi_ident_from_dev(svp->sv_dev, &li)) == 0) {
- rc = ldi_open_by_dev(&svp->sv_dev,
- OTYP_BLK, FREAD|FWRITE, crp, &svp->sv_lh, li);
- }
-
- if (rc != 0) {
- if (kstatus)
- spcs_s_add(kstatus, rc);
- DTRACE_PROBE1(sv_enable_err_lyr_open, dev_t, udev);
- return (sv_free(svp, SV_ELYROPEN));
- }
-
- /*
- * Do layering if required - must happen after nsc_open().
- */
-
- if (maj->sm_inuse++ == 0) {
- maj->sm_dev_ops = nsc_get_devops(getmajor(udev));
-
- if (maj->sm_dev_ops == NULL ||
- maj->sm_dev_ops->devo_cb_ops == NULL) {
- DTRACE_PROBE1(sv_enable_err_load, dev_t, udev);
- return (sv_free(svp, SV_ELOAD));
- }
-
- dev_ops = maj->sm_dev_ops;
- cb_ops = dev_ops->devo_cb_ops;
-
- if (cb_ops->cb_strategy == NULL ||
- cb_ops->cb_strategy == nodev ||
- cb_ops->cb_strategy == nulldev) {
- DTRACE_PROBE1(sv_enable_err_nostrategy, dev_t, udev);
- return (sv_free(svp, SV_ELOAD));
- }
-
- if (cb_ops->cb_strategy == sv_lyr_strategy) {
- DTRACE_PROBE1(sv_enable_err_svstrategy, dev_t, udev);
- return (sv_free(svp, SV_ESTRATEGY));
- }
-
- maj->sm_strategy = cb_ops->cb_strategy;
- maj->sm_close = cb_ops->cb_close;
- maj->sm_ioctl = cb_ops->cb_ioctl;
- maj->sm_write = cb_ops->cb_write;
- maj->sm_open = cb_ops->cb_open;
- maj->sm_read = cb_ops->cb_read;
- maj->sm_flag = cb_ops->cb_flag;
-
- cb_ops->cb_flag = cb_ops->cb_flag | D_MP;
- cb_ops->cb_strategy = sv_lyr_strategy;
- cb_ops->cb_close = sv_lyr_close;
- cb_ops->cb_ioctl = sv_lyr_ioctl;
- cb_ops->cb_write = sv_lyr_write;
- cb_ops->cb_open = sv_lyr_open;
- cb_ops->cb_read = sv_lyr_read;
-
- /*
- * Check that the driver has async I/O entry points
- * before changing them.
- */
-
- if (dev_ops->devo_rev < 3 || cb_ops->cb_rev < 1) {
- maj->sm_awrite = 0;
- maj->sm_aread = 0;
- } else {
- maj->sm_awrite = cb_ops->cb_awrite;
- maj->sm_aread = cb_ops->cb_aread;
-
- cb_ops->cb_awrite = sv_lyr_awrite;
- cb_ops->cb_aread = sv_lyr_aread;
- }
-
- /*
- * Bug 4645743
- *
- * Prevent sv from ever unloading after it has interposed
- * on a major device because there is a race between
- * sv removing its layered entry points from the target
- * dev_ops, a client coming in and accessing the driver,
- * and the kernel modunloading the sv text.
- *
- * To allow unload, do svboot -u, which only happens in
- * pkgrm time.
- */
- ASSERT(MUTEX_HELD(&sv_mutex));
- sv_mod_status = SV_PREVENT_UNLOAD;
- }
-
-
- svp->sv_timestamp = nsc_lbolt();
- svp->sv_state = SV_ENABLE;
- svp->sv_pending = NULL;
- rw_exit(&svp->sv_lock);
-
- sv_ndevices++;
- mutex_exit(&sv_mutex);
-
- nblocks = 0;
- if (sv_reserve(svp->sv_fd, NSC_READ|NSC_MULTI|NSC_PCATCH) == 0) {
- nblocks = svp->sv_nblocks;
- nsc_release(svp->sv_fd);
- }
-
- cmn_err(CE_CONT, "!sv: rdev 0x%lx, nblocks %" NSC_SZFMT "\n",
- svp->sv_dev, nblocks);
-
- return (0);
-}
-
-
-static int
-sv_prepare_unload()
-{
- int rc = 0;
-
- mutex_enter(&sv_mutex);
-
- if (sv_mod_status == SV_PREVENT_UNLOAD) {
- if ((sv_ndevices != 0) || (sv_tset != NULL)) {
- rc = EBUSY;
- } else {
- sv_mod_status = SV_ALLOW_UNLOAD;
- delay(SV_WAIT_UNLOAD * drv_usectohz(1000000));
- }
- }
-
- mutex_exit(&sv_mutex);
- return (rc);
-}
-
-static int
-svattach_fd(blind_t arg)
-{
- dev_t dev = (dev_t)arg;
- sv_dev_t *svp = sv_dev_to_sv(dev, NULL);
- int rc;
-
- if (sv_debug > 0)
- cmn_err(CE_CONT, "!svattach_fd(%p, %p)\n", arg, (void *)svp);
-
- if (svp == NULL) {
- cmn_err(CE_WARN, "!svattach_fd: no state (arg %p)", arg);
- return (0);
- }
-
- if ((rc = nsc_partsize(svp->sv_fd, &svp->sv_nblocks)) != 0) {
- cmn_err(CE_WARN,
- "!svattach_fd: nsc_partsize() failed, rc %d", rc);
- svp->sv_nblocks = 0;
- }
-
- if ((rc = nsc_maxfbas(svp->sv_fd, 0, &svp->sv_maxfbas)) != 0) {
- cmn_err(CE_WARN,
- "!svattach_fd: nsc_maxfbas() failed, rc %d", rc);
- svp->sv_maxfbas = 0;
- }
-
- if (sv_debug > 0) {
- cmn_err(CE_CONT,
- "!svattach_fd(%p): size %" NSC_SZFMT ", "
- "maxfbas %" NSC_SZFMT "\n",
- arg, svp->sv_nblocks, svp->sv_maxfbas);
- }
-
- return (0);
-}
-
-
-static int
-svdetach_fd(blind_t arg)
-{
- dev_t dev = (dev_t)arg;
- sv_dev_t *svp = sv_dev_to_sv(dev, NULL);
-
- if (sv_debug > 0)
- cmn_err(CE_CONT, "!svdetach_fd(%p, %p)\n", arg, (void *)svp);
-
- /* svp can be NULL during disable of an sv */
- if (svp == NULL)
- return (0);
-
- svp->sv_maxfbas = 0;
- svp->sv_nblocks = 0;
- return (0);
-}
-
-
-/*
- * Side effect: if called with (guard != 0), then expects both sv_mutex
- * and sv_lock(RW_WRITER) to be held, and will release them before returning.
- */
-
-/* ARGSUSED */
-static int
-sv_disable(dev_t dev, spcs_s_info_t kstatus)
-{
- sv_dev_t *svp = sv_dev_to_sv(dev, NULL);
-
- if (svp == NULL) {
-
- DTRACE_PROBE1(sv_disable_err_nodev, sv_dev_t *, svp);
- return (SV_ENODEV);
- }
-
- mutex_enter(&sv_mutex);
- rw_enter(&svp->sv_lock, RW_WRITER);
-
- if (svp->sv_fd == NULL || svp->sv_state != SV_ENABLE) {
- rw_exit(&svp->sv_lock);
- mutex_exit(&sv_mutex);
-
- DTRACE_PROBE1(sv_disable_err_disabled, sv_dev_t *, svp);
- return (SV_EDISABLED);
- }
-
-
- sv_ndevices--;
- return (sv_free(svp, 0));
-}
-
-
-
-static int
-sv_lyr_open(dev_t *devp, int flag, int otyp, cred_t *crp)
-{
- nsc_buf_t *tmph;
- sv_dev_t *svp;
- sv_maj_t *maj;
- int (*fn)();
- dev_t odev;
- int ret;
- int rc;
-
- svp = sv_dev_to_sv(*devp, &maj);
-
- if (svp) {
- if (svp->sv_state == SV_PENDING &&
- svp->sv_pending == curthread) {
- /*
- * This is a recursive open from a call to
- * ddi_lyr_open_by_devt and so we just want
- * to pass it straight through to the
- * underlying driver.
- */
- DTRACE_PROBE2(sv_lyr_open_recursive,
- sv_dev_t *, svp,
- dev_t, *devp);
- svp = NULL;
- } else
- rw_enter(&svp->sv_lock, RW_READER);
- }
-
- odev = *devp;
-
- if (maj && (fn = maj->sm_open) != 0) {
- if (!(maj->sm_flag & D_MP)) {
- UNSAFE_ENTER();
- ret = (*fn)(devp, flag, otyp, crp);
- UNSAFE_EXIT();
- } else {
- ret = (*fn)(devp, flag, otyp, crp);
- }
-
- if (ret == 0) {
- /*
- * Re-acquire svp if the driver changed *devp.
- */
-
- if (*devp != odev) {
- if (svp != NULL)
- rw_exit(&svp->sv_lock);
-
- svp = sv_dev_to_sv(*devp, NULL);
-
- if (svp) {
- rw_enter(&svp->sv_lock, RW_READER);
- }
- }
- }
- } else {
- ret = ENODEV;
- }
-
- if (svp && ret != 0 && svp->sv_state == SV_ENABLE) {
- /*
- * Underlying DDI open failed, but we have this
- * device SV enabled. If we can read some data
- * from the device, fake a successful open (this
- * probably means that this device is RDC'd and we
- * are getting the data from the secondary node).
- *
- * The reserve must be done with NSC_TRY|NSC_NOWAIT to
- * ensure that it does not deadlock if this open is
- * coming from nskernd:get_bsize().
- */
- rc = sv_reserve(svp->sv_fd,
- NSC_TRY | NSC_NOWAIT | NSC_MULTI | NSC_PCATCH);
- if (rc == 0) {
- tmph = NULL;
-
- rc = nsc_alloc_buf(svp->sv_fd, 0, 1, NSC_READ, &tmph);
- if (rc <= 0) {
- /* success */
- ret = 0;
- }
-
- if (tmph) {
- (void) nsc_free_buf(tmph);
- tmph = NULL;
- }
-
- nsc_release(svp->sv_fd);
-
- /*
- * Count the number of layered opens that we
- * fake since we have to fake a matching number
- * of closes (OTYP_LYR open/close calls must be
- * paired).
- */
-
- if (ret == 0 && otyp == OTYP_LYR) {
- mutex_enter(&svp->sv_olock);
- svp->sv_openlcnt++;
- mutex_exit(&svp->sv_olock);
- }
- }
- }
-
- if (svp) {
- rw_exit(&svp->sv_lock);
- }
-
- return (ret);
-}
-
-
-static int
-sv_lyr_close(dev_t dev, int flag, int otyp, cred_t *crp)
-{
- sv_dev_t *svp;
- sv_maj_t *maj;
- int (*fn)();
- int ret;
-
- svp = sv_dev_to_sv(dev, &maj);
-
- if (svp &&
- svp->sv_state == SV_PENDING &&
- svp->sv_pending == curthread) {
- /*
- * This is a recursive open from a call to
- * ddi_lyr_close and so we just want
- * to pass it straight through to the
- * underlying driver.
- */
- DTRACE_PROBE2(sv_lyr_close_recursive, sv_dev_t *, svp,
- dev_t, dev);
- svp = NULL;
- }
-
- if (svp) {
- rw_enter(&svp->sv_lock, RW_READER);
-
- if (otyp == OTYP_LYR) {
- mutex_enter(&svp->sv_olock);
-
- if (svp->sv_openlcnt) {
- /*
- * Consume sufficient layered closes to
- * account for the opens that we faked
- * whilst the device was failed.
- */
- svp->sv_openlcnt--;
- mutex_exit(&svp->sv_olock);
- rw_exit(&svp->sv_lock);
-
- DTRACE_PROBE1(sv_lyr_close_end, dev_t, dev);
-
- return (0);
- }
-
- mutex_exit(&svp->sv_olock);
- }
- }
-
- if (maj && (fn = maj->sm_close) != 0) {
- if (!(maj->sm_flag & D_MP)) {
- UNSAFE_ENTER();
- ret = (*fn)(dev, flag, otyp, crp);
- UNSAFE_EXIT();
- } else {
- ret = (*fn)(dev, flag, otyp, crp);
- }
- } else {
- ret = ENODEV;
- }
-
- if (svp) {
- rw_exit(&svp->sv_lock);
- }
-
- return (ret);
-}
-
-
-/*
- * Convert the specified dev_t into a locked and enabled sv_dev_t, or
- * return NULL.
- */
-static sv_dev_t *
-sv_find_enabled(const dev_t dev, sv_maj_t **majpp)
-{
- sv_dev_t *svp;
-
- while ((svp = sv_dev_to_sv(dev, majpp)) != NULL) {
- rw_enter(&svp->sv_lock, RW_READER);
-
- if (svp->sv_state == SV_ENABLE) {
- /* locked and enabled */
- break;
- }
-
- /*
- * State was changed while waiting on the lock.
- * Wait for a stable state.
- */
- rw_exit(&svp->sv_lock);
-
- DTRACE_PROBE1(sv_find_enabled_retry, dev_t, dev);
-
- delay(2);
- }
-
- return (svp);
-}
-
-
-static int
-sv_lyr_uio(dev_t dev, uio_t *uiop, cred_t *crp, int rw)
-{
- sv_dev_t *svp;
- sv_maj_t *maj;
- int (*fn)();
- int rc;
-
- svp = sv_find_enabled(dev, &maj);
- if (svp == NULL) {
- if (maj) {
- if (rw == NSC_READ)
- fn = maj->sm_read;
- else
- fn = maj->sm_write;
-
- if (fn != 0) {
- if (!(maj->sm_flag & D_MP)) {
- UNSAFE_ENTER();
- rc = (*fn)(dev, uiop, crp);
- UNSAFE_EXIT();
- } else {
- rc = (*fn)(dev, uiop, crp);
- }
- }
-
- return (rc);
- } else {
- return (ENODEV);
- }
- }
-
- ASSERT(RW_READ_HELD(&svp->sv_lock));
-
- if (svp->sv_flag == 0) {
- /*
- * guard access mode
- * - prevent user level access to the device
- */
- DTRACE_PROBE1(sv_lyr_uio_err_guard, uio_t *, uiop);
- rc = EPERM;
- goto out;
- }
-
- if ((rc = sv_reserve(svp->sv_fd, NSC_MULTI|NSC_PCATCH)) != 0) {
- DTRACE_PROBE1(sv_lyr_uio_err_rsrv, uio_t *, uiop);
- goto out;
- }
-
- if (rw == NSC_READ)
- rc = nsc_uread(svp->sv_fd, uiop, crp);
- else
- rc = nsc_uwrite(svp->sv_fd, uiop, crp);
-
- nsc_release(svp->sv_fd);
-
-out:
- rw_exit(&svp->sv_lock);
-
- return (rc);
-}
-
-
-static int
-sv_lyr_read(dev_t dev, uio_t *uiop, cred_t *crp)
-{
- return (sv_lyr_uio(dev, uiop, crp, NSC_READ));
-}
-
-
-static int
-sv_lyr_write(dev_t dev, uio_t *uiop, cred_t *crp)
-{
- return (sv_lyr_uio(dev, uiop, crp, NSC_WRITE));
-}
-
-
-/* ARGSUSED */
-
-static int
-sv_lyr_aread(dev_t dev, struct aio_req *aio, cred_t *crp)
-{
- return (aphysio(sv_lyr_strategy,
- anocancel, dev, B_READ, minphys, aio));
-}
-
-
-/* ARGSUSED */
-
-static int
-sv_lyr_awrite(dev_t dev, struct aio_req *aio, cred_t *crp)
-{
- return (aphysio(sv_lyr_strategy,
- anocancel, dev, B_WRITE, minphys, aio));
-}
-
-
-/*
- * Set up an array containing the list of raw path names
- * The array for the paths is svl and the size of the array is
- * in size.
- *
- * If there are more layered devices than will fit in the array,
- * the number of extra layered devices is returned. Otherwise
- * zero is return.
- *
- * Input:
- * svn : array for paths
- * size : size of the array
- *
- * Output (extra):
- * zero : All paths fit in array
- * >0 : Number of defined layered devices don't fit in array
- */
-
-static int
-sv_list(void *ptr, const int size, int *extra, const int ilp32)
-{
- sv_name32_t *svn32;
- sv_name_t *svn;
- sv_dev_t *svp;
- int *mode, *nblocks;
- int i, index;
- char *path;
-
- *extra = 0;
- index = 0;
-
- if (ilp32)
- svn32 = ptr;
- else
- svn = ptr;
-
- mutex_enter(&sv_mutex);
- for (i = 0; i < sv_max_devices; i++) {
- svp = &sv_devs[i];
-
- rw_enter(&svp->sv_lock, RW_READER);
-
- if (svp->sv_state != SV_ENABLE) {
- rw_exit(&svp->sv_lock);
- continue;
- }
-
- if ((*extra) != 0 || ptr == NULL) {
- /* Another overflow entry */
- rw_exit(&svp->sv_lock);
- (*extra)++;
- continue;
- }
-
- if (ilp32) {
- nblocks = &svn32->svn_nblocks;
- mode = &svn32->svn_mode;
- path = svn32->svn_path;
-
- svn32->svn_timestamp = (uint32_t)svp->sv_timestamp;
- svn32++;
- } else {
- nblocks = &svn->svn_nblocks;
- mode = &svn->svn_mode;
- path = svn->svn_path;
-
- svn->svn_timestamp = svp->sv_timestamp;
- svn++;
- }
-
- (void) strcpy(path, nsc_pathname(svp->sv_fd));
- *nblocks = svp->sv_nblocks;
- *mode = svp->sv_flag;
-
- if (*nblocks == 0) {
- if (sv_debug > 3)
- cmn_err(CE_CONT, "!sv_list: need to reserve\n");
-
- if (sv_reserve(svp->sv_fd, NSC_MULTI|NSC_PCATCH) == 0) {
- *nblocks = svp->sv_nblocks;
- nsc_release(svp->sv_fd);
- }
- }
-
- if (++index >= size) {
- /* Out of space */
- (*extra)++;
- }
-
- rw_exit(&svp->sv_lock);
- }
- mutex_exit(&sv_mutex);
-
- if (index < size) {
- /* NULL terminated list */
- if (ilp32)
- svn32->svn_path[0] = '\0';
- else
- svn->svn_path[0] = '\0';
- }
-
- return (0);
-}
-
-
-static void
-sv_thread_tune(int threads)
-{
- int incr = (threads > 0) ? 1 : -1;
- int change = 0;
- int nthreads;
-
- ASSERT(MUTEX_HELD(&sv_mutex));
-
- if (sv_threads_extra) {
- /* keep track of any additional threads requested */
- if (threads > 0) {
- sv_threads_extra += threads;
- return;
- }
- threads = -threads;
- if (threads >= sv_threads_extra) {
- threads -= sv_threads_extra;
- sv_threads_extra = 0;
- /* fall through to while loop */
- } else {
- sv_threads_extra -= threads;
- return;
- }
- } else if (threads > 0) {
- /*
- * do not increase the number of threads beyond
- * sv_threads_max when doing dynamic thread tuning
- */
- nthreads = nst_nthread(sv_tset);
- if ((nthreads + threads) > sv_threads_max) {
- sv_threads_extra = nthreads + threads - sv_threads_max;
- threads = sv_threads_max - nthreads;
- if (threads <= 0)
- return;
- }
- }
-
- if (threads < 0)
- threads = -threads;
-
- while (threads--) {
- nthreads = nst_nthread(sv_tset);
- sv_threads_needed += incr;
-
- if (sv_threads_needed >= nthreads)
- change += nst_add_thread(sv_tset, sv_threads_inc);
- else if ((sv_threads_needed <
- (nthreads - (sv_threads_inc + sv_threads_hysteresis))) &&
- ((nthreads - sv_threads_inc) >= sv_threads))
- change -= nst_del_thread(sv_tset, sv_threads_inc);
- }
-
-#ifdef DEBUG
- if (change) {
- cmn_err(CE_NOTE,
- "!sv_thread_tune: threads needed %d, nthreads %d, "
- "nthreads change %d",
- sv_threads_needed, nst_nthread(sv_tset), change);
- }
-#endif
-}
-
-
-/* ARGSUSED */
-static int
-svopen(dev_t *devp, int flag, int otyp, cred_t *crp)
-{
- int rc;
-
- mutex_enter(&sv_mutex);
- rc = sv_init_devs();
- mutex_exit(&sv_mutex);
-
- return (rc);
-}
-
-
-/* ARGSUSED */
-static int
-svclose(dev_t dev, int flag, int otyp, cred_t *crp)
-{
- const int secs = HZ * 5;
- const int ticks = HZ / 10;
- int loops = secs / ticks;
-
- mutex_enter(&sv_mutex);
- while (sv_ndevices <= 0 && sv_tset != NULL && loops > 0) {
- if (nst_nlive(sv_tset) <= 0) {
- nst_destroy(sv_tset);
- sv_tset = NULL;
- break;
- }
-
- /* threads still active - wait for them to exit */
- mutex_exit(&sv_mutex);
- delay(ticks);
- loops--;
- mutex_enter(&sv_mutex);
- }
- mutex_exit(&sv_mutex);
-
- if (loops <= 0) {
- cmn_err(CE_WARN,
-#ifndef DEBUG
- /* do not write to console when non-DEBUG */
- "!"
-#endif
- "sv:svclose: threads still active "
- "after %d sec - leaking thread set", secs);
- }
-
- return (0);
-}
-
-
-static int
-svioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *crp, int *rvalp)
-{
- char itmp1[12], itmp2[12]; /* temp char array for editing ints */
- spcs_s_info_t kstatus; /* Kernel version of spcs status */
- spcs_s_info_t ustatus; /* Address of user version of spcs status */
- sv_list32_t svl32; /* 32 bit Initial structure for SVIOC_LIST */
- sv_version_t svv; /* Version structure */
- sv_conf_t svc; /* User config structure */
- sv_list_t svl; /* Initial structure for SVIOC_LIST */
- void *usvn; /* Address of user sv_name_t */
- void *svn = NULL; /* Array for SVIOC_LIST */
- uint64_t phash; /* pathname hash */
- int rc = 0; /* Return code -- errno */
- int size; /* Number of items in array */
- int bytes; /* Byte size of array */
- int ilp32; /* Convert data structures for ilp32 userland */
-
- *rvalp = 0;
-
- /*
- * If sv_mod_status is 0 or SV_PREVENT_UNLOAD, then it will continue.
- * else it means it previously was SV_PREVENT_UNLOAD, and now it's
- * SV_ALLOW_UNLOAD, expecting the driver to eventually unload.
- *
- * SV_ALLOW_UNLOAD is final state, so no need to grab sv_mutex.
- */
- if (sv_mod_status == SV_ALLOW_UNLOAD) {
- return (EBUSY);
- }
-
- if ((cmd != SVIOC_LIST) && ((rc = drv_priv(crp)) != 0))
- return (rc);
-
- kstatus = spcs_s_kcreate();
- if (!kstatus) {
- DTRACE_PROBE1(sv_ioctl_err_kcreate, dev_t, dev);
- return (ENOMEM);
- }
-
- ilp32 = (ddi_model_convert_from((mode & FMODELS)) == DDI_MODEL_ILP32);
-
- switch (cmd) {
-
- case SVIOC_ENABLE:
-
- if (ilp32) {
- sv_conf32_t svc32;
-
- if (ddi_copyin((void *)arg, &svc32,
- sizeof (svc32), mode) < 0) {
- spcs_s_kfree(kstatus);
- return (EFAULT);
- }
-
- svc.svc_error = (spcs_s_info_t)svc32.svc_error;
- (void) strcpy(svc.svc_path, svc32.svc_path);
- svc.svc_flag = svc32.svc_flag;
- svc.svc_major = svc32.svc_major;
- svc.svc_minor = svc32.svc_minor;
- } else {
- if (ddi_copyin((void *)arg, &svc,
- sizeof (svc), mode) < 0) {
- spcs_s_kfree(kstatus);
- return (EFAULT);
- }
- }
-
- /* force to raw access */
- svc.svc_flag = NSC_DEVICE;
-
- if (sv_tset == NULL) {
- mutex_enter(&sv_mutex);
-
- if (sv_tset == NULL) {
- sv_tset = nst_init("sv_thr", sv_threads);
- }
-
- mutex_exit(&sv_mutex);
-
- if (sv_tset == NULL) {
- cmn_err(CE_WARN,
- "!sv: could not allocate %d threads",
- sv_threads);
- }
- }
-
- rc = sv_enable(svc.svc_path, svc.svc_flag,
- makedevice(svc.svc_major, svc.svc_minor), kstatus);
-
- if (rc == 0) {
- sv_config_time = nsc_lbolt();
-
- mutex_enter(&sv_mutex);
- sv_thread_tune(sv_threads_dev);
- mutex_exit(&sv_mutex);
- }
-
- DTRACE_PROBE3(sv_ioctl_end, dev_t, dev, int, *rvalp, int, rc);
-
- return (spcs_s_ocopyoutf(&kstatus, svc.svc_error, rc));
- /* NOTREACHED */
-
- case SVIOC_DISABLE:
-
- if (ilp32) {
- sv_conf32_t svc32;
-
- if (ddi_copyin((void *)arg, &svc32,
- sizeof (svc32), mode) < 0) {
- spcs_s_kfree(kstatus);
- return (EFAULT);
- }
-
- svc.svc_error = (spcs_s_info_t)svc32.svc_error;
- svc.svc_major = svc32.svc_major;
- svc.svc_minor = svc32.svc_minor;
- (void) strcpy(svc.svc_path, svc32.svc_path);
- svc.svc_flag = svc32.svc_flag;
- } else {
- if (ddi_copyin((void *)arg, &svc,
- sizeof (svc), mode) < 0) {
- spcs_s_kfree(kstatus);
- return (EFAULT);
- }
- }
-
- if (svc.svc_major == (major_t)-1 &&
- svc.svc_minor == (minor_t)-1) {
- sv_dev_t *svp;
- int i;
-
- /*
- * User level could not find the minor device
- * node, so do this the slow way by searching
- * the entire sv config for a matching pathname.
- */
-
- phash = nsc_strhash(svc.svc_path);
-
- mutex_enter(&sv_mutex);
-
- for (i = 0; i < sv_max_devices; i++) {
- svp = &sv_devs[i];
-
- if (svp->sv_state == SV_DISABLE ||
- svp->sv_fd == NULL)
- continue;
-
- if (nsc_fdpathcmp(svp->sv_fd, phash,
- svc.svc_path) == 0) {
- svc.svc_major = getmajor(svp->sv_dev);
- svc.svc_minor = getminor(svp->sv_dev);
- break;
- }
- }
-
- mutex_exit(&sv_mutex);
-
- if (svc.svc_major == (major_t)-1 &&
- svc.svc_minor == (minor_t)-1)
- return (spcs_s_ocopyoutf(&kstatus,
- svc.svc_error, SV_ENODEV));
- }
-
- rc = sv_disable(makedevice(svc.svc_major, svc.svc_minor),
- kstatus);
-
- if (rc == 0) {
- sv_config_time = nsc_lbolt();
-
- mutex_enter(&sv_mutex);
- sv_thread_tune(-sv_threads_dev);
- mutex_exit(&sv_mutex);
- }
-
- DTRACE_PROBE3(sv_ioctl_2, dev_t, dev, int, *rvalp, int, rc);
-
- return (spcs_s_ocopyoutf(&kstatus, svc.svc_error, rc));
- /* NOTREACHED */
-
- case SVIOC_LIST:
-
- if (ilp32) {
- if (ddi_copyin((void *)arg, &svl32,
- sizeof (svl32), mode) < 0) {
- spcs_s_kfree(kstatus);
- return (EFAULT);
- }
-
- ustatus = (spcs_s_info_t)svl32.svl_error;
- size = svl32.svl_count;
- usvn = (void *)(unsigned long)svl32.svl_names;
- } else {
- if (ddi_copyin((void *)arg, &svl,
- sizeof (svl), mode) < 0) {
- spcs_s_kfree(kstatus);
- return (EFAULT);
- }
-
- ustatus = svl.svl_error;
- size = svl.svl_count;
- usvn = svl.svl_names;
- }
-
- /* Do some boundary checking */
- if ((size < 0) || (size > sv_max_devices)) {
- /* Array size is out of range */
- return (spcs_s_ocopyoutf(&kstatus, ustatus,
- SV_EARRBOUNDS, "0",
- spcs_s_inttostring(sv_max_devices, itmp1,
- sizeof (itmp1), 0),
- spcs_s_inttostring(size, itmp2,
- sizeof (itmp2), 0)));
- }
-
- if (ilp32)
- bytes = size * sizeof (sv_name32_t);
- else
- bytes = size * sizeof (sv_name_t);
-
- /* Allocate memory for the array of structures */
- if (bytes != 0) {
- svn = kmem_zalloc(bytes, KM_SLEEP);
- if (!svn) {
- return (spcs_s_ocopyoutf(&kstatus,
- ustatus, ENOMEM));
- }
- }
-
- rc = sv_list(svn, size, rvalp, ilp32);
- if (rc) {
- if (svn != NULL)
- kmem_free(svn, bytes);
- return (spcs_s_ocopyoutf(&kstatus, ustatus, rc));
- }
-
- if (ilp32) {
- svl32.svl_timestamp = (uint32_t)sv_config_time;
- svl32.svl_maxdevs = (int32_t)sv_max_devices;
-
- /* Return the list structure */
- if (ddi_copyout(&svl32, (void *)arg,
- sizeof (svl32), mode) < 0) {
- spcs_s_kfree(kstatus);
- if (svn != NULL)
- kmem_free(svn, bytes);
- return (EFAULT);
- }
- } else {
- svl.svl_timestamp = sv_config_time;
- svl.svl_maxdevs = sv_max_devices;
-
- /* Return the list structure */
- if (ddi_copyout(&svl, (void *)arg,
- sizeof (svl), mode) < 0) {
- spcs_s_kfree(kstatus);
- if (svn != NULL)
- kmem_free(svn, bytes);
- return (EFAULT);
- }
- }
-
- /* Return the array */
- if (svn != NULL) {
- if (ddi_copyout(svn, usvn, bytes, mode) < 0) {
- kmem_free(svn, bytes);
- spcs_s_kfree(kstatus);
- return (EFAULT);
- }
- kmem_free(svn, bytes);
- }
-
- DTRACE_PROBE3(sv_ioctl_3, dev_t, dev, int, *rvalp, int, 0);
-
- return (spcs_s_ocopyoutf(&kstatus, ustatus, 0));
- /* NOTREACHED */
-
- case SVIOC_VERSION:
-
- if (ilp32) {
- sv_version32_t svv32;
-
- if (ddi_copyin((void *)arg, &svv32,
- sizeof (svv32), mode) < 0) {
- spcs_s_kfree(kstatus);
- return (EFAULT);
- }
-
- svv32.svv_major_rev = sv_major_rev;
- svv32.svv_minor_rev = sv_minor_rev;
- svv32.svv_micro_rev = sv_micro_rev;
- svv32.svv_baseline_rev = sv_baseline_rev;
-
- if (ddi_copyout(&svv32, (void *)arg,
- sizeof (svv32), mode) < 0) {
- spcs_s_kfree(kstatus);
- return (EFAULT);
- }
-
- ustatus = (spcs_s_info_t)svv32.svv_error;
- } else {
- if (ddi_copyin((void *)arg, &svv,
- sizeof (svv), mode) < 0) {
- spcs_s_kfree(kstatus);
- return (EFAULT);
- }
-
- svv.svv_major_rev = sv_major_rev;
- svv.svv_minor_rev = sv_minor_rev;
- svv.svv_micro_rev = sv_micro_rev;
- svv.svv_baseline_rev = sv_baseline_rev;
-
- if (ddi_copyout(&svv, (void *)arg,
- sizeof (svv), mode) < 0) {
- spcs_s_kfree(kstatus);
- return (EFAULT);
- }
-
- ustatus = svv.svv_error;
- }
-
- DTRACE_PROBE3(sv_ioctl_4, dev_t, dev, int, *rvalp, int, 0);
-
- return (spcs_s_ocopyoutf(&kstatus, ustatus, 0));
- /* NOTREACHED */
-
- case SVIOC_UNLOAD:
- rc = sv_prepare_unload();
-
- if (ddi_copyout(&rc, (void *)arg, sizeof (rc), mode) < 0) {
- rc = EFAULT;
- }
-
- spcs_s_kfree(kstatus);
- return (rc);
-
- default:
- spcs_s_kfree(kstatus);
-
- DTRACE_PROBE3(sv_ioctl_4, dev_t, dev, int, *rvalp, int, EINVAL);
-
- return (EINVAL);
- /* NOTREACHED */
- }
-
- /* NOTREACHED */
-}
-
-
-/* ARGSUSED */
-static int
-svprint(dev_t dev, char *str)
-{
- int instance = ddi_get_instance(sv_dip);
- cmn_err(CE_WARN, "!%s%d: %s", ddi_get_name(sv_dip), instance, str);
- return (0);
-}
-
-
-static void
-_sv_lyr_strategy(struct buf *bp)
-{
- caddr_t buf_addr; /* pointer to linear buffer in bp */
- nsc_buf_t *bufh = NULL;
- nsc_buf_t *hndl = NULL;
- sv_dev_t *svp;
- nsc_vec_t *v;
- sv_maj_t *maj;
- nsc_size_t fba_req, fba_len; /* FBA lengths */
- nsc_off_t fba_off; /* FBA offset */
- size_t tocopy, nbytes; /* byte lengths */
- int rw, rc; /* flags and return codes */
- int (*fn)();
-
- rc = 0;
-
- if (sv_debug > 5)
- cmn_err(CE_CONT, "!_sv_lyr_strategy(%p)\n", (void *)bp);
-
- svp = sv_find_enabled(bp->b_edev, &maj);
- if (svp == NULL) {
- if (maj && (fn = maj->sm_strategy) != 0) {
- if (!(maj->sm_flag & D_MP)) {
- UNSAFE_ENTER();
- rc = (*fn)(bp);
- UNSAFE_EXIT();
- } else {
- rc = (*fn)(bp);
- }
- return;
- } else {
- bioerror(bp, ENODEV);
- biodone(bp);
- return;
- }
- }
-
- ASSERT(RW_READ_HELD(&svp->sv_lock));
-
- if (svp->sv_flag == 0) {
- /*
- * guard access mode
- * - prevent user level access to the device
- */
- DTRACE_PROBE1(sv_lyr_strategy_err_guard, struct buf *, bp);
- bioerror(bp, EPERM);
- goto out;
- }
-
- if ((rc = sv_reserve(svp->sv_fd, NSC_MULTI|NSC_PCATCH)) != 0) {
- DTRACE_PROBE1(sv_lyr_strategy_err_rsrv, struct buf *, bp);
-
- if (rc == EINTR)
- cmn_err(CE_WARN, "!nsc_reserve() returned EINTR");
- bioerror(bp, rc);
- goto out;
- }
-
- if (bp->b_lblkno >= (diskaddr_t)svp->sv_nblocks) {
- DTRACE_PROBE1(sv_lyr_strategy_eof, struct buf *, bp);
-
- if (bp->b_flags & B_READ) {
- /* return EOF, not an error */
- bp->b_resid = bp->b_bcount;
- bioerror(bp, 0);
- } else
- bioerror(bp, EINVAL);
-
- goto done;
- }
-
- /*
- * Preallocate a handle once per call to strategy.
- * If this fails, then the nsc_alloc_buf() will allocate
- * a temporary handle per allocation/free pair.
- */
-
- DTRACE_PROBE1(sv_dbg_alloch_start, sv_dev_t *, svp);
-
- bufh = nsc_alloc_handle(svp->sv_fd, NULL, NULL, NULL);
-
- DTRACE_PROBE1(sv_dbg_alloch_end, sv_dev_t *, svp);
-
- if (bufh && (bufh->sb_flag & NSC_HACTIVE) != 0) {
- DTRACE_PROBE1(sv_lyr_strategy_err_hactive, struct buf *, bp);
-
- cmn_err(CE_WARN,
- "!sv: allocated active handle (bufh %p, flags %x)",
- (void *)bufh, bufh->sb_flag);
-
- bioerror(bp, ENXIO);
- goto done;
- }
-
- fba_req = FBA_LEN(bp->b_bcount);
- if (fba_req + bp->b_lblkno > (diskaddr_t)svp->sv_nblocks)
- fba_req = (nsc_size_t)(svp->sv_nblocks - bp->b_lblkno);
-
- rw = (bp->b_flags & B_READ) ? NSC_READ : NSC_WRITE;
-
- bp_mapin(bp);
-
- bp->b_resid = bp->b_bcount;
- buf_addr = bp->b_un.b_addr;
- fba_off = 0;
-
- /*
- * fba_req - requested size of transfer in FBAs after
- * truncation to device extent, and allowing for
- * possible non-FBA bounded final chunk.
- * fba_off - offset of start of chunk from start of bp in FBAs.
- * fba_len - size of this chunk in FBAs.
- */
-
-loop:
- fba_len = min(fba_req, svp->sv_maxfbas);
- hndl = bufh;
-
- DTRACE_PROBE4(sv_dbg_allocb_start,
- sv_dev_t *, svp,
- uint64_t, (uint64_t)(bp->b_lblkno + fba_off),
- uint64_t, (uint64_t)fba_len,
- int, rw);
-
- rc = nsc_alloc_buf(svp->sv_fd, (nsc_off_t)(bp->b_lblkno + fba_off),
- fba_len, rw, &hndl);
-
- DTRACE_PROBE1(sv_dbg_allocb_end, sv_dev_t *, svp);
-
- if (rc > 0) {
- DTRACE_PROBE1(sv_lyr_strategy_err_alloc, struct buf *, bp);
- bioerror(bp, rc);
- if (hndl != bufh)
- (void) nsc_free_buf(hndl);
- hndl = NULL;
- goto done;
- }
-
- tocopy = min(FBA_SIZE(fba_len), bp->b_resid);
- v = hndl->sb_vec;
-
- if (rw == NSC_WRITE && FBA_OFF(tocopy) != 0) {
- /*
- * Not overwriting all of the last FBA, so read in the
- * old contents now before we overwrite it with the new
- * data.
- */
-
- DTRACE_PROBE2(sv_dbg_read_start, sv_dev_t *, svp,
- uint64_t, (uint64_t)(hndl->sb_pos + hndl->sb_len - 1));
-
- rc = nsc_read(hndl, (hndl->sb_pos + hndl->sb_len - 1), 1, 0);
- if (rc > 0) {
- bioerror(bp, rc);
- goto done;
- }
-
- DTRACE_PROBE1(sv_dbg_read_end, sv_dev_t *, svp);
- }
-
- DTRACE_PROBE1(sv_dbg_bcopy_start, sv_dev_t *, svp);
-
- while (tocopy > 0) {
- nbytes = min(tocopy, (nsc_size_t)v->sv_len);
-
- if (bp->b_flags & B_READ)
- (void) bcopy(v->sv_addr, buf_addr, nbytes);
- else
- (void) bcopy(buf_addr, v->sv_addr, nbytes);
-
- bp->b_resid -= nbytes;
- buf_addr += nbytes;
- tocopy -= nbytes;
- v++;
- }
-
- DTRACE_PROBE1(sv_dbg_bcopy_end, sv_dev_t *, svp);
-
- if ((bp->b_flags & B_READ) == 0) {
- DTRACE_PROBE3(sv_dbg_write_start, sv_dev_t *, svp,
- uint64_t, (uint64_t)hndl->sb_pos,
- uint64_t, (uint64_t)hndl->sb_len);
-
- rc = nsc_write(hndl, hndl->sb_pos, hndl->sb_len, 0);
-
- DTRACE_PROBE1(sv_dbg_write_end, sv_dev_t *, svp);
-
- if (rc > 0) {
- bioerror(bp, rc);
- goto done;
- }
- }
-
- /*
- * Adjust FBA offset and requested (ie. remaining) length,
- * loop if more data to transfer.
- */
-
- fba_off += fba_len;
- fba_req -= fba_len;
-
- if (fba_req > 0) {
- DTRACE_PROBE1(sv_dbg_freeb_start, sv_dev_t *, svp);
-
- rc = nsc_free_buf(hndl);
-
- DTRACE_PROBE1(sv_dbg_freeb_end, sv_dev_t *, svp);
-
- if (rc > 0) {
- DTRACE_PROBE1(sv_lyr_strategy_err_free,
- struct buf *, bp);
- bioerror(bp, rc);
- }
-
- hndl = NULL;
-
- if (rc <= 0)
- goto loop;
- }
-
-done:
- if (hndl != NULL) {
- DTRACE_PROBE1(sv_dbg_freeb_start, sv_dev_t *, svp);
-
- rc = nsc_free_buf(hndl);
-
- DTRACE_PROBE1(sv_dbg_freeb_end, sv_dev_t *, svp);
-
- if (rc > 0) {
- DTRACE_PROBE1(sv_lyr_strategy_err_free,
- struct buf *, bp);
- bioerror(bp, rc);
- }
-
- hndl = NULL;
- }
-
- if (bufh)
- (void) nsc_free_handle(bufh);
-
- DTRACE_PROBE1(sv_dbg_rlse_start, sv_dev_t *, svp);
-
- nsc_release(svp->sv_fd);
-
- DTRACE_PROBE1(sv_dbg_rlse_end, sv_dev_t *, svp);
-
-out:
- if (sv_debug > 5) {
- cmn_err(CE_CONT,
- "!_sv_lyr_strategy: bp %p, bufh %p, bp->b_error %d\n",
- (void *)bp, (void *)bufh, bp->b_error);
- }
-
- DTRACE_PROBE2(sv_lyr_strategy_end, struct buf *, bp, int, bp->b_error);
-
- rw_exit(&svp->sv_lock);
- biodone(bp);
-}
-
-
-static void
-sv_async_strategy(blind_t arg)
-{
- struct buf *bp = (struct buf *)arg;
- _sv_lyr_strategy(bp);
-}
-
-
-static int
-sv_lyr_strategy(struct buf *bp)
-{
- nsthread_t *tp;
- int nlive;
-
- /*
- * If B_ASYNC was part of the DDI we could use it as a hint to
- * not create a thread for synchronous i/o.
- */
- if (sv_dev_to_sv(bp->b_edev, NULL) == NULL) {
- /* not sv enabled - just pass through */
- DTRACE_PROBE1(sv_lyr_strategy_notsv, struct buf *, bp);
- _sv_lyr_strategy(bp);
- return (0);
- }
-
- if (sv_debug > 4) {
- cmn_err(CE_CONT, "!sv_lyr_strategy: nthread %d nlive %d\n",
- nst_nthread(sv_tset), nst_nlive(sv_tset));
- }
-
- /*
- * If there are only guard devices enabled there
- * won't be a threadset, so don't try and use it.
- */
- tp = NULL;
- if (sv_tset != NULL) {
- tp = nst_create(sv_tset, sv_async_strategy, (blind_t)bp, 0);
- }
-
- if (tp == NULL) {
- /*
- * out of threads, so fall back to synchronous io.
- */
- if (sv_debug > 0) {
- cmn_err(CE_CONT,
- "!sv_lyr_strategy: thread alloc failed\n");
- }
-
- DTRACE_PROBE1(sv_lyr_strategy_no_thread,
- struct buf *, bp);
-
- _sv_lyr_strategy(bp);
- sv_no_threads++;
- } else {
- nlive = nst_nlive(sv_tset);
- if (nlive > sv_max_nlive) {
- if (sv_debug > 0) {
- cmn_err(CE_CONT,
- "!sv_lyr_strategy: "
- "new max nlive %d (nthread %d)\n",
- nlive, nst_nthread(sv_tset));
- }
-
- sv_max_nlive = nlive;
- }
- }
-
- return (0);
-}
-
-/*
- * re-write the size of the current partition
- */
-static int
-sv_fix_dkiocgvtoc(const intptr_t arg, const int mode, sv_dev_t *svp)
-{
- size_t offset;
- int ilp32;
- int pnum;
- int rc;
-
- ilp32 = (ddi_model_convert_from((mode & FMODELS)) == DDI_MODEL_ILP32);
-
- rc = nskern_partition(svp->sv_dev, &pnum);
- if (rc != 0) {
- return (rc);
- }
-
- if (pnum < 0 || pnum >= V_NUMPAR) {
- cmn_err(CE_WARN,
- "!sv_gvtoc: unable to determine partition number "
- "for dev %lx", svp->sv_dev);
- return (EINVAL);
- }
-
- if (ilp32) {
- int32_t p_size;
-
-#ifdef _SunOS_5_6
- offset = offsetof(struct vtoc, v_part);
- offset += sizeof (struct partition) * pnum;
- offset += offsetof(struct partition, p_size);
-#else
- offset = offsetof(struct vtoc32, v_part);
- offset += sizeof (struct partition32) * pnum;
- offset += offsetof(struct partition32, p_size);
-#endif
-
- p_size = (int32_t)svp->sv_nblocks;
- if (p_size == 0) {
- if (sv_reserve(svp->sv_fd,
- NSC_MULTI|NSC_PCATCH) == 0) {
- p_size = (int32_t)svp->sv_nblocks;
- nsc_release(svp->sv_fd);
- } else {
- rc = EINTR;
- }
- }
-
- if ((rc == 0) && ddi_copyout(&p_size, (void *)(arg + offset),
- sizeof (p_size), mode) != 0) {
- rc = EFAULT;
- }
- } else {
- long p_size;
-
- offset = offsetof(struct vtoc, v_part);
- offset += sizeof (struct partition) * pnum;
- offset += offsetof(struct partition, p_size);
-
- p_size = (long)svp->sv_nblocks;
- if (p_size == 0) {
- if (sv_reserve(svp->sv_fd,
- NSC_MULTI|NSC_PCATCH) == 0) {
- p_size = (long)svp->sv_nblocks;
- nsc_release(svp->sv_fd);
- } else {
- rc = EINTR;
- }
- }
-
- if ((rc == 0) && ddi_copyout(&p_size, (void *)(arg + offset),
- sizeof (p_size), mode) != 0) {
- rc = EFAULT;
- }
- }
-
- return (rc);
-}
-
-
-#ifdef DKIOCPARTITION
-/*
- * re-write the size of the current partition
- *
- * arg is dk_efi_t.
- *
- * dk_efi_t->dki_data = (void *)(uintptr_t)efi.dki_data_64;
- *
- * dk_efi_t->dki_data --> efi_gpt_t (label header)
- * dk_efi_t->dki_data + 1 --> efi_gpe_t[] (array of partitions)
- *
- * efi_gpt_t->efi_gpt_PartitionEntryArrayCRC32 --> CRC32 of array of parts
- * efi_gpt_t->efi_gpt_HeaderCRC32 --> CRC32 of header itself
- *
- * This assumes that sizeof (efi_gpt_t) is the same as the size of a
- * logical block on the disk.
- *
- * Everything is little endian (i.e. disk format).
- */
-static int
-sv_fix_dkiocgetefi(const intptr_t arg, const int mode, sv_dev_t *svp)
-{
- dk_efi_t efi;
- efi_gpt_t gpt;
- efi_gpe_t *gpe = NULL;
- size_t sgpe;
- uint64_t p_size; /* virtual partition size from nsctl */
- uint32_t crc;
- int unparts; /* number of parts in user's array */
- int pnum;
- int rc;
-
- rc = nskern_partition(svp->sv_dev, &pnum);
- if (rc != 0) {
- return (rc);
- }
-
- if (pnum < 0) {
- cmn_err(CE_WARN,
- "!sv_efi: unable to determine partition number for dev %lx",
- svp->sv_dev);
- return (EINVAL);
- }
-
- if (ddi_copyin((void *)arg, &efi, sizeof (efi), mode)) {
- return (EFAULT);
- }
-
- efi.dki_data = (void *)(uintptr_t)efi.dki_data_64;
-
- if (efi.dki_length < sizeof (gpt) + sizeof (gpe)) {
- return (EINVAL);
- }
-
- if (ddi_copyin((void *)efi.dki_data, &gpt, sizeof (gpt), mode)) {
- rc = EFAULT;
- goto out;
- }
-
- if ((unparts = LE_32(gpt.efi_gpt_NumberOfPartitionEntries)) == 0)
- unparts = 1;
- else if (pnum >= unparts) {
- cmn_err(CE_WARN,
- "!sv_efi: partition# beyond end of user array (%d >= %d)",
- pnum, unparts);
- return (EINVAL);
- }
-
- sgpe = sizeof (*gpe) * unparts;
- gpe = kmem_alloc(sgpe, KM_SLEEP);
-
- if (ddi_copyin((void *)(efi.dki_data + 1), gpe, sgpe, mode)) {
- rc = EFAULT;
- goto out;
- }
-
- p_size = svp->sv_nblocks;
- if (p_size == 0) {
- if (sv_reserve(svp->sv_fd, NSC_MULTI|NSC_PCATCH) == 0) {
- p_size = (diskaddr_t)svp->sv_nblocks;
- nsc_release(svp->sv_fd);
- } else {
- rc = EINTR;
- }
- }
-
- gpe[pnum].efi_gpe_EndingLBA = LE_64(
- LE_64(gpe[pnum].efi_gpe_StartingLBA) + p_size - 1);
-
- gpt.efi_gpt_PartitionEntryArrayCRC32 = 0;
- CRC32(crc, gpe, sgpe, -1U, sv_crc32_table);
- gpt.efi_gpt_PartitionEntryArrayCRC32 = LE_32(~crc);
-
- gpt.efi_gpt_HeaderCRC32 = 0;
- CRC32(crc, &gpt, sizeof (gpt), -1U, sv_crc32_table);
- gpt.efi_gpt_HeaderCRC32 = LE_32(~crc);
-
- if ((rc == 0) && ddi_copyout(&gpt, efi.dki_data, sizeof (gpt), mode)) {
- rc = EFAULT;
- goto out;
- }
-
- if ((rc == 0) && ddi_copyout(gpe, efi.dki_data + 1, sgpe, mode)) {
- rc = EFAULT;
- goto out;
- }
-
-out:
- if (gpe) {
- kmem_free(gpe, sgpe);
- }
-
- return (rc);
-}
-
-
-/*
- * Re-write the size of the partition specified by p_partno
- *
- * Note that if a DKIOCPARTITION is issued to an fd opened against a
- * non-sv'd device, but p_partno requests the size for a different
- * device that is sv'd, this function will *not* be called as sv is
- * not interposed on the original device (the fd).
- *
- * It would not be easy to change this as we cannot get the partition
- * number for the non-sv'd device, so cannot compute the dev_t of the
- * (sv'd) p_partno device, and so cannot find out if it is sv'd or get
- * its size from nsctl.
- *
- * See also the "Bug 4755783" comment in sv_lyr_ioctl().
- */
-static int
-sv_fix_dkiocpartition(const intptr_t arg, const int mode, sv_dev_t *svp)
-{
- struct partition64 p64;
- sv_dev_t *nsvp = NULL;
- diskaddr_t p_size;
- minor_t nminor;
- int pnum, rc;
- dev_t ndev;
-
- rc = nskern_partition(svp->sv_dev, &pnum);
- if (rc != 0) {
- return (rc);
- }
-
- if (ddi_copyin((void *)arg, &p64, sizeof (p64), mode)) {
- return (EFAULT);
- }
-
- if (p64.p_partno != pnum) {
- /* switch to requested partition, not the current one */
- nminor = getminor(svp->sv_dev) + (p64.p_partno - pnum);
- ndev = makedevice(getmajor(svp->sv_dev), nminor);
- nsvp = sv_find_enabled(ndev, NULL);
- if (nsvp == NULL) {
- /* not sv device - just return */
- return (0);
- }
-
- svp = nsvp;
- }
-
- p_size = svp->sv_nblocks;
- if (p_size == 0) {
- if (sv_reserve(svp->sv_fd, NSC_MULTI|NSC_PCATCH) == 0) {
- p_size = (diskaddr_t)svp->sv_nblocks;
- nsc_release(svp->sv_fd);
- } else {
- rc = EINTR;
- }
- }
-
- if (nsvp != NULL) {
- rw_exit(&nsvp->sv_lock);
- }
-
- if ((rc == 0) && ddi_copyout(&p_size,
- (void *)(arg + offsetof(struct partition64, p_size)),
- sizeof (p_size), mode) != 0) {
- return (EFAULT);
- }
-
- return (rc);
-}
-#endif /* DKIOCPARTITION */
-
-
-static int
-sv_lyr_ioctl(const dev_t dev, const int cmd, const intptr_t arg,
- const int mode, cred_t *crp, int *rvalp)
-{
- sv_dev_t *svp;
- sv_maj_t *maj;
- int (*fn)();
- int rc = 0;
-
- maj = 0;
- fn = 0;
-
- /*
- * If sv_mod_status is 0 or SV_PREVENT_UNLOAD, then it will continue.
- * else it means it previously was SV_PREVENT_UNLOAD, and now it's
- * SV_ALLOW_UNLOAD, expecting the driver to eventually unload.
- *
- * SV_ALLOW_UNLOAD is final state, so no need to grab sv_mutex.
- */
- if (sv_mod_status == SV_ALLOW_UNLOAD) {
- return (EBUSY);
- }
-
- svp = sv_find_enabled(dev, &maj);
- if (svp != NULL) {
- if (nskernd_isdaemon()) {
- /*
- * This is nskernd which always needs to see
- * the underlying disk device accurately.
- *
- * So just pass the ioctl straight through
- * to the underlying driver as though the device
- * was not sv enabled.
- */
- DTRACE_PROBE2(sv_lyr_ioctl_nskernd, sv_dev_t *, svp,
- dev_t, dev);
-
- rw_exit(&svp->sv_lock);
- svp = NULL;
- } else {
- ASSERT(RW_READ_HELD(&svp->sv_lock));
- }
- }
-
- /*
- * We now have a locked and enabled SV device, or a non-SV device.
- */
-
- switch (cmd) {
- /*
- * DKIOCGVTOC, DKIOCSVTOC, DKIOCPARTITION, DKIOCGETEFI
- * and DKIOCSETEFI are intercepted and faked up as some
- * i/o providers emulate volumes of a different size to
- * the underlying volume.
- *
- * Setting the size by rewriting the vtoc is not permitted.
- */
-
- case DKIOCSVTOC:
-#ifdef DKIOCPARTITION
- case DKIOCSETEFI:
-#endif
- if (svp == NULL) {
- /* not intercepted -- allow ioctl through */
- break;
- }
-
- rw_exit(&svp->sv_lock);
-
- DTRACE_PROBE2(sv_lyr_ioctl_svtoc, dev_t, dev, int, EPERM);
-
- return (EPERM);
-
- default:
- break;
- }
-
- /*
- * Pass through the real ioctl command.
- */
-
- if (maj && (fn = maj->sm_ioctl) != 0) {
- if (!(maj->sm_flag & D_MP)) {
- UNSAFE_ENTER();
- rc = (*fn)(dev, cmd, arg, mode, crp, rvalp);
- UNSAFE_EXIT();
- } else {
- rc = (*fn)(dev, cmd, arg, mode, crp, rvalp);
- }
- } else {
- rc = ENODEV;
- }
-
- /*
- * Bug 4755783
- * Fix up the size of the current partition to allow
- * for the virtual volume to be a different size to the
- * physical volume (e.g. for II compact dependent shadows).
- *
- * Note that this only attempts to fix up the current partition
- * - the one that the ioctl was issued against. There could be
- * other sv'd partitions in the same vtoc, but we cannot tell
- * so we don't attempt to fix them up.
- */
-
- if (svp != NULL && rc == 0) {
- switch (cmd) {
- case DKIOCGVTOC:
- rc = sv_fix_dkiocgvtoc(arg, mode, svp);
- break;
-
-#ifdef DKIOCPARTITION
- case DKIOCGETEFI:
- rc = sv_fix_dkiocgetefi(arg, mode, svp);
- break;
-
- case DKIOCPARTITION:
- rc = sv_fix_dkiocpartition(arg, mode, svp);
- break;
-#endif /* DKIOCPARTITION */
- }
- }
-
- if (svp != NULL) {
- rw_exit(&svp->sv_lock);
- }
-
- return (rc);
-}
diff --git a/usr/src/uts/common/avs/ns/sv/sv.conf b/usr/src/uts/common/avs/ns/sv/sv.conf
deleted file mode 100644
index 75d6ba3295..0000000000
--- a/usr/src/uts/common/avs/ns/sv/sv.conf
+++ /dev/null
@@ -1,36 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-
-name="sv" parent="pseudo" instance=0;
-
-#
-# sv_threads
-#
-# The number of threads to pre-allocate when loading the sv kernel module.
-# The sv module will ensure that there is always at least one thread
-# allocated per enabled device.
-#
-# However, if lots of asynchronous (including filesystem) i/o is
-# anticipated increasing this value may improve performance.
-#
-sv_threads=32;
diff --git a/usr/src/uts/common/avs/ns/sv/sv.h b/usr/src/uts/common/avs/ns/sv/sv.h
deleted file mode 100644
index c84a2b5674..0000000000
--- a/usr/src/uts/common/avs/ns/sv/sv.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SV_H
-#define _SV_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*
- * Storage Volume Character and Block Driver (SV)
- * Public header file.
- * SPARC case 1998/036.
- * PSARC case 1999/023.
- */
-
-#define SV_MAXPATH NSC_MAXPATH
-#define SV_DEVICE "/dev/sv"
-
-
-/*
- * Ioctl structures
- */
-
-typedef struct sv_name_s {
- char svn_path[SV_MAXPATH]; /* path to underlying raw device */
- time_t svn_timestamp; /* timestamp of successful enable */
- int svn_nblocks; /* size of device */
- int svn_mode; /* NSC_DEVICE | NSC_CACHE */
-} sv_name_t;
-
-
-#ifdef _KERNEL
-
-typedef struct sv_name32_s {
- char svn_path[SV_MAXPATH]; /* path to underlying raw device */
- int32_t svn_timestamp; /* timestamp of successful enable */
- int32_t svn_nblocks; /* size of device */
- int32_t svn_mode; /* NSC_DEVICE | NSC_CACHE */
-} sv_name32_t;
-
-#endif /* _KERNEL */
-
-
-typedef struct sv_list_s {
- spcs_s_info_t svl_error; /* Error information */
- time_t svl_timestamp; /* time of successful {en,dis}able */
- int svl_count; /* Count of elements in svl_names */
- int svl_maxdevs; /* Max # of devices that can be used */
- sv_name_t *svl_names; /* pointer to names array */
-} sv_list_t;
-
-
-#ifdef _KERNEL
-
-typedef struct sv_list32_s {
- spcs_s_info32_t svl_error; /* Error information */
- int32_t svl_timestamp; /* time of successful {en,dis}able */
- int32_t svl_count; /* Count of elements in svl_names */
- int32_t svl_maxdevs; /* Max # of devices that can be used */
- uint32_t svl_names; /* pointer to names array */
-} sv_list32_t;
-
-#endif /* _KERNEL */
-
-
-typedef struct sv_conf_s {
- spcs_s_info_t svc_error; /* Error information */
- char svc_path[SV_MAXPATH]; /* path to underlying raw device */
- int svc_flag; /* NSC_DEVICE | NSC_CACHE */
- major_t svc_major; /* major_t of underlying raw device */
- minor_t svc_minor; /* minor_t of underlying raw device */
-} sv_conf_t;
-
-#ifdef _KERNEL
-
-typedef struct sv_conf32_s {
- spcs_s_info32_t svc_error; /* Error information */
- char svc_path[SV_MAXPATH]; /* path to underlying raw device */
- int32_t svc_flag; /* NSC_DEVICE | NSC_CACHE */
- major_t svc_major; /* major_t of underlying raw device */
- minor_t svc_minor; /* minor_t of underlying raw device */
-} sv_conf32_t;
-
-#endif /* _KERNEL */
-
-
-typedef struct sv_version_s {
- spcs_s_info_t svv_error; /* Error information */
- int svv_major_rev; /* Major revision */
- int svv_minor_rev; /* Minor revision */
- int svv_micro_rev; /* Micro revision */
- int svv_baseline_rev; /* Baseline revision */
-} sv_version_t;
-
-#ifdef _KERNEL
-
-typedef struct sv_version32_s {
- spcs_s_info32_t svv_error; /* Error information */
- int32_t svv_major_rev; /* Major revision */
- int32_t svv_minor_rev; /* Minor revision */
- int32_t svv_micro_rev; /* Micro revision */
- int32_t svv_baseline_rev; /* Baseline revision */
-} sv_version32_t;
-
-#endif /* _KERNEL */
-
-
-#ifdef _KERNEL
-
-/*
- * SV guard devices.
- */
-
-typedef struct sv_guard_s {
- int sg_magic; /* Magic # */
- int sg_version; /* Version # */
- char *sg_pathname; /* Pathname of device to guard */
- char *sg_module; /* Module name of client */
- int sg_kernel; /* Prevent user access if true */
- spcs_s_info_t sg_error; /* Error to be returned to client */
-} sv_guard_t;
-
-#define SV_SG_MAGIC 0x47554152
-#define SV_SG_VERSION 1
-
-#endif /* _KERNEL */
-
-
-/*
- * Ioctl numbers.
- */
-
-#define __SV__(x) (('S'<<16)|('V'<<8)|(x))
-
-#define SVIOC_ENABLE __SV__(1)
-#define SVIOC_DISABLE __SV__(2)
-#define SVIOC_LIST __SV__(3)
-#define SVIOC_VERSION __SV__(4)
-#define SVIOC_UNLOAD __SV__(5)
-
-/*
- * seconds to wait before unload, to drain lingering IOs.
- */
-#define SV_WAIT_UNLOAD 10
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SV_H */
diff --git a/usr/src/uts/common/avs/ns/sv/sv_efi.h b/usr/src/uts/common/avs/ns/sv/sv_efi.h
deleted file mode 100644
index 2e8d4fcda3..0000000000
--- a/usr/src/uts/common/avs/ns/sv/sv_efi.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SV_EFI_H
-#define _SV_EFI_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * This header hides the differences between the header files and
- * macros needed for EFI vtocs in the various Solaris releases.
- *
- * <sys/dkio.h> and <sys/vtoc.h> must have already been included.
- */
-
-#if !defined(_SYS_DKIO_H) || !defined(_SYS_VTOC_H)
-#error sys/dkio.h or sys/vtoc.h has not been included
-#endif
-
-#ifdef DS_DDICT
-#undef DKIOCPARTITION
-#endif
-
-#ifdef DKIOCPARTITION
-
-#include <sys/efi_partition.h>
-#include <sys/byteorder.h>
-
-/*
- * Solaris 10 has all the support we need in the header files,
- * just include <sys/crc32.h>.
- */
-#include <sys/crc32.h>
-
-#endif /* DKIOCPARTITION */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SV_EFI_H */
diff --git a/usr/src/uts/common/avs/ns/sv/sv_impl.h b/usr/src/uts/common/avs/ns/sv/sv_impl.h
deleted file mode 100644
index d177e8f0e3..0000000000
--- a/usr/src/uts/common/avs/ns/sv/sv_impl.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SV_IMPL_H
-#define _SV_IMPL_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Storage Volume Character and Block Driver (SV)
- * Private header file.
- */
-
-#if defined(_KERNEL)
-
-/*
- * Locking.
- * Define SV_SLEEP_LOCK to get full sleep lock semantics (ie. mutex not
- * held across calls to sdctl functions.
- *
- * #define SV_SLEEP_LOCK
- */
-
-
-/*
- * Misc defines, enums.
- */
-
-enum { SV_DISABLE = 0, SV_PENDING, SV_ENABLE };
-
-
-/*
- * Guard device clients
- */
-
-typedef int64_t sv_gid_t; /* bitmask */
-
-typedef struct sv_gclient_s {
- struct sv_gclient_s *sg_next; /* linked list */
- char *sg_name; /* name of client */
- sv_gid_t sg_id; /* id (bitmask) of client */
-} sv_gclient_t;
-
-
-/*
- * Hashing.
- *
- * SV_MAJOR_HASH_CNT & SV_MINOR_HASH_CNT should be prime.
- *
- * In a given system, there is likely to be one or two major devices in use.
- *
- * Examples are:
- * SD - Direct Attached Storage (SCSI-2/3)
- * SSD - SAN Direct Attached Storage FC SCSI-2/3
- * SVM - Solaris Volume Manager
- * VxVM - Veritas Volume Manager
- * Global - Sun Cluster Global Devices
- *
- * For a typical system, there may be a 10s to 100s of minor devices configured
- * per major device, but most are likely to be configured under a single major
- * number. SV_MINOR_HASH_CNT has been chosen to ensure that the hash chains are
- * not too long (one or two devices), for the worst case.
- */
-
-#define SV_MAJOR_HASH_CNT 3 /* # hash buckets per system */
-#define SV_MAJOR_HASH(min) ((min) % SV_MAJOR_HASH_CNT)
-
-#define SV_MINOR_HASH_CNT 37 /* # hash buckets per major */
-#define SV_MINOR_HASH(min) ((min) % SV_MINOR_HASH_CNT)
-
-/*
- * Per major device structure.
- *
- */
-
-typedef struct sv_maj_s {
- struct dev_ops *sm_dev_ops;
- int (*sm_strategy)();
- int (*sm_awrite)();
- int (*sm_write)();
- int (*sm_ioctl)();
- int (*sm_close)();
- int (*sm_aread)();
- int (*sm_read)();
- int (*sm_open)();
- major_t sm_major; /* Major device # */
- int sm_flag;
- volatile int sm_inuse;
- volatile int sm_seq;
- struct sv_dev_s *sm_hash[SV_MINOR_HASH_CNT]; /* Minor Hash Table */
- struct sv_maj_s *sm_next; /* Major Hash Chain */
-} sv_maj_t;
-
-/*
- * Per configured sv structure.
- */
-
-typedef struct sv_dev_s {
- struct sv_dev_s *sv_hash; /* Minor hash chain */
- krwlock_t sv_lock; /* mutual exclusion */
- kmutex_t sv_olock; /* mutual exclusion for otyp flags */
- dev_t sv_dev; /* underlying dev_t */
- nsc_fd_t *sv_fd; /* underlying fd */
- nsc_size_t sv_maxfbas; /* maxfbas accepted by I/O module */
- nsc_size_t sv_nblocks; /* size of device */
- int sv_state; /* state */
- int sv_flag; /* internal flags */
- sv_gid_t sv_gclients; /* bitmask of all guard clients */
- sv_gid_t sv_gkernel; /* bitmask of kernel guard clients */
- int sv_openlcnt; /* # of OTYP_LYR opens whilst failed */
- clock_t sv_timestamp; /* time of successful {en,dis}able */
- ldi_handle_t sv_lh; /* layered open handle */
- void *sv_pending; /* the thread setting SV_PENDING */
-} sv_dev_t;
-
-/*
- * private functions exported from nskern to sv.
- */
-extern int nskern_partition(dev_t, int *);
-extern int nskernd_isdaemon(void);
-
-#endif /* _KERNEL */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SV_IMPL_H */
diff --git a/usr/src/uts/common/avs/ns/unistat/Makefile b/usr/src/uts/common/avs/ns/unistat/Makefile
deleted file mode 100644
index 7423874404..0000000000
--- a/usr/src/uts/common/avs/ns/unistat/Makefile
+++ /dev/null
@@ -1,52 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# include global definitions
-include ../../../../../Makefile.master
-
-HDRS= spcs_s.h \
- spcs_s_k.h \
- spcs_s_impl.h \
- spcs_s_u.h
-
-ROOTDIR= $(ROOT)/usr/include/sys/unistat
-ROOTDIRS= $(ROOTDIR)
-
-ROOTHDRS= $(HDRS:%=$(ROOTDIRS)/%)
-
-# install rules
-$(ROOTDIRS)/%: %
- $(INS.file)
-
-CHECKHDRS= $(HDRS:%.h=%.check)
-
-.KEEP_STATE:
-
-.PARALLEL: $(CHECKHDRS)
-
-install_h: $(ROOTDIRS) $(ROOTHDRS)
-
-$(ROOTDIRS):
- $(INS.dir)
-
-check: $(CHECKHDRS)
diff --git a/usr/src/uts/common/avs/ns/unistat/spcs_s.h b/usr/src/uts/common/avs/ns/unistat/spcs_s.h
deleted file mode 100644
index bac1383d90..0000000000
--- a/usr/src/uts/common/avs/ns/unistat/spcs_s.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SPCS_S_H
-#define _SPCS_S_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * SPCS Uniform status handling public definitions
- * @author Soper
- * @version PROTOTYPE
- */
-
-
-
-
-/*
- * Function returned normally, no status info available (== 0)
- */
-#define SPCS_S_OK 0
-
-/*
- * Function returned abnormally, status info available (== -1)
- */
-#define SPCS_S_ERROR -1
-
-/*
- * The maximum status line character array length (== 1024)
- * @see spcs_s_string
- */
-#define SPCS_S_MAXLINE 1024
-
-/*
- * The maximum number of "%s" format descriptors in status message
- * text and data parameters that can be passed along with status
- * @see spcs_s_string
- */
-#define SPCS_S_MAXSUPP 8
-
-/*
- * The opaque status information type
- */
-typedef uintptr_t spcs_s_info_t;
-
-/*
- * The status information type as a 32 bit entity for model conversions
- */
-typedef uint32_t spcs_s_info32_t;
-
-/*
- * The type of bytestream data (see spcs_s_add_bytestream() )
- */
-typedef uchar_t *spcs_s_bytestream_ptr_t;
-
-/*
- * The type of a status code
- */
-typedef int spcs_s_status_t;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SPCS_S_H */
diff --git a/usr/src/uts/common/avs/ns/unistat/spcs_s_impl.h b/usr/src/uts/common/avs/ns/unistat/spcs_s_impl.h
deleted file mode 100644
index a4e4b965a0..0000000000
--- a/usr/src/uts/common/avs/ns/unistat/spcs_s_impl.h
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SPCS_S_IMPL_H
-#define _SPCS_S_IMPL_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * The SPCS Unistat private implementation definitions
- *
- * Only modules spcs_s_u.c and spcs_s_k.c should be using this
- */
-
-/*
- * For Unistat, here are the definitions of the major and minor revisions:
- *
- * Bump major revision and zero minor revision if: Any change made to
- * spcs_s_pinfo_t in terms of size, changed fields, etc, or any user
- * functional change to spcs_s.h definitions that is not backwards
- * compatible.
- *
- * Bump minor revision if: Any backwards compatible change to
- * functionality but with no impact on interoperability between kernel and
- * user level Unistat code having differing minor revs.
- *
- */
-
-#define SPCS_S_MAJOR_REV 1 /* Unistat major revision */
-#define SPCS_S_MINOR_REV 1 /* Unistat minor revision */
-/*
- * This is the format of a unistat status code. It must overlay
- * an int.
- */
-#if defined(__sparc)
-typedef struct {
- /*
- * If this flag is set the last supplemental item in idata is expected
- * to be of type SU_BYTESTREAM and offset is a tdata index.
- */
- unsigned char bytestream: 1;
- /*
- * count of items of supporting information references in idata
- * to accompany this error status code spcs.h define SPCS_S_MAXSUPP
- * must be 2 raised to the bit size of this field. Also don't forget
- * to update the sprintf in spcs_s_string.
- */
- unsigned char reserved: 4; /* reserved for future expansion */
- unsigned char sup_count: 3;
- unsigned char module: 8; /* module code (see below) */
- unsigned short code: 16; /* status code number (>0) */
-} spcs_s_code_t;
-#elif defined(__i386) || (__amd64)
-typedef struct {
- /*
- * count of items of supporting information references in idata
- * to accompany this error status code spcs.h define SPCS_S_MAXSUPP
- * must be 2 raised to the bit size of this field. Also don't forget
- * to update the sprintf in spcs_s_string.
- */
- unsigned short code: 16; /* status code number (>0) */
- unsigned char module: 8; /* module code (see below) */
- unsigned char sup_count: 3;
- unsigned char reserved: 4; /* reserved for future expansion */
- /*
- * If this flag is set the last supplemental item in idata is expected
- * to be of type SU_BYTESTREAM and offset is a tdata index.
- */
- unsigned char bytestream: 1;
-} spcs_s_code_t;
-#else
-#error "instruction set architecture error"
-#endif
-
-/*
- * The types of supplemental data references
- */
-
-typedef enum {SU_STRING, /* character string reference */
- SU_BYTESTREAM, /* bytestream data reference */
- SU_RES2,
- SU_RES3} suenum;
-/*
- * Supplemental data references. These follow status codes that have
- * nonzero sup_count fields. The supplemental data references can
- * currently be either a string reference or a bytestream data reference.
- * In both cases the reference simply contains an offset into the
- * sdata array (string) or tdata array (bytestream). This struct must be
- * the size of an int.
- */
-
-#if defined(__sparc)
-typedef struct {
- suenum type: 3; /* the supplemental data type */
- unsigned short reserved: 13; /* unused, reserved */
- unsigned short offset: 16; /* the sudata array offset of the */
- /* start of the supplemental data */
- /* or the tdata array offset for */
- /* bytestream data */
-} spcs_s_sudata_t;
-#elif defined(__i386) || (__amd64)
-typedef struct {
- unsigned short offset: 16; /* the sudata array offset of the */
- /* start of the supplemental data */
- /* or the tdata array offset for */
- /* bytestream data */
- unsigned short reserved: 13; /* unused, reserved */
- suenum type: 3; /* the supplemental data type */
-} spcs_s_sudata_t;
-#else
-#error "instruction set architecture error"
-#endif
-
-/*
- * Although bytestream data pointers are only used in the kernel layer
- * and are converted to offsets prior to unistat data being made available
- * to userspace (i.e. this never comes back via an ioctl), it is critical
- * to keep the unistat data structure spcs_s_pinfo_t a constant size
- * whether or not we're using LP64 or a 32 bit model. So we put the
- * pointer in a union with a long long so it is fixed at 64 bits in size.
- *
- * Prior to being transported through a pipe, unistat data containing
- * tdata items (see below) must have its pointers eliminated. The pointers
- * are simply nulled out and the actual bytestream data is sent out the
- * pipe following the spcs_s_pinfo_t in the same order as its references
- * in the sequential tdata elements.
- */
-
-typedef union {
- uchar_t *data; /* the pointer to the bytestream data */
- long long _fix_the_size;
-} _fixed_char_pointer_t;
-
-/*
- * The bytestream data descriptor in a tdata array element
- */
-
-typedef struct {
- uint32_t size; /* byte size of the bytestream data */
- _fixed_char_pointer_t u_p; /* union containing pointer inside */
- /* fixed length field */
-} spcs_s_tdesc_t;
-
-/*
- * All the types that can occupy an idata array element.
- */
-
-typedef union {
- spcs_s_status_t s; /* as the public status type */
- spcs_s_code_t f; /* as the internal status type */
- spcs_s_sudata_t su; /* the supplemental data reference type */
- int i; /* as integer: TEMPORARY */
-} spcs_s_udata_t;
-
-/*
- * The number of idata array elements. This is the upper bound for the
- * total status codes and supplemental data reference items that can be
- * held by unistat at one time. It is IMPORTANT that this array be large
- * enough to hold all the status and references for the worst case path
- * through core software. This is currently trivial to do by inspection
- * of the ioctl service code. However once unistat usage is deployed to
- * the underlying layers of core software below the ioctl service call
- * layer it may require special tools to validate this.
- */
-
-#define SPCS_S_IDSIZE 16 /* size of idata array */
-/*
- * The number of sdata array elements. This is the upper bound for the
- * total characters of string data added to the unistat structure as
- * supplemental info. Same cautions as for SPCS_S_IDSIZE.
- */
-
-#define SPCS_S_SDSIZE 512 /* size of sdata array */
-/*
- * The number of tdata array elements. This is the upper bound for the
- * total bytestream data descriptors that can be held by unistat at one
- * time. Same cautions as for SPCS_S_IDSIZE.
- */
-
-#define SPCS_S_TDSIZE 2 /* size of tdata array */
-
-/*
- * The Unistat private data structure. This is pointed to by the
- * public opaque pointer spcs_s_info_t and holds all the status codes
- * and supplemental data references. String data is also stored here
- * but the body of bytestream data is stored elsewhere (see below).
- *
- * If there is real concern about the overhead of ioctl copyouts they
- * could be optimized such that only the scalars and the "used" elements
- * of the idata, sdata and tdata arrays are moved. If this is done it is
- * recommended that the scalars (i.e. major through spare) be moved into
- * a structure to cut down on the chance of a coding error with manual
- * size arithmetic.
- *
- * The major and minor revs are currently supperfulous since unistat and
- * all of its clients are contained within the same private consolidation.
- * There is an assertion to BLOW UP if mismatched major revisions are
- * detected between the kernel and user layers. If the consolidation
- * policies of core software are relaxed in the future the assertion must
- * be replaced by code designed to do something intelligent if possible.
- *
- */
-
-#pragma pack()
-typedef struct {
- /* The next two fields must stay shorts and */
- /* stay at the front and in this order */
- /* "forever" */
- short major; /* Major unistat revision */
- short minor; /* Minor unistat revision */
- /* this define should obviously never change */
-#define SPCS_S_REVSIZE (sizeof (short) + sizeof (short))
- short icount; /* Number of items currently stored in idata */
- /* and the "next" index to store a new item */
- /* into */
- short scount; /* Number of items currently stored in sdata */
- /* and the "next" index to store a new item */
- /* into */
- short tcount; /* Number of items currently stored in tdata */
- /* and the "next" index to store a new item */
- /* into */
- short spare; /* Unused, reserved */
- spcs_s_udata_t idata[SPCS_S_IDSIZE]; /* the status info and supp refs */
- char sdata[SPCS_S_SDSIZE]; /* the supplemental string data pool. */
- /* the supplemental bytestream data pool. */
- spcs_s_tdesc_t tdata[SPCS_S_TDSIZE];
-} spcs_s_pinfo_t;
-
-/*
- * Module codes. These can be in any order except that Solaris MUST BE
- * FIRST.
- */
-
-enum {SPCS_M_Solaris, /* Solaris module */
- SPCS_M_SPCS, /* SPCS "module" (for codes that apply across */
- /* all controller modules */
- SPCS_M_DSW, /* InstantImage Module */
- SPCS_M_SV, /* Storage Volume Module */
- SPCS_M_RDC, /* Remote Dual Copy Module */
- SPCS_M_SDBC, /* Storage Device Block Cache Module */
- SPCS_M_STE, /* SCSI Target Emulation Module */
- SPCS_M_SDCTL, /* Storage Device Control Module */
- SPCS_M_MC, /* Memory Channel Module */
- SPCS_M_SIMCKD, /* CKD Simulation (SIMCKD) Module */
- SPCS_M_NVM}; /* Non-Volatile Memory Module */
-
-#define SPCS_M_MAX SPCS_M_NVM /* Highest defined module code */
-
-/*
- * The SPCS general status values
- */
-
-/* the module name spellings */
-
-#define SPCS_M_NSOL "SOLARIS"
-#define SPCS_M_NSPCS "SPCS"
-#define SPCS_M_NDSW "II"
-#define SPCS_M_NSV "SV"
-#define SPCS_M_NRDC "SNDR"
-#define SPCS_M_NSDBC "SDBC"
-#define SPCS_M_NSTE "STE"
-#define SPCS_M_NSDCTL "NSCTL"
-#define SPCS_M_NMC "MC"
-#define SPCS_M_NSIM "SIMCKD"
-#define SPCS_M_NNVM "NVM"
-
-/* limits */
-
-#define SPCS_S_MAXKEY 256 /* max msg key length */
-#define SPCS_S_MAXTEXT SPCS_S_MAXLINE /* max msg text length */
-#define SPCS_S_MAXSIG 32 /* max format data signature length */
-#define SPCS_S_MAXPRE 32 /* max module prefix length */
-#define SPCS_S_MAXMODNAME 16 /* max module name length */
-
-/* the module names in a lookup array */
-#if !defined(_KERNEL)
-static char *module_names[] = {SPCS_M_NSOL, SPCS_M_NSPCS, SPCS_M_NDSW,
- SPCS_M_NSV, SPCS_M_NRDC, SPCS_M_NSDBC, SPCS_M_NSTE, SPCS_M_NSDCTL,
- SPCS_M_NMC, SPCS_M_NSIM, SPCS_M_NNVM, NULL};
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SPCS_S_IMPL_H */
diff --git a/usr/src/uts/common/avs/ns/unistat/spcs_s_k.c b/usr/src/uts/common/avs/ns/unistat/spcs_s_k.c
deleted file mode 100644
index 7ee4a93d98..0000000000
--- a/usr/src/uts/common/avs/ns/unistat/spcs_s_k.c
+++ /dev/null
@@ -1,888 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * The SPCS status support kernel utilities
- * See header spcs_s_k.h for functional spec
- */
-#include <sys/types.h>
-#include <sys/ksynch.h>
-#include <sys/kmem.h>
-#include <sys/errno.h>
-#include <sys/cmn_err.h>
-#include <sys/ddi.h>
-#include <sys/sunddi.h>
-#include <sys/varargs.h>
-
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_k.h>
-#include <sys/unistat/spcs_s_impl.h>
-#include <sys/unistat/spcs_errors.h>
-
-#ifdef DS_DDICT
-#include <sys/nsctl/contract.h>
-#endif
-/*
- * Debug support to allow testing in userspace
- */
-
-#if UNISTAT_ASSERTIONS
-#define _CELEVEL CE_PANIC
-#else
-#define _CELEVEL CE_WARN
-#endif
-
-
-/*
- * Unistat state data
- */
-
-/*
- * This flag is made nonzero to indicate the bytestream transport mechanism
- * is initalized.
- */
-
-static int bytestream_transport_initialized = 0;
-
-/*
- * Common code for status init
- *
- */
-
-static void init_status(spcs_s_pinfo_t *p)
-{
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!init_status entry");
-#endif
- p->major = SPCS_S_MAJOR_REV;
- p->minor = SPCS_S_MINOR_REV;
- p->icount = 0;
- p->scount = 0;
- p->tcount = 0;
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!init_status exit");
-#endif
-}
-
-/*
- * Create and initialize local ioctl status.
- *
- */
-
-spcs_s_info_t
-spcs_s_kcreate()
-{
- spcs_s_pinfo_t *kstatus;
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!spcs_s_kcreate entry");
-#endif
- kstatus = (spcs_s_pinfo_t *)
- kmem_alloc(sizeof (spcs_s_pinfo_t), KM_SLEEP);
-
- if (kstatus)
- init_status(kstatus);
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!spcs_s_kcreate exit");
-#endif
- return ((spcs_s_info_t)kstatus);
-}
-
-/*
- * Initialize existing ioctl status.
- */
-
-void
-spcs_s_kinit(spcs_s_info_t kstatus)
-{
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!spcs_s_kinit called");
-#endif
- init_status((spcs_s_pinfo_t *)kstatus);
-}
-
-/*
- * Release (free) ioctl status storage.
- * BUG: this should take an spcs_s_info_t** or else the userspace
- * version shoud just take a pointer. Could hopefully fix up Simon and
- * Phil's code without too much trouble to fix this. Being inconsistent
- * over the long term is bad.
- */
-
-void
-spcs_s_kfree(spcs_s_info_t kstatus)
-{
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!spcs_s_kfree entry");
-#endif
- kmem_free((void *)kstatus, sizeof (spcs_s_pinfo_t));
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!spcs_s_kfree exit");
-#endif
-}
-
-/*
- * Delete one error code and its supplemental info
- * The "oldest" error code is removed.
- * The assumption is that there is at least one status code present.
- * Neither sdata nor tdata space is reclaimed
- */
-
-static void
-spcs_delete(spcs_s_pinfo_t *p)
-{
- int i;
- int d;
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!spcs_s_delete entry");
-#endif
- d = p->idata[0].f.sup_count + 1;
-
- for (i = 0; i < (p->icount - d); i++)
- p->idata[i] = p->idata[i+d];
- p->icount -= d;
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!spcs_s_delete exit");
-#endif
-}
-
-/*
- * Common code for adding a status code
- * Return 1 if overflow detected, 0 if enough space for code and support
- * info.
- */
-
-static boolean_t
-add_code(spcs_s_pinfo_t *p, spcs_s_status_t stcode)
-{
- spcs_s_udata_t c;
- c.s = stcode;
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!add_code entry");
-#endif
-
- if ((p->icount + c.f.sup_count + 1) > SPCS_S_IDSIZE) {
- if (p->icount == SPCS_S_IDSIZE)
- spcs_delete(p);
- p->idata[p->icount++].s = SPCS_EOVERFLOW;
-
- cmn_err(_CELEVEL, "!SPCS Unistat: not enough room in idata!");
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!add_code exit 1");
-#endif
-
- return (B_TRUE);
- } else
- p->idata[p->icount++] = c;
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!add_code exit 2");
-#endif
- return (B_FALSE);
-}
-
-/*
- * Common code for adding a string as supplemental info.
- * Add_code is assumed to have been called already to ensure enough space
- * idata. The string is copied into the sdata array and the index to the
- * first character is put in idata along with the datatype indicator.
- */
-
-static void
-add_item(spcs_s_pinfo_t *p, char *string)
-{
- int len;
- char *nullstr = "XXXXXXXX";
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!add_item entry");
-#endif
- len = strlen(string);
-
-/*
- * The following HACK is for RDC which is somewhat careless about
- * it's usage of strings. It does not make sense to panic the machine
- * because we botched an informational message. Print something
- * usefull so we can go back and fix it.
- * This can be removed when everyone has played by the correct unistat rules
- */
- if (len == 0) {
- string = nullstr;
- len = strlen(nullstr);
- }
- if ((len + 1) > (SPCS_S_SDSIZE - p->scount))
- cmn_err(_CELEVEL,
- "!SPCS: Unistat sdata array too small: needed %d bytes",
- len + 1);
-
- p->idata[p->icount].su.type = SU_STRING;
- p->idata[p->icount++].su.offset = p->scount;
- (void) strcpy(&(p->sdata[p->scount]), string);
- p->scount += len + 1;
-}
-
-/*
- * Check the rev level of the userspace status structure
- * and spew some chunks if it doesn't match the kernel's unistat rev.
- * Some day something more intelligent should happen to try to provide
- * backward compatiblity with some mismatches (see the impl header file).
- * Returns true if the revisions are compatible, false otherwise.
- */
-
-static boolean_t
-check_revision(spcs_s_info_t ustatus)
-{
- char *m;
- char buf[SPCS_S_REVSIZE];
- spcs_s_pinfo_t *p = (spcs_s_pinfo_t *)buf;
- int mode = 0;
-
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!check_revision entry");
-#endif
-
- m =
- "!SPCS Unistat failure (packaging error): data struct mismatch";
- (void) ddi_copyin((void *) ustatus, (void *) p, SPCS_S_REVSIZE, mode);
-
- if ((p->major == SPCS_S_MAJOR_REV) && (p->minor == SPCS_S_MINOR_REV)) {
- /* Both match */
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!check_revision exit 1");
-#endif
- return (B_TRUE);
- }
-
- /*
- * We have a major and/or minor version mismatch.
- * Deal with each case individually.
- */
-
-#ifdef DEBUG
- cmn_err(CE_WARN, "!unistat kernel v%d.%d, user v%d.%d\n",
- SPCS_S_MAJOR_REV, SPCS_S_MINOR_REV, (int)p->major, (int)p->minor);
-#endif
-
- if (p->major > SPCS_S_MAJOR_REV) {
- /*
- * couldn't guess what to do if the userspace version is ahead
- * of the kernel version, so issue a warning
- */
- cmn_err(CE_WARN, m);
- } else if (p->major < SPCS_S_MAJOR_REV) {
- /*
- * kernel's major version is ahead of userspace version: do
- * something extremely clever here some day instead of the
- * warning
- */
- cmn_err(CE_WARN, m);
- } else if (p->minor < SPCS_S_MINOR_REV) {
-
- /*
- * kernel's minor version is ahead of userspace version: do
- * something clever here some day instead of the warning
- */
-
- cmn_err(CE_WARN, m);
- } else {
- /*
- * couldn't guess what to do if the userspace version is ahead
- * of the kernel's minor version, so issue a warning
- */
-
- cmn_err(CE_WARN, m);
- }
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!check_revision exit 2");
-#endif
- return (B_FALSE);
-}
-
-/*
- * Add a code and optional support information to status
- *
- * The support info can only consist of char pointers.
- *
- * Varargs doesn't provide a means of detecting too few supplemental
- * values...
- */
-
-void
-spcs_s_add(spcs_s_info_t kstatus, spcs_s_status_t stcode, ...)
-{
- va_list ap;
- spcs_s_udata_t c;
- spcs_s_pinfo_t *p;
- char *sp;
-
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!cspcs_s_add entry");
-#endif
- p = (spcs_s_pinfo_t *)kstatus;
- c.s = stcode;
-
- if (add_code(p, stcode) == B_TRUE) {
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!cspcs_s_add exit 1");
-#endif
- return;
- }
-
- va_start(ap, stcode);
-
- while (c.f.sup_count--) {
- sp = va_arg(ap, caddr_t);
- if (sp != (char *)NULL)
- add_item(p, sp);
- }
-
- va_end(ap);
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!cspcs_s_add exit 2");
-#endif
-}
-
-/*
- * Common code to copy status to userspace
- *
- * Only "used" data is copied to minimize overhead.
- */
-
-static void
-scopyout(spcs_s_pinfo_t *kstatus, spcs_s_pinfo_t *ustatus)
-{
- int mode = 0;
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!scopyout entry");
-#endif
-
- /*
- * If tdata is in use, blow up: asynch data is not intended for ioctls.
- * How would we ship it back? (the user hasn't given us any place to
- * put it!)
- */
-
- if (kstatus->tcount)
- cmn_err(_CELEVEL, "!SPCS: Unistat async data in ioctl status!");
-
- /*
- * Gently, Bentley
- * Have to copy all the header stuff even though there is no need for
- * some items like the revisions. This is unavoidable without making
- * the structure more complex or guessing about alignment and the true
- * size of the part of the structure sitting ahead of the {i,s,t}data
- * arrays.
- */
-
- (void) ddi_copyout((void *) kstatus, (void *) ustatus,
- sizeof (spcs_s_pinfo_t) - (sizeof (kstatus->idata) +
- sizeof (kstatus->sdata) + sizeof (kstatus->tdata)), mode);
- (void) ddi_copyout((void *)kstatus->idata, (void *) ustatus->idata,
- (kstatus->icount * sizeof (kstatus->idata[0])), mode);
- (void) ddi_copyout((void *)kstatus->sdata, (void *) ustatus->sdata,
- (kstatus->scount * sizeof (kstatus->sdata[0])), mode);
- (void) ddi_copyout((void *)kstatus->tdata, (void *) ustatus->tdata,
- (kstatus->tcount * sizeof (kstatus->tdata[0])), mode);
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!scopyout exit");
-#endif
-}
-
-/*
- * Copy the ioctl status info to userspace
- */
-
-void
-spcs_s_copyout(spcs_s_info_t *kstatus_a, spcs_s_info_t ustatus)
-{
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!spcs_s_copyout entry");
-#endif
- if (check_revision(ustatus) == B_TRUE)
- scopyout((spcs_s_pinfo_t *)*kstatus_a,
- (spcs_s_pinfo_t *)ustatus);
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!spcs_s_copyout exit");
-#endif
-}
-
-
-/*
- * Copy the ioctl status info to userspace
- * Free the status info storage.
- */
-
-void
-spcs_s_copyoutf(spcs_s_info_t *kstatus_a, spcs_s_info_t ustatus)
-{
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!spcs_s_copyoutf entry");
-#endif
- if (check_revision(ustatus) == B_TRUE)
- scopyout((spcs_s_pinfo_t *)*kstatus_a,
- (spcs_s_pinfo_t *)ustatus);
- spcs_s_kfree(*kstatus_a);
- *kstatus_a = NULL;
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!spcs_s_copyoutf exit");
-#endif
-}
-
-/*
- * Return the oldest status code from the status info or SPCS_S_OK if
- * there is none.
- */
-
-spcs_s_status_t
-spcs_s_oldest_status(spcs_s_info_t kstatus)
-{
- spcs_s_pinfo_t *p;
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!spcs_s_oldest_status entry");
-#endif
- p = (spcs_s_pinfo_t *)kstatus;
-
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!spcs_s_oldest_status exit");
-#endif
- return (p->icount ? p->idata[0].s : SPCS_S_OK);
-}
-
-/*
- * Return the idata index of the last status code in the array (i.e.
- * the "youngest" code present). The assumption is that the caller has
- * checked to see that pcount is nonzero.
- */
-
-static int
-last_code_idx(spcs_s_pinfo_t *p)
-{
- int last = 0;
- int idx = 0;
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!last_code_idx entry");
-#endif
-
- while (idx < p->icount) {
- last = idx;
- idx += p->idata[idx].f.sup_count + 1;
- }
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!last_code_idx exit");
-#endif
- return (last);
-}
-
-/*
- * Return the youngest status code form the status info or SPCS_S_OK if
- * there is none.
- */
-
-spcs_s_status_t
-spcs_s_youngest_status(spcs_s_info_t kstatus)
-{
- spcs_s_pinfo_t *p;
- spcs_s_status_t temp;
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!spcs_s_youngest_status entry");
-#endif
- p = (spcs_s_pinfo_t *)kstatus;
-
- if (p->icount)
- temp = p->idata[last_code_idx(p)].s;
- else
- temp = SPCS_S_OK;
-
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!spcs_s_youngest_status exit");
-#endif
- return (temp);
-}
-
-/*
- * Insert a new status code or NULL if there is none.
- * Copy the status info to userspace.
- * return a value to use as an return value (e.g. ioctl return).
- */
-
-spcs_s_status_t
-spcs_s_ocopyout(spcs_s_info_t *kstatus_a,
- spcs_s_info_t ustatus, spcs_s_status_t stcode, ...)
-{
- spcs_s_udata_t ret;
- va_list ap;
- spcs_s_udata_t c;
- spcs_s_pinfo_t *p;
- char *sp;
-
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!spcs_s_ocopyout entry");
-#endif
- p = (spcs_s_pinfo_t *)*kstatus_a;
- c.s = stcode;
-
- if (check_revision(ustatus) == B_FALSE)
- ret.s = EINVAL;
- else {
- if (stcode) {
- if (add_code(p, stcode) == B_FALSE) {
- va_start(ap, stcode);
-
- while (c.f.sup_count--) {
- sp = va_arg(ap, caddr_t);
- if (sp != (char *)NULL)
- add_item(p, sp);
- }
-
- va_end(ap);
- }
- }
- ret.s = p->icount ? p->idata[last_code_idx(p)].s: SPCS_S_OK;
- scopyout(p, (spcs_s_pinfo_t *)ustatus);
- }
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!spcs_s_ocopyout exit");
-#endif
- return (ret.s);
-}
-
-
-/*
- * Insert a new status code or NULL if there is none.
- * Copy the status info to userspace.
- * Free the kernel status info storage
- * return a value to use as an operatiion return value (e.g. ioctl return)
- */
-
-spcs_s_status_t
-spcs_s_ocopyoutf(spcs_s_info_t *kstatus_a,
- spcs_s_info_t ustatus, spcs_s_status_t stcode, ...)
-{
- spcs_s_udata_t ret;
- va_list ap;
- spcs_s_udata_t c;
- spcs_s_pinfo_t *p;
- char *sp;
-
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!spcs_s_ocopyoutf entry");
-#endif
- p = *(spcs_s_pinfo_t **)kstatus_a;
- c.s = stcode;
-
- if (check_revision(ustatus) == B_FALSE) {
- ret.s = EINVAL;
- } else {
- if (stcode) {
- if (add_code(p, stcode) == B_FALSE) {
- va_start(ap, stcode);
-
- while (c.f.sup_count--) {
- sp = va_arg(ap, caddr_t);
- if (sp != (char *)NULL)
- add_item(p, sp);
- }
-
- va_end(ap);
- }
- }
-
- ret.s = p->icount ? p->idata[last_code_idx(p)].s: SPCS_S_OK;
- scopyout(p, (spcs_s_pinfo_t *)ustatus);
- }
- spcs_s_kfree((spcs_s_info_t)p);
- *kstatus_a = NULL;
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!spcs_s_ocopyoutf exit");
-#endif
- return (ret.s);
-}
-
-/*
- * Return true if a status code is a Solaris error code
- */
-
-boolean_t
-spcs_s_is_solaris(spcs_s_status_t error)
-{
- spcs_s_udata_t c;
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!spcs_s_is_solaris called");
-#endif
- c.s = error;
- return (c.f.module == 0 ? B_TRUE : B_FALSE);
-}
-
-/*
- * Edit a value into a numeric string
- */
-
-char
-*spcs_s_inttostring(int val, char *buf, int buflen, int hex)
-{
- char tempbuf[20];
-
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!spcs_s_inttostring entry 0x%x", val);
-#endif
- if (buflen) {
- if (hex)
- (void) sprintf(tempbuf, "0x%0X", val);
- else
- (void) sprintf(tempbuf, "%d", val);
- if (strlen(tempbuf) < (size_t)buflen)
- (void) strcpy(buf, tempbuf);
- else
- (void) strcpy(buf, "***");
- } else {
- (void) strcpy(buf, "***");
- }
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!spcs_s_inttostring exit: %s", buf);
-#endif
- return (buf);
-}
-
-/*
- * Initialize the bytestream mechanism.
- * This is a prototype. Specification TBD. Not in 10/22 commitment
- */
-
-int
-spcs_s_start_bytestream()
-{
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!spcs_s_start_bytestream called");
-#endif
- bytestream_transport_initialized = 1;
- return (SPCS_S_OK);
-}
-
-/*
- * Stop (shut off) the bytestream mechanism.
- *
- * This is a prototype. Specification TBD. Not in 10/22 commitment
- */
-
-int
-spcs_s_stop_bytestream()
-{
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!spcs_s_stop_bytestream called");
-#endif
- bytestream_transport_initialized = 0;
- return (SPCS_S_OK);
-}
-
-/*
- * Add a status code and the address and length of arbitrary binary
- * data to be held (possibly with other status) for later transmission to
- * userspace via a pipe facility (i.e. NOT via ioctl return). This is a
- * means of getting arbitrary information with or without other status
- * info shipped out as an alternative to cmn_err and/or trace file
- * mechanisms.
- * @param kstatus The status info pointer
- * @param stcode The status code to annotate the data
- * @param address The starting address of the data
- * @param length The byte length of the data
- * This is a prototype. Specification TBD. Not in the 10/22/98 unistat
- * commitment
- */
-
-void
-spcs_s_add_bytestream(spcs_s_info_t kstatus, spcs_s_status_t stcode,
- spcs_s_bytestream_ptr_t data, int size)
-{
- spcs_s_pinfo_t *p;
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!spcs_s_add_bytestream entry");
-#endif
- p = (spcs_s_pinfo_t *)kstatus;
-
- if (p->tcount == SPCS_S_TDSIZE)
- cmn_err(CE_PANIC,
- "SPCS: Unistat too many calls to spcs_s_add_bytestream");
- if ((p->icount + 2) >= SPCS_S_TDSIZE)
- cmn_err(CE_PANIC,
- "SPCS: Unistat idata array too small in "
- "spcs_s_add_bytestream");
- p->idata[p->icount].s = stcode;
- if (p->idata[p->icount++].f.sup_count != 1)
- cmn_err(CE_PANIC,
- "SPCS: Unistat wrong sup_count in spcs_s_add_bytestream");
- p->idata[p->icount].su.type = SU_BYTESTREAM;
- p->idata[p->icount].su.offset = p->tcount++;
- p->tdata[p->idata[p->icount].su.offset].size = size;
- p->tdata[p->idata[p->icount++].su.offset].u_p.data = data;
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!spcs_s_add_bytestream exit");
-#endif
-}
-
-/*
- * Asynchronously output unistat info and possibly bytestreams to
- * userspace. The bytestream mechanism must have been initialized.
- * @param kstatus The status info pointer
- * @return SPCS_S_OK for normal completion, SPCS_S_ERROR otherwise
- * This is a prototype. Specification TBD. Not in the 10/22/98 unistat
- * commitment
- */
-
-int
-spcs_s_asynch_status(spcs_s_info_t kstatus)
-{
- spcs_s_pinfo_t *p;
- int i, s, b, suppcount;
- uchar_t *bp;
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!spcs_s_asynch_status entry");
-#endif
- p = (spcs_s_pinfo_t *)kstatus;
-
- /*
- * Any real code would have to go through and process the
- * address/length pairs in the tdata array. The lengths would be
- * valid but the addresses would be meaningless. Instead, for a
- * stream transport mechanism the bytestream(s) would follow the
- * spcs_s_pinfo_t structure. So after the last call to
- * spcs_s_add_bytestream things the spcs_pinfo_t would look like this:
- * |-------------|
- * | preamble |
- * |-------------|
- * | idata |
- * |(sup offset) |-----------------|
- * |(sup offset) |--| | bytestream reference (index)
- * |-------------| | string |
- * | sdata | | ref (offset) |
- * | (strings) |<-| |
- * |-------------| |
- * | tdata | |
- * | |<----------------|
- * | (length) |
- * | (address) |-------------------->byte data "out there somewhere"
- * |-------------|
- *
- * After processing in this function the data headed for a pipe or
- * other sequention stream would look like this:
- *
- * |-------------|
- * | preamble |
- * |-------------|
- * | idata |
- * | |-----------------|
- * | |--| | bytestream reference (index)
- * |-------------| | string |
- * | sdata | | ref (offset) |
- * | (strings) |<-| |
- * |-------------| |
- * | tdata | |
- * | |<----------------|
- * | (length) |
- * | (null addr) |
- * |-------------|
- * |first |
- * |bytestream |
- * |group |
- * |-------------|
- * |second |
- * |bytestream |
- * |group |
- * |-------------|
- * | . . . |
- * |-------------|
- *
- * For the prototype we just dump the stuff out so we can see the
- * functions work.
- */
-
- if (! bytestream_transport_initialized) {
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!spcs_s_asynch_status exit 1");
-#endif
- return (SPCS_S_ERROR);
- }
-
- cmn_err(CE_NOTE, "!SPCS Unistat Asynchronous Status Dump");
- cmn_err(CE_NOTE, "!This is a test fixture waiting for a pipe or");
- cmn_err(CE_NOTE, "!shared memory");
-
- /*
- * I'd like nothing more than to code up a really cool pipe or mmap'd
- * shared memory scheme to shovel this stuff up to a daemon that feeds
- * Java events out to listener threads belonging to both management
- * software, coresw product code and developer code. As it is I just
- * have time to spew stuff out via cmn_err. Have to make believe this
- * is an alternative to cmn_err and not just another dang client!
- */
-
- i = 0;
-
- while (i < p->icount) {
-
- /*
- * can't access the status text or anything else proper and
- * pretty from here in the kernel, have to just dump it. Put
- * the status codes out as decimal to make them look as weird
- * as possible so we see that the point of this is not for
- * anybody to actually pay attention to them but to use this
- * as a means of testing the rest of the prototype and
- * suggesting potental functionality. We also put the oldest
- * stuff out first, backwards from ioctl status. That's
- * because there are only minutes to implement this and the
- * point is to see the potential, etc.
- */
-
- suppcount = p->idata[i].f.sup_count;
-
- cmn_err(CE_NOTE, "!Status item %d value %x supplements %d",
- i, p->idata[i].s, suppcount);
- i++;
-
- for (s = 0; s < suppcount; s++) {
- if (p->idata[i+s].su.type == SU_STRING)
- cmn_err(CE_NOTE,
- "!Supplement %d string value: %s", s,
- (char *)(p->sdata +
- p->idata[i+s].su.offset));
- else {
- cmn_err(CE_NOTE,
- "!Supplement %d bytestream dump:", s);
- cmn_err(CE_NOTE, "!offset data");
- bp = p->tdata[p->idata[i+s].su.offset].u_p.data;
- /* The SunSoft mandated 8 character tabstops */
- /* really BITE MY BUTT */
- for (b = 0;
- b < p->tdata[p->idata[i+s].su.offset].size;
- b++)
- cmn_err(CE_NOTE, "!%6d %2x",
- b, *bp++);
- }
- }
-
- i += suppcount;
- }
-
-#ifdef UNISTAT_TRACE
- cmn_err(CE_WARN, "!spcs_s_asynch_status exit 2");
-#endif
- return (SPCS_S_OK);
-}
diff --git a/usr/src/uts/common/avs/ns/unistat/spcs_s_k.h b/usr/src/uts/common/avs/ns/unistat/spcs_s_k.h
deleted file mode 100644
index 852a072abe..0000000000
--- a/usr/src/uts/common/avs/ns/unistat/spcs_s_k.h
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SPCS_S_K_H
-#define _SPCS_S_K_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Public SPCS uniform status details
- */
-
-/*
- * KERNEL level status support utilities
- */
-
-
-/*
- * Create and initialize local status. Call this at entry to topmost
- * operation (e.g. the start of ioctl service)
- * @return The allocated and initialized status info or NULL if no memory
- * available
- */
-spcs_s_info_t
-spcs_s_kcreate();
-
-/*
- * Initialize existing status. Call this at entry to topmost operation
- * (e.g. the start of ioctl service)
- * @param kstatus The status info.
- */
-void
-spcs_s_kinit(spcs_s_info_t kstatus);
-
-/*
- * Add a status code and optional support information to status
- * @param kstatus The status info pointer
- * @param stcode The status code to be added (.e.g. DSW_EEMPTY)
- * <BR>Supplemental value parameters may be supplied as needed. There
- * should be one supplemental info parameter corresponding
- * to each edit specification (e.g. %s) in the message text for a
- * given code.
- * <BR>If there is no additional room to insert everything the code
- * SPCS_EOVERFLOW is inserted instead of stcode, possibly replacing an
- * a previously inserted status code.
- */
-void
-spcs_s_add(spcs_s_info_t kstatus, spcs_s_status_t stcode, ...);
-
-/*
- * Copy status info to userspace
- * @param kstatus_a is The address of the local (kernel) status info
- * @param ustatus The userspace status info
- */
-void
-spcs_s_copyout(spcs_s_info_t *kstatus_a, spcs_s_info_t ustatus);
-
-/*
- * Copy status info to userspace and free status info storage
- * @param kstatus_a is The address of the local (kernel) status info
- * @param ustatus The userspace status info
- */
-void
-spcs_s_copyoutf(spcs_s_info_t *kstatus_a, spcs_s_info_t ustatus);
-
-/*
- * Return the oldest status code from the status info or SPCS_S_OK if
- * there is none. This is the status code that was inserted first (i.e.
- * LIFO).
- * @param kstatus The local (kernel level) status info
- * @return The oldest status code value
- */
-
-spcs_s_status_t
-spcs_s_oldest_status(spcs_s_info_t kstatus);
-
-/*
- * Return the youngest status code from the status info or SPCS_S_OK if
- * there is none. This is the status code that was inserted last (i.e.
- * LIFO).
- * @param kstatus The local (kernel level) status info
- * @return The youngest status code value
- */
-
-spcs_s_status_t
-spcs_s_youngest_status(spcs_s_info_t kstatus);
-
-/*
- * Copy status info to userspace and provide return value.
- * <BR>This is a one-step means of returning from a kernel function. It is
- * identical to spcs_s_fcopyout except that the kernel status storage is
- * not released.
- * @param kstatus_a The address of the local kernel status info.
- * @param ustatus The user status info
- * @param stcode A status code. If the status code is NULL it is ignored.
- * <BR>Supplemental value parameters may be supplied as needed. There
- * should be one supplemental info parameter corresponding
- * to each edit specification (e.g. %s) in the message text for a
- * given code.
- * <BR>If there is no additional room to insert everything the code
- * SPCS_EOVERFLOW is inserted instead of stcode, possibly replacing an
- * a previously inserted status code.
- * @return If stcode is NULL and there is no status info present,
- * SPCS_S_OK, else SPCS_S_ERROR.
- */
-spcs_s_status_t
-spcs_s_ocopyout(spcs_s_info_t *kstatus_a,
- spcs_s_info_t ustatus, spcs_s_status_t stcode, ...);
-
-/*
- * Copy status info to userspace, free it and provide a return value
- * <BR>This is a one-step means of returning from a kernel function. It is
- * identical to spcs_s_fcopyout except that the kernel status storage is
- * released.
- * <BR>Return a value to use as a function result (SPCS_S_OK or ERROR)
- * <BR>This is a one-step means of returning from an operation. It is
- * identical to spcs_s_copyout except that the kernel status information
- * storage is released.
- * @param kstatus_a The address of the local kernel status info.
- * @param ustatus The user status info
- * @param stcode A status code. If the status code is NULL it is ignored.
- * @param stcode A status code. If the status code is NULL it is ignored.
- * <BR>Supplemental value parameters may be supplied as needed. There
- * should be one supplemental info parameter corresponding
- * to each edit specification (e.g. %s) in the message text for a
- * <BR>If there is no additional room to insert everything the code
- * SPCS_EOVERFLOW is inserted instead of stcode, possibly replacing an
- * a previously inserted status code.
- * @return If stcode is NULL and there is no status info present,
- * SPCS_S_OK, else SPCS_S_ERROR.
- */
-spcs_s_status_t
-spcs_s_ocopyoutf(spcs_s_info_t *kstatus_a,
- spcs_s_info_t ustatus, spcs_s_status_t stcode, ...);
-
-/*
- * Release (free) status storage.
- * @param status The status information to release (kmem_free)
- */
-void
-spcs_s_kfree(spcs_s_info_t status);
-
-/*
- * Test a status code and return true if it is a Solaris error code
- * @return B_TRUE if the code is a Solaris code (module == 0), else
- * B_FALSE
- */
-boolean_t
-spcs_s_is_solaris(spcs_s_status_t error);
-
-/*
- *
- * Edit an value into a decimal or hexidecimal string.
- * Note that if multiple calls to this function are used to develop the
- * parameters for spcs_s_add() the character arrays must be distinct.
- * @param val The value to edit
- * @param buf Pointer to the start of a char array for conversion
- * @param buflen The size of the char array (minimum 2)
- * @param hex If nonzero "0x" is prepended to generated string and
- * it is edited as hexidecimal.
- * @return The numeric string or "***" if an error is detected
- */
-
-char *
-spcs_s_inttostring(int val, char *buf, int buflen, int hex);
-
-/*
- * Initialize the bytestream mechanism.
- *
- * This function initializes the Unistat mechanism for transporting
- * status information with or without bytestream data to userspace.
- *
- * @return SPCS_S_OK for normal completion, SPCS_S_ERROR otherwise
- *
- * Specification TBD. Not in 10/22 commitment
- */
-
-int
-spcs_s_start_bytestream();
-
-/*
- * Stop (shut off) the bytestream mechanism.
- *
- * This function terminates the Unistat mechanism for transporting
- * status information with or without bytestream data to userspace.
- *
- * @return SPCS_S_OK for normal completion, SPCS_S_ERROR otherwise
- *
- * Specification TBD. Not in 10/22 commitment
- */
-
-int
-spcs_s_stop_bytestream();
-
-/*
- * Add a status code and the address and length of arbitrary binary
- * data to be held (possibly with other status) for later transmission to
- * userspace via a pipe facility (i.e. NOT via ioctl return). This is a
- * means of getting arbitrary information with or without other status
- * info shipped out as an alternative to cmn_err and/or trace file
- * mechanisms.
- * @param kstatus The status info pointer
- * @param stcode The status code to annotate the data
- * @param data The starting address of the data
- * @param size The byte length of the data
- * Specification TBD. Not in the 10/22/98 unistat commitment
- */
-
-void
-spcs_s_add_bytestream(spcs_s_info_t kstatus, spcs_s_status_t stcode,
- spcs_s_bytestream_ptr_t data, int size);
-
-/*
- * Asynchronously output unistat info and possibly bytestreams to
- * userspace. The bytestream mechanism must have been initialized.
- * @param kstatus The status info pointer
- * @return SPCS_S_OK for normal completion, SPCS_S_ERROR otherwise
- * Specification TBD. Not in the 10/22/98 unistat commitment
- */
-
-int
-spcs_s_asynch_status(spcs_s_info_t kstatus);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SPCS_S_K_H */
diff --git a/usr/src/uts/common/avs/ns/unistat/spcs_s_u.h b/usr/src/uts/common/avs/ns/unistat/spcs_s_u.h
deleted file mode 100644
index 84dcbc1124..0000000000
--- a/usr/src/uts/common/avs/ns/unistat/spcs_s_u.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SPCS_S_U_H
-#define _SPCS_S_U_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * USER level status support utilities
- */
-
-#include <stdio.h>
-
-/*
- * Create and initialize local status. Call this prior to invoking
- * an ioctl
- * @return The status or NULL if malloc failed
- */
-
-spcs_s_info_t
-spcs_s_ucreate();
-
-/*
- * Initialize ioctl status storage to "remove" any status present
- * @param ustatus The status
- */
-
-void
-spcs_s_uinit(spcs_s_info_t ustatus);
-
-/*
- * Return a string with the module label and next status message text or
- * NULL if none left. Supplemental values are edited into the text and
- * the used status and values are removed so that subsequent calls will
- * access the next piece of information.
- * Note that status codes and supplemental values are processed in
- * the reverse order of their insertion by SPCS kernel code. That is,
- * spcs_s_string returns the "youngest" status information first (i.e.
- * LIFO).
- * Note that spcs_s_string will not have any error information in
- * the special case where Solaris has aborted an ioctl and returned an
- * error code via errno or the ioctl service code had an "early" error
- * from copyin or could not allocate its status area. In this case
- * spcs_s_string will return NULL the first time it is called and a
- * positive integer error code will be present in errno and should get
- * handled by the spcs_s_string caller appropriately by using strerror.
- * @param ustatus The status
- * @param msg A char array of at least SPCS_S_MAXTEXT length
- * @return status message string or NULL if no more status present
- */
-
-char *spcs_s_string(spcs_s_info_t ustatus, char *msg);
-
-/*
- * Write status info to the file specified
- * Uses spsc_s_string to edit status into strings and output them
- * to the file specifed in the same order that the status was inserted.
- * If there is no status present but errno contains a positive value
- * then it will be treated as a Solaris error code and its message text
- * will be written. Note that this routine does NOT remove status
- * information so it can be called more than once.
- * @param ustatus The status
- * @param fd The file descriptor to use for output
- */
-
-void spcs_s_report(spcs_s_info_t ustatus, FILE *fd);
-
-/*
- * Release (free) ioctl status storage.
- * Note that this interface is an extension to SPARC 1998/038 10/22/98
- * commitment.
- * @param ustatus_a The address of the status (set to NULL)
- */
-
-void
-spcs_s_ufree(spcs_s_info_t *ustatus_a);
-
-/*
- * Write message to log file.
- * @param product Product code for tagging in log file.
- * @param ustatus The status - may be NULL.
- * @param format printf style format.
- */
-
-void
-spcs_log(const char *product, spcs_s_info_t *ustatus, const char *format, ...);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SPCS_S_U_H */
diff --git a/usr/src/uts/common/avs/ns/unistat/spuni.c b/usr/src/uts/common/avs/ns/unistat/spuni.c
deleted file mode 100644
index 6a13b72702..0000000000
--- a/usr/src/uts/common/avs/ns/unistat/spuni.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#define _SPUNI_
-
-#include <sys/types.h>
-#include <sys/ksynch.h>
-#include <sys/kmem.h>
-#include <sys/errno.h>
-#include <sys/conf.h>
-#include <sys/cmn_err.h>
-#include <sys/modctl.h>
-#include <sys/cred.h>
-#include <sys/file.h>
-#include <sys/ddi.h>
-#include <sys/unistat/spcs_s.h>
-
-#ifdef DS_DDICT
-#include <sys/nsctl/contract.h>
-#endif
-
-#include <sys/nsctl/nsctl.h>
-#include <sys/nsctl/nsvers.h>
-
-/*
- * Module linkage.
- */
-
-static struct modlmisc spuni_modlmisc = {
- &mod_miscops, /* Type of module */
- "nws:Unistat:" ISS_VERSION_STR
-};
-
-static struct modlinkage spuni_modlinkage = {
- MODREV_1,
- &spuni_modlmisc,
- NULL
-};
-
-int
-_init(void)
-{
- return (mod_install(&spuni_modlinkage));
-}
-
-int
-_fini(void)
-{
- return (mod_remove(&spuni_modlinkage));
-}
-
-/*
- * Solaris module info code
- */
-int
-_info(struct modinfo *modinfop)
-{
- return (mod_info(&spuni_modlinkage, modinfop));
-}
diff --git a/usr/src/uts/intel/Makefile.intel b/usr/src/uts/intel/Makefile.intel
index d7616eac11..a648a12c41 100644
--- a/usr/src/uts/intel/Makefile.intel
+++ b/usr/src/uts/intel/Makefile.intel
@@ -285,7 +285,7 @@ DRV_KMODS += mm
DRV_KMODS += mouse8042
DRV_KMODS += mpt_sas
DRV_KMODS += mr_sas
-DRV_KMODS += mwl
+DRV_KMODS += mwl
DRV_KMODS += nca
DRV_KMODS += nsmb
DRV_KMODS += nulldriver
@@ -374,8 +374,6 @@ DRV_KMODS += fcoei
DRV_KMODS += qlt
DRV_KMODS += iscsit
DRV_KMODS += pppt
-DRV_KMODS += ncall nsctl sdbc nskern sv
-DRV_KMODS += ii rdc rdcsrv rdcstub
DRV_KMODS += iptun
DRV_KMODS += vmxnet3s
DRV_KMODS += pvscsi
@@ -633,7 +631,6 @@ MISC_KMODS += sata
MISC_KMODS += scsi
MISC_KMODS += sda
MISC_KMODS += sol_ofs
-MISC_KMODS += spuni
MISC_KMODS += strategy
MISC_KMODS += strplumb
MISC_KMODS += tem
diff --git a/usr/src/uts/intel/ii/Makefile b/usr/src/uts/intel/ii/Makefile
deleted file mode 100644
index 484f12bad1..0000000000
--- a/usr/src/uts/intel/ii/Makefile
+++ /dev/null
@@ -1,95 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# uts/intel/ii/Makefile
-#
-# This makefile drives the production of the ii kernel module
-#
-# intel implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-#
-UTSBASE = ../..
-
-ARCHDIR:sh = cd ..; basename `pwd`
-
-#
-# Define the module and object file sets.
-#
-MODULE = ii
-OBJECTS = $(DSW_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(DSW_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(USR_DRV_DIR)/$(MODULE)
-INC_PATH += -I$(ROOT)/usr/include
-CONF_SRCDIR = $(UTSBASE)/common/avs/ns/dsw
-
-#
-# Include common rules.
-#
-include ../Makefile.$(ARCHDIR)
-include $(UTSBASE)/common/avs/Makefile.com
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY) $(SRC_CONFILE)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOT_CONFFILE)
-
-#
-# lint pass one enforcement
-#
-CFLAGS += $(CCVERBOSE)
-LDFLAGS += -dy -N"drv/nsctl" -N"drv/nskern" -N"misc/spuni"
-LINTTAGS += -erroff=E_ASSIGN_NARROW_CONV
-LINTTAGS += -erroff=E_BAD_PTR_CAST_ALIGN
-
-CERRWARN += -_gcc=-Wno-parentheses
-CERRWARN += -_gcc=-Wno-uninitialized
-
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-#
-# Include common targets.
-#
-include ../Makefile.targ
-
diff --git a/usr/src/uts/intel/ncall/Makefile b/usr/src/uts/intel/ncall/Makefile
deleted file mode 100644
index 40a25e1dd2..0000000000
--- a/usr/src/uts/intel/ncall/Makefile
+++ /dev/null
@@ -1,89 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# uts/intel/ncall/Makefile
-#
-# This makefile drives the production of the ncall kernel module
-#
-# intel implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-#
-UTSBASE = ../..
-
-ARCHDIR:sh = cd ..; basename `pwd`
-
-#
-# Define the module and object file sets.
-#
-MODULE = ncall
-OBJECTS = $(NCALL_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(NCALL_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(USR_DRV_DIR)/$(MODULE)
-INC_PATH += -I$(ROOT)/usr/include
-CONF_SRCDIR = $(UTSBASE)/common/avs/ncall
-
-#
-# Include common rules.
-#
-include $(UTSBASE)/intel/Makefile.$(ARCHDIR)
-include $(UTSBASE)/common/avs/Makefile.com
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY) $(SRC_CONFILE)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOT_CONFFILE)
-
-#
-# lint pass one enforcement
-#
-CFLAGS += -v -D_SYSCALL32
-LINT_DEFS += -D_SYSCALL32
-
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-#
-# Include common targets.
-#
-include ../Makefile.targ
diff --git a/usr/src/uts/intel/nsctl/Makefile b/usr/src/uts/intel/nsctl/Makefile
deleted file mode 100644
index e57c1eb168..0000000000
--- a/usr/src/uts/intel/nsctl/Makefile
+++ /dev/null
@@ -1,95 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# uts/intel/nsctl/Makefile
-#
-# This makefile drives the production of the nsctl kernel module
-#
-# intel implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-#
-UTSBASE = ../..
-
-ARCHDIR:sh = cd ..; basename `pwd`
-
-#
-# Define the module and object file sets.
-#
-MODULE = nsctl
-OBJECTS = $(NSCTL_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(NSCTL_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(USR_DRV_DIR)/$(MODULE)
-INC_PATH += -I$(UTSBASE)/common/avs
-INC_PATH += -I$(ROOT)/usr/include
-CONF_SRCDIR = $(UTSBASE)/common/avs/ns/nsctl
-
-#
-# Include common rules.
-#
-include ../Makefile.$(ARCHDIR)
-include $(UTSBASE)/common/avs/Makefile.com
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY) $(SRC_CONFILE)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOT_CONFFILE)
-
-#
-# lint pass one enforcement
-#
-CFLAGS += $(CCVERBOSE)
-LDFLAGS += -dy -N"drv/nskern" -N"drv/ncall" -N"misc/spuni"
-LINTTAGS += -erroff=E_ASSIGN_NARROW_CONV
-LINTTAGS += -erroff=E_BAD_PTR_CAST_ALIGN
-
-CERRWARN += -_gcc=-Wno-parentheses
-
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-
-#
-# Include common targets.
-#
-include ../Makefile.targ
diff --git a/usr/src/uts/intel/nskern/Makefile b/usr/src/uts/intel/nskern/Makefile
deleted file mode 100644
index c57aaa4b54..0000000000
--- a/usr/src/uts/intel/nskern/Makefile
+++ /dev/null
@@ -1,97 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# uts/intel/nskern/Makefile
-#
-# This makefile drives the production of the nskern kernel module
-#
-# intel implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-#
-UTSBASE = ../..
-
-ARCHDIR:sh = cd ..; basename `pwd`
-
-#
-# Define the module and object file sets.
-#
-MODULE = nskern
-OBJECTS = $(NSKERN_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(NSKERN_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(USR_DRV_DIR)/$(MODULE)
-INC_PATH += -I$(UTSBASE)/common/avs -I./$(OBJS_DIR)
-INC_PATH += -I$(ROOT)/usr/include
-CONF_SRCDIR = $(UTSBASE)/common/avs/ns/solaris
-
-#
-# Include common rules.
-#
-include ../Makefile.$(ARCHDIR)
-include $(UTSBASE)/common/avs/Makefile.com
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY) $(SRC_CONFILE)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOT_CONFFILE)
-AS_INC_PATH += -I$(DSF_DIR)/$(OBJS_DIR)
-
-ASSYM_H = $(DSF_DIR)/$(OBJS_DIR)/assym.h
-
-#
-# lint pass one enforcement
-#
-CFLAGS += -v
-
-.KEEP_STATE:
-
-$(OBJS_DIR)/nsc_asm.o: nsc_asm.s
-
-$(BINARY): $(ASSYM_H)
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-
-install: $(INSTALL_DEPS)
-
-#
-# Include common targets.
-#
-include ../Makefile.targ
diff --git a/usr/src/uts/intel/nskern/nsc_asm.s b/usr/src/uts/intel/nskern/nsc_asm.s
deleted file mode 100644
index 6f0c329511..0000000000
--- a/usr/src/uts/intel/nskern/nsc_asm.s
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#if defined(lint) || defined(DS_DDICT)
-#include <sys/types.h>
-#include <sys/param.h>
-#else
-#include "assym.h" /* Determine value of CPU_THREAD */
-#include <sys/asm_linkage.h>
-#endif
-
-#ifdef DS_DDICT
-#define uint8_t uchar_t
-#endif
-
-
-/*
- * Special support routines that can't be done with C
- * x86 variant
- */
-
-/*
- * uint8_t nsc_ldstub(uint8_t *cp)
- *
- * Store 0xFF at the specified location, and return its previous content.
- */
-
-#if defined(lint) || defined(DS_DDICT)
-uint8_t
-nsc_ldstub(uint8_t *cp)
-{
- uint8_t rv;
- rv = *cp;
- *cp = 0xFF;
- return (rv);
-}
-#else
- ENTRY(nsc_ldstub)
-#if defined(__amd64)
- movl $0xff,%eax
- lock
- xchgb %al, (%rdi) /* rdi = lock addr */
- ret
-#elif defined(__i386)
- movl 4(%esp), %ecx /* ecx = lock addr */
- movl $0xff, %eax /* eax = 0xff */
- lock
- xchgb %al, (%ecx) /* atomic swap eax <-> *ecx */
- ret
-#else
-#error "port this routine"
-#endif
- SET_SIZE(nsc_ldstub)
-#endif
-
-/*
- * nsc_membar_stld(void)
- *
- * On SPARC this is a C callable interface to SPARC asm membar instruction.
- * For x86 we brute force it with a #LOCK instruction.
- */
-
-#if defined(lint) || defined(DS_DDICT)
-void
-nsc_membar_stld(void)
-{}
-#else
-
- ENTRY(nsc_membar_stld)
-#if defined(__amd64)
- mfence
- ret
-#elif defined(__i386)
- lock
- xorl $0, (%esp)
- ret
-#else
-#error "port this routine"
-#endif
- SET_SIZE(nsc_membar_stld)
-
-#endif /* lint || DS_DDICT */
-
-
-/*
- * if a() calls b() calls nsc_caller(),
- * nsc_caller() returns return address in a().
- */
-
-#if defined(lint) || defined(DS_DDICT)
-caddr_t
-nsc_caller(void)
-{
- return (0);
-}
-#else
-
- ENTRY(nsc_caller)
-#if defined(__amd64)
- movq 8(%rbp), %rax /* b()'s return pc, in a() */
- ret
-#elif defined(__i386)
- movl 4(%ebp), %eax /* b()'s return pc, in a() */
- ret
-#else
-#error "port this routine"
-#endif
- SET_SIZE(nsc_caller)
-
-#endif /* lint || DS_DDICT */
-
-
-/*
- * if a() calls nsc_callee(), nsc_callee() returns the
- * return address in a();
- */
-
-#if defined(lint) || defined(DS_DDICT)
-caddr_t
-nsc_callee(void)
-{
- return (0);
-}
-#else
-
- ENTRY(nsc_callee)
-#if defined(__amd64)
- movq (%rsp), %rax /* callee()'s return pc, in a() */
- ret
-#elif defined(__i386)
- movl (%esp), %eax /* callee()'s return pc, in a() */
- ret
-#else
-#error "port this routine"
-#endif
- SET_SIZE(nsc_callee)
-
-#endif /* lint || DS_DDICT */
-
-
-/*
- * nsc_threadp(void)
- *
- * C callable interface to get the current thread pointer.
- */
-
-#if defined(lint) || defined(DS_DDICT)
-void *
-nsc_threadp(void)
-{
- return (NULL);
-}
-#else
-
- ENTRY(nsc_threadp)
-#if defined(__amd64)
- movq %gs:CPU_THREAD, %rax
- ret
-#elif defined(__i386)
- movl %gs:CPU_THREAD,%eax
- ret
-#else
-#error "port this routine"
-#endif
- SET_SIZE(nsc_threadp)
-
-#endif /* lint || DS_DDICT */
diff --git a/usr/src/uts/intel/rdc/Makefile b/usr/src/uts/intel/rdc/Makefile
deleted file mode 100644
index 337ef0f14c..0000000000
--- a/usr/src/uts/intel/rdc/Makefile
+++ /dev/null
@@ -1,108 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# uts/intel/rdc/Makefile
-#
-# This makefile drives the production of the rdc kernel module
-#
-# intel implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-#
-UTSBASE = ../..
-
-ARCHDIR:sh = cd ..; basename `pwd`
-
-#
-# Define the module and object file sets.
-#
-MODULE = rdc
-OBJECTS = $(RDC_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(RDC_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(USR_DRV_DIR)/$(MODULE)
-INC_PATH += -I$(ROOT)/usr/include
-CONF_SRCDIR = $(UTSBASE)/common/avs/ns/rdc
-
-#
-# Include common rules.
-#
-include ../Makefile.$(ARCHDIR)
-include $(UTSBASE)/common/avs/Makefile.com
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY) $(SRC_CONFILE)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOT_CONFFILE)
-
-#
-# lint pass one enforcement
-#
-CFLAGS += $(CCVERBOSE) -D_SD_8K_BLKSIZE -D_SYSCALL32
-LINT_DEFS += -D_SYSCALL32
-LINTTAGS += -erroff=E_FUNC_RET_MAYBE_IGNORED2
-LINTTAGS += -erroff=E_BAD_PTR_CAST_ALIGN
-LINTTAGS += -erroff=E_INCONS_ARG_DECL2
-LDFLAGS += -dy -N"drv/nsctl" -N"drv/nskern" -N"drv/ncall" -N"misc/spuni" \
- -N"misc/rdcsrv" -N"strmod/rpcmod"
-
-CERRWARN += -_gcc=-Wno-switch
-CERRWARN += -_gcc=-Wno-unused-label
-CERRWARN += -_gcc=-Wno-parentheses
-CERRWARN += -_gcc=-Wno-uninitialized
-
-
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
- -rm -f obj*/rdc_prot_xdr.c debug*/rdc_prot_xdr.c
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-$(OBJS_DIR)/rdc_prot_xdr.c: $(UTSBASE)/common/avs/ns/rdc/rdc_prot.x
- $(RPCGEN) -i 0 -C -c -o $@ \
- `/bin/pwd`/$(UTSBASE)/common/avs/ns/rdc/rdc_prot.x
-
-$(OBJS_DIR)/rdc_prot_xdr.o: $(OBJS_DIR)/rdc_prot_xdr.c
- $(COMPILE.c) -o $@ $(OBJS_DIR)/rdc_prot_xdr.c
-
-#
-# Include common targets.
-#
-include ../Makefile.targ
diff --git a/usr/src/uts/intel/rdcsrv/Makefile b/usr/src/uts/intel/rdcsrv/Makefile
deleted file mode 100644
index 852d4aa932..0000000000
--- a/usr/src/uts/intel/rdcsrv/Makefile
+++ /dev/null
@@ -1,96 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# uts/intel/rdcsrv/Makefile
-#
-# This makefile drives the production of the rdcsrv kernel module
-#
-# intel implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-#
-UTSBASE = ../..
-
-ARCHDIR:sh = cd ..; basename `pwd`
-
-#
-# Define the module and object file sets.
-#
-MODULE = rdcsrv
-OBJECTS = $(RDCSRV_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(RDCSRV_OBJS:%.o=$(LINTS_DIR)/%.ln)
-INC_PATH += -I$(ROOT)/usr/include
-ROOTMODULE = $(USR_DRV_DIR)/$(MODULE)
-ROOTLINK = $(USR_MISC_DIR)/$(MODULE)
-
-#
-# Include common rules.
-#
-include ../Makefile.$(ARCHDIR)
-include $(UTSBASE)/common/avs/Makefile.com
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOTLINK)
-
-#
-# lint pass one enforcement
-#
-CFLAGS += $(CCVERBOSE) -D_SD_8K_BLKSIZE -D_SYSCALL32
-LINT_DEFS += -D_SD_8K_BLKSIZE -D_SYSCALL32
-LDFLAGS += -dy -N"strmod/rpcmod" -N"misc/rdcstub"
-
-CERRWARN += -_gcc=-Wno-unused-label
-CERRWARN += -_gcc=-Wno-unused-variable
-
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-$(ROOTLINK): $(USR_MISC_DIR) $(ROOTMODULE)
- -$(RM) $@; $(LN) $(ROOTMODULE) $@
-
-#
-# Include common targets.
-#
-include ../Makefile.targ
diff --git a/usr/src/uts/intel/rdcstub/Makefile b/usr/src/uts/intel/rdcstub/Makefile
deleted file mode 100644
index 2a91cc1d7e..0000000000
--- a/usr/src/uts/intel/rdcstub/Makefile
+++ /dev/null
@@ -1,93 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# uts/intel/rdcstub/Makefile
-#
-# This makefile drives the production of the rdcsrv kernel module
-#
-# intel implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-#
-UTSBASE = ../..
-
-ARCHDIR:sh = cd ..; basename `pwd`
-
-#
-# Define the module and object file sets.
-#
-MODULE = rdcstub
-OBJECTS = $(RDCSTUB_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(RDCSTUB_OBJS:%.o=$(LINTS_DIR)/%.ln)
-INC_PATH += -I$(ROOT)/usr/include
-ROOTMODULE = $(USR_DRV_DIR)/$(MODULE)
-ROOTLINK = $(USR_MISC_DIR)/$(MODULE)
-
-#
-# Include common rules.
-#
-include ../Makefile.$(ARCHDIR)
-include $(UTSBASE)/common/avs/Makefile.com
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOTLINK)
-
-#
-# lint pass one enforcement
-#
-CFLAGS += -v -D_SD_8K_BLKSIZE -D_SYSCALL32
-LINT_DEFS += -D_SD_8K_BLKSIZE -D_SYSCALL32
-LDFLAGS += -dy -N"strmod/rpcmod"
-
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-$(ROOTLINK): $(USR_MISC_DIR) $(ROOTMODULE)
- -$(RM) $@; $(LN) $(ROOTMODULE) $@
-
-#
-# Include common targets.
-#
-include ../Makefile.targ
diff --git a/usr/src/uts/intel/sdbc/Makefile b/usr/src/uts/intel/sdbc/Makefile
deleted file mode 100644
index bc506fab29..0000000000
--- a/usr/src/uts/intel/sdbc/Makefile
+++ /dev/null
@@ -1,172 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#
-# uts/intel/sdbc/Makefile
-#
-# This makefile drives the production of the sdbc kernel module
-#
-# intel implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-#
-UTSBASE = ../..
-
-ARCHDIR:sh = cd ..; basename `pwd`
-
-UTSCOMMON = $(UTSBASE)/common
-AVSCOMMON = $(UTSCOMMON)/avs
-
-#
-# Define the module and object file sets.
-#
-MODULE = sdbc
-OBJECTS = $(SDBC_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(SDBC_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(USR_DRV_DIR)/$(MODULE)
-INC_PATH += -I$(ROOT)/usr/include
-INC_PATH += -I$(AVSCOMMON)
-INC_PATH += -I$(AVSCOMMON)/ns/sdbc
-CONF_SRCDIR = $(UTSBASE)/common/avs/ns/sdbc
-
-#
-# Include common rules.
-#
-include ../Makefile.$(ARCHDIR)
-include $(UTSBASE)/common/avs/Makefile.com
-
-CLOBBERFILES += obj*/*.c debug*/*.c obj*/sd_mkiob debug*/sd_mkiob
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY) $(SRC_CONFILE)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOT_CONFFILE)
-
-#
-# lint pass one enforcement
-#
-CFLAGS += $(CCVERBOSE) -D_SD_8K_BLKSIZE -D_SDBC_SINGLE_BRD
-LDFLAGS += -dy -N"drv/nsctl" -N"drv/ncall" -N"drv/nskern" -N"misc/spuni"
-LINTTAGS += -erroff=E_ASSIGN_NARROW_CONV
-LINTTAGS += -erroff=E_BAD_PTR_CAST_ALIGN
-
-CERRWARN += -_gcc=-Wno-parentheses
-CERRWARN += -_gcc=-Wno-uninitialized
-CERRWARN += -_gcc=-Wno-unused-label
-
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-$(OBJS_DIR)/sd_mkiob: $(UTSBASE)/common/avs/ns/sdbc/sd_mkiob.sh
- $(CP) $(UTSBASE)/common/avs/ns/sdbc/sd_mkiob.sh $@
- $(CHMOD) 755 $@
-
-$(OBJS_DIR)/sd_iob_impl0.c: $(UTSBASE)/common/avs/ns/sdbc/sd_iob.h \
- $(OBJS_DIR)/sd_mkiob
- $(OBJS_DIR)/sd_mkiob 0 512 $(AVSCOMMON)/ns/sdbc/sd_iob.h > $@
-
-$(OBJS_DIR)/sd_iob_impl1.c: $(UTSBASE)/common/avs/ns/sdbc/sd_iob.h \
- $(OBJS_DIR)/sd_mkiob
- $(OBJS_DIR)/sd_mkiob 512 1024 $(AVSCOMMON)/ns/sdbc/sd_iob.h > $@
-
-$(OBJS_DIR)/sd_iob_impl2.c: $(UTSBASE)/common/avs/ns/sdbc/sd_iob.h \
- $(OBJS_DIR)/sd_mkiob
- $(OBJS_DIR)/sd_mkiob 1024 1536 $(AVSCOMMON)/ns/sdbc/sd_iob.h > $@
-
-$(OBJS_DIR)/sd_iob_impl3.c: $(UTSBASE)/common/avs/ns/sdbc/sd_iob.h \
- $(OBJS_DIR)/sd_mkiob
- $(OBJS_DIR)/sd_mkiob 1536 2048 $(AVSCOMMON)/ns/sdbc/sd_iob.h > $@
-
-$(OBJS_DIR)/sd_iob_impl4.c: $(UTSBASE)/common/avs/ns/sdbc/sd_iob.h \
- $(OBJS_DIR)/sd_mkiob
- $(OBJS_DIR)/sd_mkiob 2048 2560 $(AVSCOMMON)/ns/sdbc/sd_iob.h > $@
-
-$(OBJS_DIR)/sd_iob_impl5.c: $(UTSBASE)/common/avs/ns/sdbc/sd_iob.h \
- $(OBJS_DIR)/sd_mkiob
- $(OBJS_DIR)/sd_mkiob 2560 3072 $(AVSCOMMON)/ns/sdbc/sd_iob.h > $@
-
-$(OBJS_DIR)/sd_iob_impl6.c: $(UTSBASE)/common/avs/ns/sdbc/sd_iob.h \
- $(OBJS_DIR)/sd_mkiob
- $(OBJS_DIR)/sd_mkiob 3072 3584 $(AVSCOMMON)/ns/sdbc/sd_iob.h > $@
-
-$(OBJS_DIR)/sd_iob_impl7.c: $(UTSBASE)/common/avs/ns/sdbc/sd_iob.h \
- $(OBJS_DIR)/sd_mkiob
- $(OBJS_DIR)/sd_mkiob 3584 9999 $(AVSCOMMON)/ns/sdbc/sd_iob.h > $@
-
-$(OBJS_DIR)/sd_iob_impl0.o: $(OBJS_DIR)/sd_iob_impl0.c
- $(COMPILE.c) -o $@ $(OBJS_DIR)/sd_iob_impl0.c
- $(POST_PROCESS_O)
-
-$(OBJS_DIR)/sd_iob_impl1.o: $(OBJS_DIR)/sd_iob_impl1.c
- $(COMPILE.c) -o $@ $(OBJS_DIR)/sd_iob_impl1.c
- $(POST_PROCESS_O)
-
-$(OBJS_DIR)/sd_iob_impl2.o: $(OBJS_DIR)/sd_iob_impl2.c
- $(COMPILE.c) -o $@ $(OBJS_DIR)/sd_iob_impl2.c
- $(POST_PROCESS_O)
-
-$(OBJS_DIR)/sd_iob_impl3.o: $(OBJS_DIR)/sd_iob_impl3.c
- $(COMPILE.c) -o $@ $(OBJS_DIR)/sd_iob_impl3.c
- $(POST_PROCESS_O)
-
-$(OBJS_DIR)/sd_iob_impl4.o: $(OBJS_DIR)/sd_iob_impl4.c
- $(COMPILE.c) -o $@ $(OBJS_DIR)/sd_iob_impl4.c
- $(POST_PROCESS_O)
-
-$(OBJS_DIR)/sd_iob_impl5.o: $(OBJS_DIR)/sd_iob_impl5.c
- $(COMPILE.c) -o $@ $(OBJS_DIR)/sd_iob_impl5.c
- $(POST_PROCESS_O)
-
-$(OBJS_DIR)/sd_iob_impl6.o: $(OBJS_DIR)/sd_iob_impl6.c
- $(COMPILE.c) -o $@ $(OBJS_DIR)/sd_iob_impl6.c
- $(POST_PROCESS_O)
-
-$(OBJS_DIR)/sd_iob_impl7.o: $(OBJS_DIR)/sd_iob_impl7.c
- $(COMPILE.c) -o $@ $(OBJS_DIR)/sd_iob_impl7.c
- $(POST_PROCESS_O)
-
-
-#
-# Include common targets.
-#
-include ../Makefile.targ
diff --git a/usr/src/uts/intel/spuni/Makefile b/usr/src/uts/intel/spuni/Makefile
deleted file mode 100644
index f4c4d9378c..0000000000
--- a/usr/src/uts/intel/spuni/Makefile
+++ /dev/null
@@ -1,88 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# uts/intel/spuni/Makefile
-#
-# This makefile drives the production of the spuni kernel module
-#
-# intel implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-#
-UTSBASE = ../..
-
-ARCHDIR:sh = cd ..; basename `pwd`
-
-#
-# Define the module and object file sets.
-#
-MODULE = spuni
-OBJECTS = $(UNISTAT_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(UNISTAT_OBJS:%.o=$(LINTS_DIR)/%.ln)
-INC_PATH += -I$(ROOT)/usr/include
-ROOTMODULE = $(USR_MISC_DIR)/$(MODULE)
-
-#
-# Include common rules.
-#
-include ../Makefile.$(ARCHDIR)
-include $(UTSBASE)/common/avs/Makefile.com
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE)
-
-#
-# lint pass one enforcement
-#
-CFLAGS += -v
-LINTFLAGS += -erroff=E_BAD_PTR_CAST_ALIGN
-
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-#
-# Include common targets.
-#
-include ../Makefile.targ
diff --git a/usr/src/uts/intel/sv/Makefile b/usr/src/uts/intel/sv/Makefile
deleted file mode 100644
index af3f10107e..0000000000
--- a/usr/src/uts/intel/sv/Makefile
+++ /dev/null
@@ -1,91 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# uts/intel/sv/Makefile
-#
-# This makefile drives the production of the sv kernel module
-#
-# intel implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-#
-UTSBASE = ../..
-
-ARCHDIR:sh = cd ..; basename `pwd`
-
-#
-# Define the module and object file sets.
-#
-MODULE = sv
-OBJECTS = $(SV_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(SV_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(USR_DRV_DIR)/$(MODULE)
-INC_PATH += -I$(ROOT)/usr/include
-CONF_SRCDIR = $(UTSBASE)/common/avs/ns/sv
-
-#
-# Include common rules.
-#
-include ../Makefile.$(ARCHDIR)
-include $(UTSBASE)/common/avs/Makefile.com
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY) $(SRC_CONFILE)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOT_CONFFILE)
-
-#
-# lint pass one enforcement
-#
-CFLAGS += $(CCVERBOSE)
-LDFLAGS += -dy -N"drv/nsctl" -N"drv/nskern" -N"misc/spuni"
-
-CERRWARN += -_gcc=-Wno-uninitialized
-
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-#
-# Include common targets.
-#
-include ../Makefile.targ
diff --git a/usr/src/uts/sparc/Makefile.sparc b/usr/src/uts/sparc/Makefile.sparc
index b1f06de520..2b193b20f4 100644
--- a/usr/src/uts/sparc/Makefile.sparc
+++ b/usr/src/uts/sparc/Makefile.sparc
@@ -313,8 +313,6 @@ DRV_KMODS += fcoei
DRV_KMODS += qlt
DRV_KMODS += iscsit
DRV_KMODS += pppt
-DRV_KMODS += ncall nsctl sdbc nskern sv
-DRV_KMODS += ii rdc rdcsrv rdcstub
DRV_KMODS += iscsi
DRV_KMODS += emlxs
DRV_KMODS += oce
@@ -416,7 +414,6 @@ MISC_KMODS += qlc_fw_2400
MISC_KMODS += qlc_fw_2500
MISC_KMODS += qlc_fw_6322
MISC_KMODS += qlc_fw_8100
-MISC_KMODS += spuni
MISC_KMODS += mii
MISC_KMODS += klmmod klmops
diff --git a/usr/src/uts/sparc/ii/Makefile b/usr/src/uts/sparc/ii/Makefile
deleted file mode 100644
index e4f936866f..0000000000
--- a/usr/src/uts/sparc/ii/Makefile
+++ /dev/null
@@ -1,95 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# uts/sparc/ii/Makefile
-#
-# This makefile drives the production of the ii kernel module
-#
-# sparc implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-#
-UTSBASE = ../..
-
-ARCHDIR:sh = cd ..; basename `pwd`
-
-#
-# Define the module and object file sets.
-#
-MODULE = ii
-OBJECTS = $(DSW_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(DSW_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(USR_DRV_DIR)/$(MODULE)
-INC_PATH += -I$(ROOT)/usr/include
-CONF_SRCDIR = $(UTSBASE)/common/avs/ns/dsw
-
-#
-# Include common rules.
-#
-include ../Makefile.$(ARCHDIR)
-include $(UTSBASE)/common/avs/Makefile.com
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY) $(SRC_CONFILE)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOT_CONFFILE)
-
-#
-# lint pass one enforcement
-#
-CFLAGS += $(CCVERBOSE)
-LDFLAGS += -dy -N"drv/nsctl" -N"drv/nskern" -N"misc/spuni"
-LINTTAGS += -erroff=E_ASSIGN_NARROW_CONV
-LINTTAGS += -erroff=E_BAD_PTR_CAST_ALIGN
-
-CERRWARN += -_gcc=-Wno-parentheses
-CERRWARN += -_gcc=-Wno-uninitialized
-
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-#
-# Include common targets.
-#
-include ../Makefile.targ
-
diff --git a/usr/src/uts/sparc/ncall/Makefile b/usr/src/uts/sparc/ncall/Makefile
deleted file mode 100644
index 99d4b27288..0000000000
--- a/usr/src/uts/sparc/ncall/Makefile
+++ /dev/null
@@ -1,89 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# uts/sparc/ncall/Makefile
-#
-# This makefile drives the production of the ncall kernel module
-#
-# sparc implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-#
-UTSBASE = ../..
-
-ARCHDIR:sh = cd ..; basename `pwd`
-
-#
-# Define the module and object file sets.
-#
-MODULE = ncall
-OBJECTS = $(NCALL_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(NCALL_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(USR_DRV_DIR)/$(MODULE)
-INC_PATH += -I$(ROOT)/usr/include
-CONF_SRCDIR = $(UTSBASE)/common/avs/ncall
-
-#
-# Include common rules.
-#
-include $(UTSBASE)/sparc/Makefile.$(ARCHDIR)
-include $(UTSBASE)/common/avs/Makefile.com
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY) $(SRC_CONFILE)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOT_CONFFILE)
-
-#
-# lint pass one enforcement
-#
-CFLAGS += -v -D_SYSCALL32
-LINT_DEFS += -D_SYSCALL32
-
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-#
-# Include common targets.
-#
-include ../Makefile.targ
diff --git a/usr/src/uts/sparc/nsctl/Makefile b/usr/src/uts/sparc/nsctl/Makefile
deleted file mode 100644
index 2875093f8e..0000000000
--- a/usr/src/uts/sparc/nsctl/Makefile
+++ /dev/null
@@ -1,95 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# uts/sparc/nsctl/Makefile
-#
-# This makefile drives the production of the nsctl kernel module
-#
-# sparc implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-#
-UTSBASE = ../..
-
-ARCHDIR:sh = cd ..; basename `pwd`
-
-#
-# Define the module and object file sets.
-#
-MODULE = nsctl
-OBJECTS = $(NSCTL_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(NSCTL_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(USR_DRV_DIR)/$(MODULE)
-INC_PATH += -I$(UTSBASE)/common/avs
-INC_PATH += -I$(ROOT)/usr/include
-CONF_SRCDIR = $(UTSBASE)/common/avs/ns/nsctl
-
-#
-# Include common rules.
-#
-include ../Makefile.$(ARCHDIR)
-include $(UTSBASE)/common/avs/Makefile.com
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY) $(SRC_CONFILE)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOT_CONFFILE)
-
-#
-# lint pass one enforcement
-#
-CFLAGS += $(CCVERBOSE)
-LDFLAGS += -dy -N"drv/nskern" -N"drv/ncall" -N"misc/spuni"
-LINTTAGS += -erroff=E_ASSIGN_NARROW_CONV
-LINTTAGS += -erroff=E_BAD_PTR_CAST_ALIGN
-
-CERRWARN += -_gcc=-Wno-parentheses
-
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-
-#
-# Include common targets.
-#
-include ../Makefile.targ
diff --git a/usr/src/uts/sparc/nskern/Makefile b/usr/src/uts/sparc/nskern/Makefile
deleted file mode 100644
index b591f6df63..0000000000
--- a/usr/src/uts/sparc/nskern/Makefile
+++ /dev/null
@@ -1,89 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# uts/sparc/nskern/Makefile
-#
-# This makefile drives the production of the nskern kernel module
-#
-# sparc implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-#
-UTSBASE = ../..
-
-ARCHDIR:sh = cd ..; basename `pwd`
-
-#
-# Define the module and object file sets.
-#
-MODULE = nskern
-OBJECTS = $(NSKERN_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(NSKERN_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(USR_DRV_DIR)/$(MODULE)
-INC_PATH += -I$(UTSBASE)/common/avs
-INC_PATH += -I$(ROOT)/usr/include
-CONF_SRCDIR = $(UTSBASE)/common/avs/ns/solaris
-
-#
-# Include common rules.
-#
-include ../Makefile.$(ARCHDIR)
-include $(UTSBASE)/common/avs/Makefile.com
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY) $(SRC_CONFILE)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOT_CONFFILE)
-
-#
-# lint pass one enforcement
-#
-CFLAGS += -v
-
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-#
-# Include common targets.
-#
-include ../Makefile.targ
diff --git a/usr/src/uts/sparc/nskern/nsc_asm.s b/usr/src/uts/sparc/nskern/nsc_asm.s
deleted file mode 100644
index 04463728be..0000000000
--- a/usr/src/uts/sparc/nskern/nsc_asm.s
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#if defined(lint) || defined(DS_DDICT)
-#include <sys/types.h>
-#include <sys/param.h>
-#else
-#include <sys/asm_linkage.h>
-#endif
-
-#ifdef DS_DDICT
-#define uint8_t uchar_t
-#endif
-
-
-/*
- * Special support routines that can't be done with C
- */
-
-
-/*
- * uint8_t nsc_ldstub(uint8_t *cp)
- *
- * Store 0xFF at the specified location, and return its previous content.
- */
-
-#if defined(lint) || defined(DS_DDICT)
-uint8_t
-nsc_ldstub(uint8_t *cp)
-{
- uint8_t rv;
- rv = *cp;
- *cp = 0xFF;
- return (rv);
-}
-#else
-
- ENTRY(nsc_ldstub)
- retl
- ldstub [%o0], %o0
- SET_SIZE(nsc_ldstub)
-
-#endif /* lint || DS_DDICT */
-
-
-/*
- * nsc_membar_stld(void)
- *
- * C callable interface to SPARC asm membar instruction.
- */
-
-#if defined(lint) || defined(DS_DDICT)
-void
-nsc_membar_stld(void)
-{}
-#else
-
- ENTRY(nsc_membar_stld)
- retl
- membar #StoreLoad
- SET_SIZE(nsc_membar_stld)
-
-#endif /* lint || DS_DDICT */
-
-
-/*
- * if a() calls b() calls nsc_caller(),
- * nsc_caller() returns return address in a().
- */
-
-#if defined(lint) || defined(DS_DDICT)
-caddr_t
-nsc_caller(void)
-{
- return (0);
-}
-#else
-
- ENTRY(nsc_caller)
- retl
- mov %i7, %o0
- SET_SIZE(nsc_caller)
-
-#endif /* lint || DS_DDICT */
-
-
-/*
- * if a() calls nsc_callee(), nsc_callee() returns the
- * return address in a();
- */
-
-#if defined(lint) || defined(DS_DDICT)
-caddr_t
-nsc_callee(void)
-{
- return (0);
-}
-#else
-
- ENTRY(nsc_callee)
- .register %g7, #scratch
- retl
- mov %o7, %o0
- SET_SIZE(nsc_callee)
-
-#endif /* lint || DS_DDICT */
-
-
-/*
- * nsc_threadp(void)
- *
- * C callable interface to get the current thread pointer.
- */
-
-#if defined(lint) || defined(DS_DDICT)
-void *
-nsc_threadp(void)
-{
- return (NULL);
-}
-#else
-
- ENTRY(nsc_threadp)
- retl
- mov %g7, %o0
- SET_SIZE(nsc_threadp)
-
-#endif /* lint || DS_DDICT */
diff --git a/usr/src/uts/sparc/rdc/Makefile b/usr/src/uts/sparc/rdc/Makefile
deleted file mode 100644
index 193cc187a4..0000000000
--- a/usr/src/uts/sparc/rdc/Makefile
+++ /dev/null
@@ -1,106 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# uts/sparc/rdc/Makefile
-#
-# This makefile drives the production of the rdc kernel module
-#
-# sparc implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-#
-UTSBASE = ../..
-
-ARCHDIR:sh = cd ..; basename `pwd`
-
-#
-# Define the module and object file sets.
-#
-MODULE = rdc
-OBJECTS = $(RDC_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(RDC_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(USR_DRV_DIR)/$(MODULE)
-INC_PATH += -I$(ROOT)/usr/include
-CONF_SRCDIR = $(UTSBASE)/common/avs/ns/rdc
-
-#
-# Include common rules.
-#
-include ../Makefile.$(ARCHDIR)
-include $(UTSBASE)/common/avs/Makefile.com
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY) $(SRC_CONFILE)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOT_CONFFILE)
-
-#
-# lint pass one enforcement
-#
-CFLAGS += $(CCVERBOSE) -D_SD_8K_BLKSIZE -D_SYSCALL32
-LINT_DEFS += -D_SYSCALL32
-LINTTAGS += -erroff=E_BAD_PTR_CAST_ALIGN
-LINTTAGS += -erroff=E_INCONS_ARG_DECL2
-LDFLAGS += -dy -N"drv/nsctl" -N"drv/nskern" -N"drv/ncall" -N"misc/spuni"
-LDFLAGS += -N"misc/rdcsrv" -N"strmod/rpcmod"
-
-CERRWARN += -_gcc=-Wno-switch
-CERRWARN += -_gcc=-Wno-unused-label
-CERRWARN += -_gcc=-Wno-parentheses
-CERRWARN += -_gcc=-Wno-uninitialized
-
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
- -rm -f obj*/rdc_prot_xdr.c debug*/rdc_prot_xdr.c
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-$(OBJS_DIR)/rdc_prot_xdr.c: $(UTSBASE)/common/avs/ns/rdc/rdc_prot.x
- $(RPCGEN) -i 0 -C -c -o $@ \
- `/bin/pwd`/$(UTSBASE)/common/avs/ns/rdc/rdc_prot.x
-
-$(OBJS_DIR)/rdc_prot_xdr.o: $(OBJS_DIR)/rdc_prot_xdr.c
- $(COMPILE.c) -o $@ $(OBJS_DIR)/rdc_prot_xdr.c
-
-#
-# Include common targets.
-#
-include ../Makefile.targ
diff --git a/usr/src/uts/sparc/rdcsrv/Makefile b/usr/src/uts/sparc/rdcsrv/Makefile
deleted file mode 100644
index 94dfeaeace..0000000000
--- a/usr/src/uts/sparc/rdcsrv/Makefile
+++ /dev/null
@@ -1,96 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# uts/sparc/rdcsrv/Makefile
-#
-# This makefile drives the production of the rdcsrv kernel module
-#
-# sparc implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-#
-UTSBASE = ../..
-
-ARCHDIR:sh = cd ..; basename `pwd`
-
-#
-# Define the module and object file sets.
-#
-MODULE = rdcsrv
-OBJECTS = $(RDCSRV_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(RDCSRV_OBJS:%.o=$(LINTS_DIR)/%.ln)
-INC_PATH += -I$(ROOT)/usr/include
-ROOTMODULE = $(USR_DRV_DIR)/$(MODULE)
-ROOTLINK = $(USR_MISC_DIR)/$(MODULE)
-
-#
-# Include common rules.
-#
-include ../Makefile.$(ARCHDIR)
-include $(UTSBASE)/common/avs/Makefile.com
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOTLINK)
-
-#
-# lint pass one enforcement
-#
-CFLAGS += $(CCVERBOSE) -D_SD_8K_BLKSIZE -D_SYSCALL32
-LINT_DEFS += -D_SD_8K_BLKSIZE -D_SYSCALL32
-LDFLAGS += -dy -N"strmod/rpcmod" -N"misc/rdcstub"
-
-CERRWARN += -_gcc=-Wno-unused-label
-CERRWARN += -_gcc=-Wno-unused-variable
-
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-$(ROOTLINK): $(USR_MISC_DIR) $(ROOTMODULE)
- -$(RM) $@; $(LN) $(ROOTMODULE) $@
-
-#
-# Include common targets.
-#
-include ../Makefile.targ
diff --git a/usr/src/uts/sparc/rdcstub/Makefile b/usr/src/uts/sparc/rdcstub/Makefile
deleted file mode 100644
index b8b441e24c..0000000000
--- a/usr/src/uts/sparc/rdcstub/Makefile
+++ /dev/null
@@ -1,93 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# uts/sparc/rdcstub/Makefile
-#
-# This makefile drives the production of the rdcsrv kernel module
-#
-# sparc implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-#
-UTSBASE = ../..
-
-ARCHDIR:sh = cd ..; basename `pwd`
-
-#
-# Define the module and object file sets.
-#
-MODULE = rdcstub
-OBJECTS = $(RDCSTUB_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(RDCSTUB_OBJS:%.o=$(LINTS_DIR)/%.ln)
-INC_PATH += -I$(ROOT)/usr/include
-ROOTMODULE = $(USR_DRV_DIR)/$(MODULE)
-ROOTLINK = $(USR_MISC_DIR)/$(MODULE)
-
-#
-# Include common rules.
-#
-include ../Makefile.$(ARCHDIR)
-include $(UTSBASE)/common/avs/Makefile.com
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOTLINK)
-
-#
-# lint pass one enforcement
-#
-CFLAGS += -v -D_SD_8K_BLKSIZE -D_SYSCALL32
-LINT_DEFS += -D_SD_8K_BLKSIZE -D_SYSCALL32
-LDFLAGS += -dy -N"strmod/rpcmod"
-
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-$(ROOTLINK): $(USR_MISC_DIR) $(ROOTMODULE)
- -$(RM) $@; $(LN) $(ROOTMODULE) $@
-
-#
-# Include common targets.
-#
-include ../Makefile.targ
diff --git a/usr/src/uts/sparc/sdbc/Makefile b/usr/src/uts/sparc/sdbc/Makefile
deleted file mode 100644
index 110556f12b..0000000000
--- a/usr/src/uts/sparc/sdbc/Makefile
+++ /dev/null
@@ -1,172 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#
-# uts/sparc/sdbc/Makefile
-#
-# This makefile drives the production of the sdbc kernel module
-#
-# sparc implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-#
-UTSBASE = ../..
-
-ARCHDIR:sh = cd ..; basename `pwd`
-
-UTSCOMMON = $(UTSBASE)/common
-AVSCOMMON = $(UTSCOMMON)/avs
-
-#
-# Define the module and object file sets.
-#
-MODULE = sdbc
-OBJECTS = $(SDBC_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(SDBC_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(USR_DRV_DIR)/$(MODULE)
-INC_PATH += -I$(ROOT)/usr/include
-INC_PATH += -I$(AVSCOMMON)
-INC_PATH += -I$(AVSCOMMON)/ns/sdbc
-CONF_SRCDIR = $(UTSBASE)/common/avs/ns/sdbc
-
-#
-# Include common rules.
-#
-include ../Makefile.$(ARCHDIR)
-include $(UTSBASE)/common/avs/Makefile.com
-
-CLOBBERFILES += obj*/*.c debug*/*.c obj*/sd_mkiob debug*/sd_mkiob
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY) $(SRC_CONFILE)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOT_CONFFILE)
-
-#
-# lint pass one enforcement
-#
-CFLAGS += $(CCVERBOSE) -D_SD_8K_BLKSIZE -D_SDBC_SINGLE_BRD
-LDFLAGS += -dy -N"drv/nsctl" -N"drv/ncall" -N"drv/nskern" -N"misc/spuni"
-LINTTAGS += -erroff=E_ASSIGN_NARROW_CONV
-LINTTAGS += -erroff=E_BAD_PTR_CAST_ALIGN
-
-CERRWARN += -_gcc=-Wno-parentheses
-CERRWARN += -_gcc=-Wno-uninitialized
-CERRWARN += -_gcc=-Wno-unused-label
-
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-$(OBJS_DIR)/sd_mkiob: $(UTSBASE)/common/avs/ns/sdbc/sd_mkiob.sh
- $(CP) $(UTSBASE)/common/avs/ns/sdbc/sd_mkiob.sh $@
- $(CHMOD) 755 $@
-
-$(OBJS_DIR)/sd_iob_impl0.c: $(UTSBASE)/common/avs/ns/sdbc/sd_iob.h \
- $(OBJS_DIR)/sd_mkiob
- $(OBJS_DIR)/sd_mkiob 0 512 $(AVSCOMMON)/ns/sdbc/sd_iob.h > $@
-
-$(OBJS_DIR)/sd_iob_impl1.c: $(UTSBASE)/common/avs/ns/sdbc/sd_iob.h \
- $(OBJS_DIR)/sd_mkiob
- $(OBJS_DIR)/sd_mkiob 512 1024 $(AVSCOMMON)/ns/sdbc/sd_iob.h > $@
-
-$(OBJS_DIR)/sd_iob_impl2.c: $(UTSBASE)/common/avs/ns/sdbc/sd_iob.h \
- $(OBJS_DIR)/sd_mkiob
- $(OBJS_DIR)/sd_mkiob 1024 1536 $(AVSCOMMON)/ns/sdbc/sd_iob.h > $@
-
-$(OBJS_DIR)/sd_iob_impl3.c: $(UTSBASE)/common/avs/ns/sdbc/sd_iob.h \
- $(OBJS_DIR)/sd_mkiob
- $(OBJS_DIR)/sd_mkiob 1536 2048 $(AVSCOMMON)/ns/sdbc/sd_iob.h > $@
-
-$(OBJS_DIR)/sd_iob_impl4.c: $(UTSBASE)/common/avs/ns/sdbc/sd_iob.h \
- $(OBJS_DIR)/sd_mkiob
- $(OBJS_DIR)/sd_mkiob 2048 2560 $(AVSCOMMON)/ns/sdbc/sd_iob.h > $@
-
-$(OBJS_DIR)/sd_iob_impl5.c: $(UTSBASE)/common/avs/ns/sdbc/sd_iob.h \
- $(OBJS_DIR)/sd_mkiob
- $(OBJS_DIR)/sd_mkiob 2560 3072 $(AVSCOMMON)/ns/sdbc/sd_iob.h > $@
-
-$(OBJS_DIR)/sd_iob_impl6.c: $(UTSBASE)/common/avs/ns/sdbc/sd_iob.h \
- $(OBJS_DIR)/sd_mkiob
- $(OBJS_DIR)/sd_mkiob 3072 3584 $(AVSCOMMON)/ns/sdbc/sd_iob.h > $@
-
-$(OBJS_DIR)/sd_iob_impl7.c: $(UTSBASE)/common/avs/ns/sdbc/sd_iob.h \
- $(OBJS_DIR)/sd_mkiob
- $(OBJS_DIR)/sd_mkiob 3584 9999 $(AVSCOMMON)/ns/sdbc/sd_iob.h > $@
-
-$(OBJS_DIR)/sd_iob_impl0.o: $(OBJS_DIR)/sd_iob_impl0.c
- $(COMPILE.c) -o $@ $(OBJS_DIR)/sd_iob_impl0.c
- $(POST_PROCESS_O)
-
-$(OBJS_DIR)/sd_iob_impl1.o: $(OBJS_DIR)/sd_iob_impl1.c
- $(COMPILE.c) -o $@ $(OBJS_DIR)/sd_iob_impl1.c
- $(POST_PROCESS_O)
-
-$(OBJS_DIR)/sd_iob_impl2.o: $(OBJS_DIR)/sd_iob_impl2.c
- $(COMPILE.c) -o $@ $(OBJS_DIR)/sd_iob_impl2.c
- $(POST_PROCESS_O)
-
-$(OBJS_DIR)/sd_iob_impl3.o: $(OBJS_DIR)/sd_iob_impl3.c
- $(COMPILE.c) -o $@ $(OBJS_DIR)/sd_iob_impl3.c
- $(POST_PROCESS_O)
-
-$(OBJS_DIR)/sd_iob_impl4.o: $(OBJS_DIR)/sd_iob_impl4.c
- $(COMPILE.c) -o $@ $(OBJS_DIR)/sd_iob_impl4.c
- $(POST_PROCESS_O)
-
-$(OBJS_DIR)/sd_iob_impl5.o: $(OBJS_DIR)/sd_iob_impl5.c
- $(COMPILE.c) -o $@ $(OBJS_DIR)/sd_iob_impl5.c
- $(POST_PROCESS_O)
-
-$(OBJS_DIR)/sd_iob_impl6.o: $(OBJS_DIR)/sd_iob_impl6.c
- $(COMPILE.c) -o $@ $(OBJS_DIR)/sd_iob_impl6.c
- $(POST_PROCESS_O)
-
-$(OBJS_DIR)/sd_iob_impl7.o: $(OBJS_DIR)/sd_iob_impl7.c
- $(COMPILE.c) -o $@ $(OBJS_DIR)/sd_iob_impl7.c
- $(POST_PROCESS_O)
-
-
-#
-# Include common targets.
-#
-include ../Makefile.targ
diff --git a/usr/src/uts/sparc/spuni/Makefile b/usr/src/uts/sparc/spuni/Makefile
deleted file mode 100644
index 3147e7a3b9..0000000000
--- a/usr/src/uts/sparc/spuni/Makefile
+++ /dev/null
@@ -1,88 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# uts/sparc/spuni/Makefile
-#
-# This makefile drives the production of the spuni kernel module
-#
-# sparc implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-#
-UTSBASE = ../..
-
-ARCHDIR:sh = cd ..; basename `pwd`
-
-#
-# Define the module and object file sets.
-#
-MODULE = spuni
-OBJECTS = $(UNISTAT_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(UNISTAT_OBJS:%.o=$(LINTS_DIR)/%.ln)
-INC_PATH += -I$(ROOT)/usr/include
-ROOTMODULE = $(USR_MISC_DIR)/$(MODULE)
-
-#
-# Include common rules.
-#
-include ../Makefile.$(ARCHDIR)
-include $(UTSBASE)/common/avs/Makefile.com
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE)
-
-#
-# lint pass one enforcement
-#
-CFLAGS += -v
-LINTFLAGS += -erroff=E_BAD_PTR_CAST_ALIGN
-
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-#
-# Include common targets.
-#
-include ../Makefile.targ
diff --git a/usr/src/uts/sparc/sv/Makefile b/usr/src/uts/sparc/sv/Makefile
deleted file mode 100644
index 9f68438d65..0000000000
--- a/usr/src/uts/sparc/sv/Makefile
+++ /dev/null
@@ -1,91 +0,0 @@
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# uts/sparc/sv/Makefile
-#
-# This makefile drives the production of the sv kernel module
-#
-# sparc implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-#
-UTSBASE = ../..
-
-ARCHDIR:sh = cd ..; basename `pwd`
-
-#
-# Define the module and object file sets.
-#
-MODULE = sv
-OBJECTS = $(SV_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(SV_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(USR_DRV_DIR)/$(MODULE)
-INC_PATH += -I$(ROOT)/usr/include
-CONF_SRCDIR = $(UTSBASE)/common/avs/ns/sv
-
-#
-# Include common rules.
-#
-include ../Makefile.$(ARCHDIR)
-include $(UTSBASE)/common/avs/Makefile.com
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY) $(SRC_CONFILE)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOT_CONFFILE)
-
-#
-# lint pass one enforcement
-#
-CFLAGS += $(CCVERBOSE)
-LDFLAGS += -dy -N"drv/nsctl" -N"drv/nskern" -N"misc/spuni"
-
-CERRWARN += -_gcc=-Wno-uninitialized
-
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-#
-# Include common targets.
-#
-include ../Makefile.targ